SpringBoot框架中JPA使用的一些问题
主要是自己在使用JPA框架时遇到的一个坑,拿出来分享一下
首先上一个简单JPA框架实体
public interface EnterpriseInfoDao extends JpaSpecificationExecutor<EnterpriseInfoEntity>, PagingAndSortingRepository<EnterpriseInfoEntity,String> { }
JPA的运用我就不多说了网上搜一下都是,我就举一个一般的使用方法
public interface EnterpriseInfoDao extends JpaSpecificationExecutor<EnterpriseInfoEntity>, PagingAndSortingRepository<EnterpriseInfoEntity,String> {
EnterpriseInfoEntity findByEnterpriseName(String name);
}
通过EnterpriseName找到对应的企业实体,EnterpriseName是实体中的一个字段,由于我们数据库企业名是唯一的,所以返回值就是单个实体
接下来我举例一个返回值不是企业实体的方法
public interface EnterpriseInfoDao extends JpaSpecificationExecutor<EnterpriseInfoEntity>, PagingAndSortingRepository<EnterpriseInfoEntity,String> { EnterpriseInfoEntity findByEnterpriseName(String name);
@Query(value = "select pi.id,pi.name from person_info pi\n" +
"left join enterprise_info ei on ei.id = pi.belong_ent\n" +
"where ent.id in ?1\n" +
"and ei.id_deleted = ?2", nativeQuery = true)
List<Object[]> findByEnterprise(List<String> entIds,Integer deleted);
}
我只是举个例子,不要问我为什么不写个personDao,只是举个例子
当你使用query写原生sql语句时,你返回的不是该Dao的对应实体的话,你需要将它的返回类型设置为List<Object[]>或者Object[]
这里我就遇到了一个坑,还遇到了2次,我就把它记录下来
一般来说对于这个List<Object[]>类型的返回值,在判空之后,循环拿出每个Object[]数组,然后ob[0]就是id,ob[1]就是name
但是如果在数据库中该企业下没有人员存在,那么这个坑就出现了
首先List不为空,它的大小为1,在object数组中,ob的length为1,它只有一个null,这个时候你去取ob[1]的时候系统就会报超出array大小的错误,原因就是这个。
我推荐的解决方案是直接在你的service中用jtbctemple的queryForList操作,它的返回值为List<Map<String,Object>>,即使object是null你也可以取到值,写个简单的例子
StringBuffer sb = new StringBuffer(); sb.append("select pi.id as id,pi.name as name from person_info pi\n" +
"left join enterprise_info ei on ei.id = pi.belong_ent";
List<Map<String,Object>> extra = jdbcTemplate.queryForList(sb.toString());
if(!CollectionUnits.isEmpty(extra)){
for(Map<String, Object> map: extra){
String id = (String)map.get("id");
String name = (String)map.get("name");
}
}