一、引言
在JPA中,为了实现某些复杂的sql语句查询可以借助JPA EntityManager来实现该功能,EntityManager是JPA中用于增删改查的接口,它的作用相当于一座桥梁,连接内存中的java对象和数据库的数据存储。
二、实现
- 下面是简单的Dao层实现
import org.springframework.stereotype.Repository;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
@Repository
public class tDaoImpl {
@Autowired
private EntityManager entityManager;
@Override
public Page<Output> queryMBomDetailsByIdAndStatus(Input input) {
/**查询列表详细内容**/
StringBuffer sql = new StringBuffer("SELECT m.a,m.b,m.c,m.d,m.e,m.f,u.g,u.h" +
" FROM table1 m " +
"LEFT JOIN table2 u ON m.x = u.x WHERE 1=1 ");
Map<String, Object> map = new HashMap<>();
if (!StringUtils.isEmpty(input.getBomMid())) {
sql.append(" and m.id = :id ");
map.put("id", input.getBomMid());
}
if (null != input.getStatus()) {
sql.append(" and m.name = :name ");
map.put("name", input.getStatus());
}
if (!StringUtils.isEmpty(input.getAccountMid())) {
sql.append(" and u.sn = :sn ");
map.put("accountMid", input.getAccountMid());
}
sql.append(" ORDER BY m.create_At DESC");
//第二个参数是输出的实体类
Query query = entityManager.createNativeQuery(sql.toString(),Output.class);
query.setFirstResult((input.getPageIndex() - 1) * input.getPageSize());//第一条位置
query.setMaxResults(input.getPageSize());//查询结果最大容量
/**查询数据总条数**/
String sqlStr = sql.toString();
String count = "SELECT count(1) ";
String substring = sqlStr.substring(0, sql.indexOf("FROM"));
String countSql = sqlStr.replace(substring, count);
Query countQuery = entityManager.createNativeQuery(countSql);
//拼接查询条件
for (String key : map.keySet()) {
query.setParameter(key, map.get(key));
countQuery.setParameter(key, map.get(key));
}
List<Output> list = query.getResultList();//详细集合
long total = ((BigInteger) countQuery.getSingleResult()).longValue();//总数量
//分页信息
PageRequest pageable = PageRequest.of(input.getPageIndex() - 1, input.getPageSize());
//为了方便分页查询,可将结果分装到org.springframework.data.domain.Page;类中
Page<Output> resultPage = new PageImpl<>(list, pageable, total);
return resultPage;
}
}
2.注意事项
在Query query = entityManager.createNativeQuery(sql.toString(),Output.class);中输出的实体包含Date等特殊类型的数据时会报org.springframework.orm.jpa.JpaSystemException: Unknown entity的错误,此时建议最好映射的是String类型的内容,同时输出的Entity同普通JPA一样,要实现下面的注解
3.其他
在Dao层中查询的结果也可以通过下面的方法将结果放到List集合中
//重要:可将查询结果以map返回,key为查询的sql字段名
query.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
List<Output> resultList = new ArrayList<>();//结果数据
for (Object o : list) {
Output Output = new Output();
Map mapResult = (HashMap) o;
Output.setA(String.valueOf(mapResult.get("a")));
Output.setB(String.valueOf(mapResult.get("b")));
Output.setC(String.valueOf(mapResult.get("c")));
Output.setD(String.valueOf(mapResult.get("d")));//
resultList.add(Output);
}