复杂查询情况分析
在遇到复杂查询时,尤其是需要动态传递查询参数时,jpa为我们提供给可一下几种方式可以应对上述情况:
Search
Search 封装分页,扩展了findAll()函数.
Eg:
@Override
public Page<Student> search(finalStudent student, PageInfo page) {
return studentRepository.findAll(new
@Override
public
Predicate stuNameLike = null;
if(null
stuNameLike =cb.like(root.<String> get("name"), "%" +student.getName() + "%");
}
null;
if(null!= student && null
clazzNameLike = cb.like(root.<String>get("clazz").<String> get("name"), "%" +student.getClazz().getName() + "%");
}
if(null!= stuNameLike) query.where(stuNameLike);
if(null
returnnull;
}
new PageRequest(page.getPage() - 1,page.getLimit(), new
}
@Query 注解自定义的查询
Eg:
@Query("select a.labelIdfrom MbLabelRelEntity a where a.mbId in ?1 group by a.labelId")
List<String> getLabelIdList(List<String> mbIds);
@Modifying
@Query("update User bean set bean.status=?2 wherebean.id=?1")
publicvoid checkUser(Integer id, int status);
注:
1、当注解的sql语句涉及更新表操作是,需要添加@Modifying注解
2、其中 ?1、?2表示第几个参数
@Query(value = "select name,author,pricefrom Book b where b.name like %:name%")
List<Book>findByNameMatch(@Param("name") String name);
动态查询
JPA提供的API中,动态查询大概有这么一些方法,
CreateNameQuery
@NamedNativeQueries({
@NamedNativeQuery(
name = "getNativeNutShellInfo", //需要调用的name
query = "{call cp_syslogin_web(?,?,?)}", //存储过程,返回的List字段对应的值@EntityResult此处填充实体的属性值
resultSetMapping = "ReturnColumnEntityList"
)
})
@SqlResultSetMappings({
@SqlResultSetMapping(
name = "ReturnColumnEntityList",
entities = {
@EntityResult(entityClass = NutShellInfo.class,fields={ //返回的List字段对应的值此处填充实体的属性值
@FieldResult(name = "aguid", column = "aguid"),
@FieldResult(name = "user", column = "htkusr"),
@FieldResult(name = "qty", column = "qtynow"),
@FieldResult(name = "registered", column = "breg"),
@FieldResult(name = "hint", column = "hint"),
@FieldResult(name = "ver", column = "ver"),
@FieldResult(name = "overQty", column = "boverqty"),
@FieldResult(name = "timeout", column = "btimeout"),
@FieldResult(name = "host", column = "htkwww")
})
}
)
})
@Entity
public class NutShellInfo {
@Id
private String aguid;
@Column(name = "htkusr")
private String user;
@Column(name = "qtynow")
private double qty;
@Column(name = "breg")
private boolean registered;
private String hint;
private String ver;
@Column(name = "boverqty")
private boolean overQty;
@Column(name = "btimeout")
private boolean timeout;
@Column(name = "htkwww")
private String host;
@Transient
private String password;//这个字段不对数据库操作
/***setterand getter**/
}
=========================dao=========================
@Service
publicclass PubBaseDaoImpl<T> implements PubBaseDao<T> {
private EntityManager em = null;
@PersistenceContext
public void setEm(EntityManager em) {
this.em = em;
}
@Override
public List<T> qryNamedQuery(StringnativeName,Object[] params) {
Queryq = em.createNamedQuery(nativeName);
setQueryParams(q, params);
return q.getResultList();
}
public void setQueryParams(Query query,Object[] params) {
try{
if(params != null && params.length > 0) {
for (int i = 0; i < params.length; i++) {
query.setParameter(i + 1, params[i]);
}
}
}catch (Exception e) {
e.printStackTrace();
}
}
=================services===================================
@Override
public void qryInfo(String userId, StringmachineCode) {
List<NutShellInfo> list =baseDao.qryNamedQuery("getNativeNutShellInfo",new Object[] { userId,machineCode, 0 });
}
JPA 原生态SQL 的复杂查询之createNamedQuery,select* from查询,返回的List字段对应的填充实体
============实体类==========================
@NamedNativeQueries({
@NamedNativeQuery(
name = "getNativeNutShellInfo", //需要调用的name
query = "select * from NutShellInfo where aguid=? and htkusr=? and btimeout=? ", //存储过程,返回的List字段对应的值@EntityResult此处填充实体的属性值
resultSetMapping = "ReturnColumnEntityList"
)
})
@SqlResultSetMappings({
@SqlResultSetMapping(
name = "ReturnColumnEntityList",
entities = {
@EntityResult(entityClass = NutShellInfo.class,fields={ //返回的List字段对应的值此处填充实体的属性值
@FieldResult(name = "aguid", column = "id"),
@FieldResult(name = "user", column = "htkusr"),
@FieldResult(name = "qty", column = "qtynow"),
@FieldResult(name = "registered", column = "breg"),
@FieldResult(name = "hint", column = "hint"),
@FieldResult(name = "ver", column = "ver"),
@FieldResult(name = "overQty", column = "boverqty"),
@FieldResult(name = "timeout", column = "btimeout"),
@FieldResult(name = "host", column = "htkwww")
})
}
)
})
@Entity
public class NutShellInfo {
@Id
private String aguid;
@Column(name = "htkusr")
private String user;
@Column(name = "qtynow")
private double qty;
@Column(name = "breg")
private boolean registered;
private String hint;
private String ver;
@Column(name = "boverqty")
private boolean overQty;
@Column(name = "btimeout")
private boolean timeout;
@Column(name = "htkwww")
private String host;
@Transient
private String password;//这个字段不对数据库操作
/****setter and getter*****/
}
=========================dao=========================
@Service
public class PubBaseDaoImpl<T>implements PubBaseDao<T> {
private EntityManager em = null;
@PersistenceContext
public void setEm(EntityManager em) {
this.em = em;
}
@Override
public List<T> qryNamedQuery(StringnativeName,Object[] params) {
Query q = em.createNamedQuery(nativeName);
setQueryParams(q, params);
return q.getResultList();
}
public void setQueryParams(Query query,Object[] params) {
try{
if(params != null && params.length > 0) {
for (int i = 0; i < params.length; i++) {
query.setParameter(i + 1, params[i]);
}
}
}catch (Exception e) {
e.printStackTrace();
}
}
=================services===================================
@Override
public void qryInfo(String userId, StringmachineCode) {
List<NutShellInfo> list =baseDao.qryNamedQuery("getNativeNutShellInfo",new Object[] { userId,machineCode, 0 });
}
JPA 原生态SQL 的复杂查询之createNamedQuery,selectxxx,xxx from查询,返回的List字段对应的填充实体
============实体类==========================
@NamedNativeQueries({
@NamedNativeQuery(
name = "getNativeNutShellInfo", //需要调用的name
query = "select aguid,htkusr from NutShellInfo where aguid=?and htkusr=? and btimeout=? ", //存储过程,返回的List字段对应的值@EntityResult此处填充实体的属性值
resultSetMapping = "ReturnColumnEntityList"
)
})
@SqlResultSetMappings({
@SqlResultSetMapping(
name = "ReturnColumnEntityList",
entities = {}
columns = {
@ColumnResult(name = "aguid"),
@ColumnResult(name = "htkusr"),
}
)
})
@Entity
public class NutShellInfo {
@Id
private String aguid;
@Column(name = "htkusr")
private String user;
@Column(name = "qtynow")
private double qty;
@Column(name = "breg")
private boolean registered;
private String hint;
private String ver;
@Column(name = "boverqty")
private boolean overQty;
@Column(name = "btimeout")
privateboolean timeout;
@Column(name = "htkwww")
private String host;
@Transient
private String password;//这个字段不对数据库操作
/******setter and getter********/
}
=========================dao=========================
@Service
public class PubBaseDaoImpl<T>implements PubBaseDao<T> {
private EntityManager em = null;
@PersistenceContext
public void setEm(EntityManager em) {
this.em = em;
}
@Override
public List<T> qryNamedQuery(StringnativeName,Object[] params) {
Query q = em.createNamedQuery(nativeName);
setQueryParams(q, params);
return q.getResultList();
}
public void setQueryParams(Query query,Object[] params) {
try{
if(params != null && params.length > 0) {
for (int i = 0; i < params.length; i++) {
query.setParameter(i+ 1, params[i]);
}
}
}catch (Exception e) {
e.printStackTrace();
}
}
=================services===================================
@Override
public void qryInfo(String userId, StringmachineCode) {
List<NutShellInfo> list =baseDao.qryNamedQuery("getNativeNutShellInfo",new Object[] { userId,machineCode, 0 });
}
createNativeQuery
执行原生的SQL语句. 但当我们查询结果没有对应实体类时,query.getResultList()返回的是一个List.
为了解决上述问题,所以提供了
createNativeQuery(String sqlString, Class resultClass)
createNativeQuery(String sqlString,String resultSetMapping)
第一种方式
一般针对复杂(多表)查询,但是返回结果为单张表信息,可以用定义的javaBean实体进行sql结果的格式化。(未进行测试)
第二种方式(@SqlResultSetMapping 或 @SqlResultSetMappings):
针对复杂多表查询,返回结果为多表信息或几张表中摘取的部分字段,或经过聚合函数计算后的字段信息,在javabean格式化时,可以定义resultSetMapping 来进行接受。(@SqlResultSetMapping 或@SqlResultSetMappings)
Eg:
String sql=” select * from ”
List<ComparativeResultEntity> list=em.createNativeQuery(sql, “comparativeResult")
.getResultList();
@Entity
@SqlResultSetMapping(name = "comparativeResult",
entities = { @EntityResult(entityClass = ComparativeResultEntity.class,
fields = {
@FieldResult(name = "id", column = "gmonth"),
@FieldResult(name = "month", column = "gmonth"),
@FieldResult(name = "thisMoney", column = "thisMoney"),
@FieldResult(name = "thisAmount", column = "thisAmount"),
@FieldResult(name = "lastMoney", column = "lastMoney"),
@FieldResult(name = "lastAmount", column = "lastAmount"),
@FieldResult(name = "moneyRatio", column = "moneyRatio"),
@FieldResult(name = "amountRatio", column = "amountRatio")
})
}
)
publicclass ComparativeResultEntity implements Serializable {
privatestaticfinallongserialVersionUID =5852089358217463285L;
@Id
private String id;
private Integer thisAmount;
private Double thisMoney;
private Integer lastAmount;
private Double lastMoney;
private String month;
private Double moneyRatio;
/****setter andgetter****/
}
第三种方式(setResultTransformer)
注:需要注意hibernate的版本
String sql =”select * from table”;
Query nativeQuery= em.createNativeQuery(sql);
nativeQuery.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
List list = nativeQuery.getResultList();