spring boot中的jpa非常好用,但是在创建动态查询时稍微有些麻烦。基本上有以下两种办法:
- 方法一:用criteria查询
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
CriteriaBuilder
接口用来构建Predicate
,而Predicate
接口用来连接子句,每次添加到predicate
之前都要进行参数非空判断。
//dao层需继承JpaSpecificationExecutor
public interface BeanRepository extends JpaRepository<Bean, Integer>, JpaSpecificationExecutor<Bean> {
}
------------------
//关键代码
@Override
public Predicate toPredicate(Root<Bean> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
List<Predicate> predicates = new ArrayList<Predicate>();
//参数非空判断
if (params.get("Key值") != null && StringUtils.isNotBlank((String) params.get("Key值"))) {
predicates.add(cb.equal(root.get("bean中的变量,eg.age").as(Integer.class), params.get("age对应的参数Map中的Key")));
}
return query.where(predicates.toArray(new Predicate[predicates.size()]));
}
- 方法二:直接使用原生SQL,构建query来执行
由于本人涉及到的前台传回来的sql长短和条件都不固定,并且参数较多,写起来很麻烦。因此选择这种办法,将前台的数据拼接为sql,直接创建查询。
导入的包:
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import javax.persistence.EntityManager;
import javax.persistence.Query;
EntityManager
直接创建原生查询,createNativeQuery
的参数(string sql,info.class)
写入Bean.class,就直接可以用List<Bean>
接收了
private LocalContainerEntityManagerFactoryBean entityManagerFactory;
public void exec(){
EntityManager em = entityManagerFactory.getNativeEntityManagerFactory().createEntityManager();
StringBuilder sqljoint=new StringBuilder(300);
sqljoint.append("SELECT * FROM public.entity where 1=1");
//sqljoint.apped("附加的where子句")
String sql=sqljoint.toString();
em.getTransaction().begin();
//创建原生查询的时候,将info.class类即第二个参数,写成要传回的bean,这样就可以直接用List<Bean>接收
Query query = em.createNativeQuery(sql,EntityBean.class);
List<EntityBean> obj=query.getResultList();
}
Ps:链接备忘
spring boot jpa 使用原生sql查询
https://blog.csdn.net/weixin_40256864/article/details/81092853
mapbox教程
https://blog.csdn.net/jwdstef/article/details/38760111
手写汉字识别
http://lib.csdn.net/article/aiframework/60528