1.问题的提出
有的人可能会遇到这样的代码,看了后难以忍受,缺点如下所述:
- 返回类型Object[]数组,至于每一个下标对应哪个字段,没法直观的看到,例如object[11]是什么类型? 字段名是什么? 这个就无法直观得知 .
- sql中复杂的关系导致不可维护,每一个接手的人都要研究sql半天
- 该种动态拼接条件方法导致类似的代码会大量重复,所以IDEA打开的时候黄了半边天.
- 该查询为分页查询,这样写的话,还要再copy一个count查询才能拿到总数,无疑又是代码重复.
- JPA之类框架目的就是少些原生sql语句,大量这样的操作的话,还不如使用dbUtil这样的工具类查询.
1 @Override 2 public List<Object[]> findByPcardCardOrder( 3 PcardCardOrder pcardCardOrder,String applyInstName2,Integer page, Integer rows) { 4 StringBuffer sql = new StringBuffer( 5 "SELECT p.*" 6 +",p2.vcard_make_des" 7 +",p3.cardnum_rule_id,p3.vtype_nm" 8 +",p4.cn_card_bin,p4.cn_nm" 9 +",p5.inst_id,p5.inst_name,p5.apply_range,p5.card_name,p5.card_type,p5.bin_card_material" 10 +",p6.inst_name AS apply_inst_name " 11 +",p7.inst_name AS apply_inst_name2" 12 + ",p8.inst_name as receive_inst_name" 13 + " FROM " 14 +" tbl_pcard_card_order p LEFT JOIN tbl_pcard_vcard_make p2 ON p.make_id = p2.vcard_make_id" 15 +" LEFT JOIN tbl_pcard_vtype p3 ON p2.vcard_make_vtype_id=p3.vtype_id" 16 +" LEFT JOIN tbl_pcard_cardnum_rule p4 ON p3.cardnum_rule_id=p4.cn_id" 17 +" LEFT JOIN tbl_pcard_cardbin p5 ON p4.cn_card_bin=p5.card_bin" 18 +" LEFT JOIN tbl_pcard_institution p6 ON p5.apply_range=p6.inst_id" 19 +" LEFT JOIN tbl_pcard_institution p7 ON p.apply_inst_id=p7.inst_id" 20 +" LEFT JOIN tbl_pcard_institution p8 ON p.receive_inst=p8.inst_id" 21 +" WHERE 1=1 "); 22 int i = 1; 23 Map<String, Object> map = new HashMap<String, Object>(); 24 25 if (!StringUtils.isEmpty(pcardCardOrder.getCordId())) { 26 sql.append(" and p.cord_id="); 27 sql.append("?" + i); 28 map.put(i + "", pcardCardOrder.getCordId()); 29 i++; 30 } 31 if (!StringUtils.isEmpty(pcardCardOrder.getAppointMchtcard())) { 32 sql.append(" and p.appoint_mchtcard="); 33 sql.append("?" + i); 34 map.put(i + "", pcardCardOrder.getAppointMchtcard()); 35 i++; 36 } 37 38 if (!StringUtils.isEmpty(pcardCardOrder.getMakeId())) { 39 sql.append(" and p.make_id like "); 40 sql.append("?" + i); 41 map.put(i + "","%%"+ pcardCardOrder.getMakeId()+"%%"); 42 i++; 43 } 44 45 if (!StringUtils.isEmpty(applyInstName2)) { 46 sql.append(" and p7.inst_name like "); 47 sql.append("?"+i); 48 map.put(i+"","%%"+applyInstName2+"%%"); 49 i++; 50 } 51 52 sql.append(" order by p.ct_dm desc"); 53 Query query = entityManager.createNativeQuery(sql.toString()); 54 for (String key : map.keySet()) { 55 query.setParameter(key, map.get(key)); 56 } 57 if (page != null && rows != null) { 58 query.setFirstResult(rows * (page - 1)); 59 query.setMaxResults(rows); 60 } 61 return query.getResultList(); 62 }
2.学习QueryDSL
而QueryDSL就可以避免上面全部的问题,在解决问题之前先学习如何使用 .
2.1 QueryDSL简介
- QueryDSL仅仅是一个通用的查询框架,专注于通过Java API构建类型安全的SQL查询。
- QueryDSL可以通过一组通用的查询API为用户构建出适合不同类型ORM框架或者是SQL的查询语句,也就是说QueryDSL是基于各种ORM框架以及SQL之上的一个通用的查询框架。
- 借助QueryDSL可以在任何支持的ORM框架或者SQL平台上以一种通用的API方式来构建查询。目前QueryDSL支持的平台包括JPA,JDO,SQL,Java Collections,RDF,Lucene,Hibernate Search。
- 官网地址:点击进入
2.2配置到项目
首先对于queryDSL有两个版本,com.mysema.querydsl
和com.querydsl,
前者是3.X系列,后者是4.X系列,这里使用的是后者.
第一步: Maven引入依赖
<!--query dsl-->
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>${querydsl.version}</version>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
<scope>provided</scope>
</dependency>
<!--query dsl end-->
第二步: 加入插件,用于生成查询实例
<!--该插件可以生成querysdl需要的查询对象,执行mvn compile即可-->
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
执行mvn compile
之后,可以找到该target/generated-sources/java,
然后IDEA标示为源代码目录即可.
借鉴链接:https://www.jianshu.com/p/2b68af9aa0f5
共同学习,共同进步,若有补充,欢迎指出,谢谢!