Spring Data JPA动态查询

spring Data JPA大大的简化了我们持久层的开发,但是实际应用中,我们还是需要动态查询的。

    比如,前端有多个条件,这些条件很多都是可选的,那么后端的SQL,就应该是可以定制的,在使用hibernate的时候,可以通过判断条件来拼接SQL(HQL),当然,Spring Data JPA在简化我们开发的同时,也是提供了支持的。

    通过实现Criteria二实现的动态查询,需要我们的Repo接口继承JpaSpecificationExecutor接口,这是个泛型接口。

    然后查询的时候,传入动态查询参数,分页参数等即可。

    使用起来很简单,不过为了知其所以然,先介绍一下Criteria API。

    Criteria API

    如果编译器能够对查询执行语法正确性检查,那么对于 Java 对象而言该查询就是类型安全的。Java™Persistence API (JPA) 的 2.0 版本引入了 Criteria API,这个 API 首次将类型安全查询引入到 Java 应用程序中,并为在运行时动态地构造查询提供一种机制。本文介绍如何使用 Criteria API 和与之密切相关的 Metamodel API 编写动态的类型安全查询。

    在使用Spring Data JPA的时候,只要我们的Repo层继承JpaSpecificationExecutor接口就可以使用Specification进行动态查询了,我们先看下JpaSpecificationExecutor接口:

[java]  view plain  copy
 print ?
  1. public interface JpaSpecificationExecutor {  
  2.     T findOne(Specification spec);  
  3.     List findAll(Specification spec);  
  4.     Page findAll(Specification spec, Pageable pageable);  
  5.     List findAll(Specification spec, Sort sort);  
  6.     long count(Specification spec);  
  7. }  
    可以看到提供了5个方法,方法的参数和返回值已经很明显的表达了其意图。其中的参数,Pageable和Sort应该是比较简单的,分别是分页参数和排序参数,而重点就是Specification参数,先看下这个接口的定义:
[java]  view plain  copy
 print ?
  1. public interface Specification {  
  2.     Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb);  
  3. }  
    其中就一个方法,返回的是动态查询的数据结构。

    javax.persistence.criteria.Predicate toPredicate(javax.persistence.criteria.Root root,
    javax.persistence.criteria.CriteriaQuery query,
    javax.persistence.criteria.CriteriaBuilder cb);

    这里使用的都是Java EE中的规范,具体实现本人采用的是Hibernate,当然也可以选择其他实现了JPA规范的数据持久层框架。

    这里需要再次回过头看看Criteria API中的一些东西:

    Criteria 查询是以元模型的概念为基础的,元模型是为具体持久化单元的受管实体定义的,这些实体可以是实体类,嵌入类或者映射的父类。 

    CriteriaQuery接口:代表一个specific的顶层查询对象,它包含着查询的各个部分,比如:select 、from、where、group by、order by等注意:CriteriaQuery对象只对实体类型或嵌入式类型的Criteria查询起作用

    Root接口:代表Criteria查询的根对象,Criteria查询的查询根定义了实体类型,能为将来导航获得想要的结果,它与SQL查询中的FROM子句类似

    1:Root实例是类型化的,且定义了查询的FROM子句中能够出现的类型。

    2:查询根实例能通过传入一个实体类型给 AbstractQuery.from方法获得。

    3:Criteria查询,可以有多个查询根。

    4:AbstractQuery是CriteriaQuery 接口的父类,它提供得到查询根的方法。CriteriaBuilder接口:用来构建CritiaQuery的构建器对象Predicate:一个简单或复杂的谓词类型,其实就相当于条件或者是条件组合
    其中支持的方法非常之强大,下面给出一个示例,大家可以参考一下,同样的,可以根据示例,自己可以写出更为复杂的查询:
    Repo接口:

[java]  view plain  copy
 print ?
  1. public interface DevHREmpConstrastDao  
  2.         extends JpaRepository,JpaSpecificationExecutor  
    查询实例1:
[java]  view plain  copy
 print ?
  1. /** 
  2.  * 条件查询时动态组装条件 
  3.  */  
  4. private Specification where(  
  5.         final String corg,final String name,final String type,final String date,final String checker){  
  6.     return new Specification() {  
  7.         @Override  
  8.         public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) {  
  9.             List predicates = new ArrayList();  
  10.             //机构  
  11.             if(corg!=null&&!corg.equals("")){  
  12.                 List orgIds = organizationDao.findByName("%"+corg+"%");  
  13.                 if(orgIds.size()>0&&orgIds.size()<1000)  
  14.                     predicates.add(root.get("confirmOrgNo").in(orgIds));//confirmOrgNo  
  15.             }  
  16.             //名字  
  17.             if(name!=null&&!name.equals("")){  
  18.                 List userIds = userDao.findByName(name);  
  19.                 if(userIds.size()>0&&userIds.size()<1000)//如果太多就不管了这个条件了  
  20.                     predicates.add(root.get("hrUserName").in(userIds));  
  21.             }  
  22.             //类型  
  23.             if(type!=null&&!type.equals(""))  
  24.                 predicates.add(cb.equal(root.get("hrUpdateType"),type));  
  25.             //日期  
  26.             if(date!=null&&!date.equals("")){  
  27.                 //处理时间  
  28.                 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");  
  29.                 Date startDate;  
  30.                 Date endDate;  
  31.                 try {  
  32.                     startDate = format.parse(date);  
  33.                 } catch (ParseException e) {  
  34.                     startDate = new Date(946656000000L);//2000 01 01  
  35.                 }  
  36.                 endDate = startDate;  
  37.                 Calendar calendar = Calendar.getInstance() ;  
  38.                 calendar.setTime(endDate);  
  39.                 calendar.add(Calendar.DATE, 1);  
  40.                 endDate = calendar.getTime();  
  41.                 calendar = null;  
  42.                 predicates.add(cb.between(root.get("insDate"),startDate,endDate));  
  43.             }  
  44.             //审核人  
  45.             if(checker!=null&&!checker.equals("")){  
  46.                 List userIds = userDao.findByName(checker);  
  47.                 if(userIds.size()>0&&userIds.size()<1000)//如果太多就不管了这个条件了  
  48.                     predicates.add(root.get("confirmUserId").in(userIds));  
  49.             }  
  50.             return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();  
  51.         }  
  52.     };  
  53. }  
    查询实例2:

[java]  view plain  copy
 print ?
  1. /** 
  2.    * 条件查询时动态组装条件 
  3.    */  
  4.   private Specification where(  
  5.           final String corg,final String name,final String type,final String date,final String checker){  
  6.       return new Specification() {  
  7.           @Override  
  8.           public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) {  
  9.               List predicates = new ArrayList();  
  10.               //机构  
  11.               if(corg!=null&&!corg.equals("")){  
  12.                   List orgIds = organizationDao.findByName("%"+corg+"%");  
  13.                   if(orgIds.size()>0&&orgIds.size()<1000)  
  14.                       predicates.add(root.get("confirmOrgNo").in(orgIds));//confirmOrgNo  
  15.               }  
  16.               //名字  
  17.               if(name!=null&&!name.equals("")){  
  18.                   List userIds = userDao.findByName(name);  
  19.                   if(userIds.size()>0&&userIds.size()<1000)//如果太多就不管了这个条件了  
  20.                       predicates.add(root.get("hrUserName").in(userIds));  
  21.               }  
  22.               //类型  
  23.               if(type!=null&&!type.equals(""))  
  24.                   predicates.add(cb.equal(root.get("hrUpdateType"),type));  
  25.               //日期  
  26.               if(date!=null&&!date.equals("")){  
  27.                   //处理时间  
  28.                   SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");  
  29.                   Date startDate;  
  30.                   Date endDate;  
  31.                   try {  
  32.                       startDate = format.parse(date);  
  33.                   } catch (ParseException e) {  
  34.                       startDate = new Date(946656000000L);//2000 01 01  
  35.                   }  
  36.                   endDate = startDate;  
  37.                   Calendar calendar = Calendar.getInstance() ;  
  38.                   calendar.setTime(endDate);  
  39.                   calendar.add(Calendar.DATE, 1);  
  40.                   endDate = calendar.getTime();  
  41.                   calendar = null;  
  42.                   predicates.add(cb.between(root.get("insDate"),startDate,endDate));  
  43.               }  
  44.               //审核人  
  45.               if(checker!=null&&!checker.equals("")){  
  46.                   List userIds = userDao.findByName(checker);  
  47.                   if(userIds.size()>0&&userIds.size()<1000)//如果太多就不管了这个条件了  
  48.                       predicates.add(root.get("confirmUserId").in(userIds));  
  49.               }  
  50.               return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();  
  51.           }  
  52.       };  
  53.   }  

    然后调用dao层方法传入where()方法返回的参数即可。




项目结构如下:

Spring Data JPA动态查询_第1张图片


pom.xml

[html]  view plain  copy
 
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  2.     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">  
  3.     <modelVersion>4.0.0modelVersion>  
  4.   
  5.     <groupId>cn.dbgroupId>  
  6.     <artifactId>psqlartifactId>  
  7.     <packaging>warpackaging>  
  8.     <version>0.0.1-SNAPSHOTversion>  
  9.   
  10.     <name>psql Maven Webappname>  
  11.     <url>http://maven.apache.orgurl>  
  12.   
  13.     <dependencies>  
  14.   
  15.         <dependency>  
  16.             <groupId>junitgroupId>  
  17.             <artifactId>junitartifactId>  
  18.             <version>4.10version>  
  19.             <scope>testscope>  
  20.         dependency>  
  21.   
  22.         <dependency>  
  23.             <groupId>commons-dbcpgroupId>  
  24.             <artifactId>commons-dbcpartifactId>  
  25.             <version>1.4version>  
  26.         dependency>  
  27.   
  28.         <dependency>  
  29.             <groupId>javax.servletgroupId>  
  30.             <artifactId>jsp-apiartifactId>  
  31.             <version>2.0version>  
  32.         dependency>  
  33.   
  34.         <dependency>  
  35.             <groupId>mysqlgroupId>  
  36.             <artifactId>mysql-connector-javaartifactId>  
  37.             <version>5.1.5version>  
  38.         dependency>  
  39.   
  40.         <dependency>  
  41.             <groupId>org.springframework.datagroupId>  
  42.             <artifactId>spring-data-jpaartifactId>  
  43.             <version>1.6.1.RELEASEversion>  
  44.         dependency>  
  45.   
  46.         <dependency>  
  47.             <groupId>org.springframework.bootgroupId>  
  48.             <artifactId>spring-boot-starter-data-jpaartifactId>  
  49.             <version>1.1.4.RELEASEversion>  
  50.         dependency>  
  51.   
  52.         <dependency>  
  53.             <groupId>org.apache.maven.pluginsgroupId>  
  54.             <artifactId>maven-resources-pluginartifactId>  
  55.             <version>2.6version>  
  56.         dependency>  
  57.   
  58.     dependencies>  
  59.   
  60.     <repositories>  
  61.         <repository>  
  62.             <id>spring-milestonesid>  
  63.             <url>http://repo.spring.io/libs-milestoneurl>  
  64.         repository>  
  65.     repositories>  
  66.   
  67.     <build>  
  68.         <plugins>  
  69.             <plugin>  
  70.                 <groupId>org.apache.maven.pluginsgroupId>  
  71.                 <artifactId>maven-compiler-pluginartifactId>  
  72.                 <configuration>  
  73.                     <source>1.8source>  
  74.                     <target>1.8target>  
  75.                 configuration>  
  76.             plugin>  
  77.         plugins>  
  78.     build>  
  79.   
  80. project>  


persistence.xml

[html]  view plain  copy
 
  1. xml version="1.0" encoding="UTF-8"?>  
  2.   
  3. <persistence xmlns="http://java.sun.com/xml/ns/persistence"  
  4.     version="2.0">  
  5.     <persistence-unit name="SimplePU" transaction-type="RESOURCE_LOCAL">  
  6.         <provider>org.hibernate.ejb.HibernatePersistenceprovider>  
  7.   
  8.         <properties>  
  9.             <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />  
  10.             <property name="hibernate.connection.url" value="jdbc:mysql://127.0.0.1:3306/db_cloud" />  
  11.             <property name="hibernate.connection.username" value="root" />  
  12.             <property name="hibernate.connection.password" value="root" />  
  13.             <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />  
  14.             <property name="hibernate.show_sql" value="true" />  
  15.             <property name="hibernate.format_sql" value="true" />  
  16.             <property name="hibernate.use_sql_comments" value="false" />  
  17.             <property name="hibernate.hbm2ddl.auto" value="update" />  
  18.         properties>  
  19.     persistence-unit>  
  20. persistence>   


applicationContext.xml

[html]  view plain  copy
 
  1. xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"  
  4.     xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"  
  5.     xmlns:jpa="http://www.springframework.org/schema/data/jpa"  
  6.     xsi:schemaLocation="    
  7.         http://www.springframework.org/schema/beans    
  8.         http://www.springframework.org/schema/beans/spring-beans.xsd    
  9.         http://www.springframework.org/schema/tx    
  10.         http://www.springframework.org/schema/tx/spring-tx.xsd    
  11.         http://www.springframework.org/schema/data/jpa  
  12.         http://www.springframework.org/schema/data/jpa/spring-jpa.xsd  
  13.         http://www.springframework.org/schema/context    
  14.         http://www.springframework.org/schema/context/spring-context.xsd">  
  15.   
  16.     <bean name="dataSource" class="org.apache.commons.dbcp.BasicDataSource">  
  17.         <property name="driverClassName">  
  18.             <value>com.mysql.jdbc.Drivervalue>  
  19.         property>  
  20.         <property name="url">  
  21.             <value>jdbc:mysql://127.0.0.1:3306/db_cloudvalue>  
  22.         property>  
  23.         <property name="username" value="root" />  
  24.         <property name="password" value="root" />  
  25.     bean>  
  26.   
  27.     <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">  
  28.         <property name="entityManagerFactory" ref="entityManagerFactory" />  
  29.     bean>  
  30.   
  31.     <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>  
  32.   
  33.     <bean id="entityManagerFactory"  
  34.         class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">  
  35.     bean>  
  36.   
  37.     <jpa:repositories base-package="cn.db.psql"  
  38.         entity-manager-factory-ref="entityManagerFactory"  
  39.         transaction-manager-ref="transactionManager" />  
  40.   
  41. beans>    


Person.Java

[java]  view plain  copy
 
  1. package cn.db.psql;  
  2.   
  3. import javax.persistence.Column;  
  4. import javax.persistence.Entity;  
  5. import javax.persistence.GeneratedValue;  
  6. import javax.persistence.GenerationType;  
  7. import javax.persistence.Id;  
  8. import javax.persistence.Table;  
  9.   
  10. @Entity  
  11. @Table(name = "ts_person")   
  12. public class Person {  
  13.       
  14.     @Column  
  15.     @Id  
  16.     @GeneratedValue(strategy=GenerationType.IDENTITY)  
  17.     private Integer userid;  
  18.       
  19.     @Column  
  20.     private String username;  
  21.       
  22.     @Column  
  23.     private String stype;  
  24.       
  25.     @Column  
  26.     private Integer city_id;  
  27.   
  28.     public Integer getUserid() {  
  29.         return userid;  
  30.     }  
  31.   
  32.     public void setUserid(Integer userid) {  
  33.         this.userid = userid;  
  34.     }  
  35.   
  36.     public String getUsername() {  
  37.         return username;  
  38.     }  
  39.   
  40.     public void setUsername(String username) {  
  41.         this.username = username;  
  42.     }  
  43.   
  44.     public String getStype() {  
  45.         return stype;  
  46.     }  
  47.   
  48.     public void setStype(String stype) {  
  49.         this.stype = stype;  
  50.     }  
  51.   
  52.     public Integer getCity_id() {  
  53.         return city_id;  
  54.     }  
  55.   
  56.     public void setCity_id(Integer city_id) {  
  57.         this.city_id = city_id;  
  58.     }  
  59.       
  60.     public String toString()  
  61.     {  
  62.         return "[userid="+userid+",username="+username+",stype="+stype+",city_id="+city_id+"]";  
  63.     }  
  64. }  

PersonJpaSpecificationExecutor.java

[java]  view plain  copy
 
  1. package cn.db.psql;  
  2.   
  3. import java.util.List;  
  4.   
  5. import org.springframework.data.domain.Page;  
  6. import org.springframework.data.domain.Pageable;  
  7. import org.springframework.data.jpa.domain.Specification;  
  8. import org.springframework.data.jpa.repository.JpaRepository;  
  9. import org.springframework.data.jpa.repository.JpaSpecificationExecutor;  
  10. import org.springframework.stereotype.Repository;  
  11.   
  12. /** 
  13.  * 复杂条件的查询 
  14.  */  
  15. @Repository("personJpaSpecificationExecutor")  
  16. public interface PersonJpaSpecificationExecutor extends JpaRepository, JpaSpecificationExecutor   
  17. {  
  18.     Page findAll(Specification spec, Pageable pageable);  //分页按条件查询    
  19.       
  20.     List findAll(Specification spec);  
  21. }  

PersonRepository.java

[java]  view plain  copy
 
  1. package cn.db.psql;  
  2.   
  3. import org.springframework.data.jpa.repository.JpaRepository;  
  4. import org.springframework.data.jpa.repository.Query;  
  5. import org.springframework.data.repository.query.Param;  
  6. import org.springframework.stereotype.Repository;  
  7.   
  8. /** 
  9.  * 简单的查询 
  10.  */  
  11. @Repository("personRepository")  
  12. public interface PersonRepository extends JpaRepository   
  13. {  
  14.     @Query("select a from Person a where a.userid = :userid")  
  15.     public Person findByUserid(@Param("userid")Integer userid);  
  16. }  


PersonSpecification.java

[java]  view plain  copy
 
  1. package cn.db.psql;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import javax.persistence.criteria.CriteriaBuilder;  
  7. import javax.persistence.criteria.CriteriaQuery;  
  8. import javax.persistence.criteria.Path;  
  9. import javax.persistence.criteria.Predicate;  
  10. import javax.persistence.criteria.Root;  
  11.   
  12. import org.springframework.data.jpa.domain.Specification;  
  13.   
  14. public class PersonSpecification implements Specification  
  15. {  
  16.     private String _username;  
  17.     private String _stype;  
  18.     private Integer _cityId;  
  19.       
  20.     public PersonSpecification(String username, String stype, Integer cityId)  
  21.     {  
  22.         this._username = username;  
  23.         this._stype = stype;  
  24.         this._cityId = cityId;  
  25.     }  
  26.       
  27.     public Predicate toPredicate(Root root, CriteriaQuery query,CriteriaBuilder cb)   
  28.     {  
  29.           
  30.         Path username = root.get("username");  
  31.           
  32.         Path stype = root.get("stype");  
  33.         Path city_id = root.get("city_id");  
  34.           
  35.         List list = new ArrayList();   
  36.           
  37.         Predicate pa = cb.equal(username, _username);  
  38.         Predicate pb = cb.equal(stype, _stype);  
  39.         Predicate pc = cb.equal(city_id, _cityId);  
  40.           
  41.         if(_username != null)  
  42.         {  
  43.             list.add(pa);  
  44.         }  
  45.         if(_stype != null)  
  46.         {  
  47.             list.add(pb);  
  48.         }  
  49.         if(_cityId != null)  
  50.         {  
  51.             list.add(pc);  
  52.         }  
  53.           
  54.         Predicate[] parray = new Predicate[list.size()];  
  55.           
  56.         return cb.and(list.toArray(parray));  
  57.     }  
  58.   
  59.     public String get_username() {  
  60.         return _username;  
  61.     }  
  62.   
  63.     public void set_username(String _username) {  
  64.         this._username = _username;  
  65.     }  
  66.   
  67.     public String get_stype() {  
  68.         return _stype;  
  69.     }  
  70.   
  71.     public void set_stype(String _stype) {  
  72.         this._stype = _stype;  
  73.     }  
  74.   
  75.     public Integer get_cityId() {  
  76.         return _cityId;  
  77.     }  
  78.   
  79.     public void set_cityId(Integer _cityId) {  
  80.         this._cityId = _cityId;  
  81.     }  
  82. }  


Client.java

[java]  view plain  copy
 
  1. package cn.db.psql;  
  2.   
  3. import java.util.List;  
  4.   
  5. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  6.   
  7. public class Client {  
  8.       
  9.     public static void find() throws Exception  
  10.     {  
  11.         ClassPathXmlApplicationContext ctx =   
  12.                 new ClassPathXmlApplicationContext("applicationContext.xml");   
  13.           
  14.         try  
  15.         {  
  16.             PersonJpaSpecificationExecutor ur = (PersonJpaSpecificationExecutor)ctx.getBean("personJpaSpecificationExecutor");  
  17.               
  18.             PersonSpecification us = new PersonSpecification(null,"1",1);  
  19.               
  20.             List plist = ur.findAll(us);  
  21.               
  22.             System.out.println("==============================================");  
  23.               
  24.             for(Person p : plist)  
  25.             {  
  26.                 System.out.println(p);  
  27.             }  
  28.               
  29.             System.out.println("==============================================");  
  30.               
  31.         }catch(Exception e)  
  32.         {  
  33.             e.printStackTrace();  
  34.         }  
  35.           
  36.         ctx.close();  
  37.     }  
  38.       
  39.     public static void main(String[] args) throws Exception  
  40.     {  
  41.         find();  
  42.     }  
  43. }  




FastQuery 快速操作数据层框架

FastQuery 基于Java语言.他的使命是:简化Java操作数据层.做为一个开发者, 仅仅只需要设计DAO接口即可,其内部采用ASM动态生成实现,执行快. 因此,代码简洁而优雅.从而,大幅度提升开发效率.

FastQuery 主要特性如下:

  1. 设计优雅,配置简单,极易上手.
  2. 采用ASM动态生成字节码,因此支持编译前预处理,可最大限度减少运行期的错误.显著提升程序的强壮性.
  3. 支持安全查询,防止SQL注入.
  4. 支持与主流数据库连接池框架集成,如集成c3p0,dbcp等等
  5. 支持 @Query 查询,使用 @Condition,可实现动态 where 条件查询.
  6. 支持查询结果集以JSON类型返回
  7. 支持AOP,注入拦截器只需标识几个简单的注解,如: @Before , @After

运行环境要求

jdk1.8+

配置文件

jdbc-config.xml

用来配置支持jdbc. 注意:如果采用连接池,该配置文件可以不要.


<jdbc-config>  
        
        <named-config name="xk_db">  
        <property name="driverClass">com.mysql.jdbc.Driverproperty>  
        <property name="url">jdbc:mysql://192.168.1.1:3306/xk?user=xk&password=abc123property>
        named-config>

        
        <named-config name="shtest_db">  
        <property name="driverClass">com.mysql.jdbc.Driverproperty>  
        <property name="databaseName">dbnameproperty>  
        <property name="user">usernameproperty>  
        <property name="password">userpasswdproperty>   
        <property name="portNumber">3306property>   
        <property name="serverName">192.168.1.1property> 
    named-config>
jdbc-config>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

c3p0-config.xml

支持c3p0配置,详情配置请参照c3p0官网的说明: http://www.mchange.com/projects/c3p0/.


<c3p0-config>  
       
    <named-config name="xk-c3p0">  
        <property name="driverClass">com.mysql.jdbc.Driverproperty>  
        <property name="jdbcUrl">jdbc:mysql://192.168.1.1:3306/xkproperty>  
        <property name="user">xkproperty>  
        <property name="password">abc123property>  
        <property name="acquireIncrement">50property>  
        <property name="initialPoolSize">100property>  
        <property name="minPoolSize">50property>  
        <property name="maxPoolSize">1000property>
        <property name="maxStatements">0property>  
        <property name="maxStatementsPerConnection">5property>     
        named-config> 
c3p0-config>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

fastquery.json

配置数据源的作用范围

// @author xixifeng ([email protected])
// 配置必须遵循标准的json语法.
[
    // config目前支持的可选值有"jdbc","c3p0"
    {
        "config": "c3p0",            // 表示由c3p0负责提供数据源
        "dataSourceName": "xk-c3p0", // 数据源的名称
        "basePackages": [            // 该数据源的作用范围
            "org.fastquery.example.StudentDBService"
            // 在这可以配置多个DB接口,以","号隔开
        ]
    },

    /*
     再配置一个数据源作用域
    */
    {
        "config" : "jdbc",            // 表示由jdbc驱动负责提供数据源
        "dataSourceName": "shtest_db",
        "basePackages": [ // 该数据源的作用范围
            "org.fastquery.example.DataAcquireDbService"
                // 在这可以配置多个DB接口,以","号隔开
        ]
    }
]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

一个完整的入门例子

  • 准备一个实体
 public class Student
 {
      private String no;
      private String name;
      private String sex;
      private Integer age;
      private String dept;
      // getter /setter 省略...
 } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • DAO接口
 public interface StudentDBService extends QueryRepository {
    @Query("select * from student")
    JSONArray findAll();
    @Query("select * from student")
    Student[] find();      
 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 使用DAO接口.

    注意:不用去实现StudentDBService接口.

 // get porxy impl
 StudentDBService studentDBService = FQuery.getRepository(StudentDBService.class);
 // call findAll
 JSONArray jsonArray = studentDBService.findAll();
 // call find
 Student[] students = studentDBService.find(); 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

带条件查询

// sql中的?1 表示当前方法的第一个参数
// sql中的?2 表示当前方法的第二个参数
//       ?N 表示当前方法的第N个参数

// 查询返回数组格式
@Query("select no as no,name,sex,age,dept from student s where s.sex=?2 and s.age > ?1")
Student[] find(Integer age,String sex);

// 查询返回JSON格式
@Query("select * from student s where s.sex=?1 and s.age > ?2")
JSONArray find(String sex,Integer age);

// 查询返回List Map
@Query("select * from student s where s.sex=?1 and s.age > ?2")
List> findBy(String sex,Integer age);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

动态条件查询

@Query("select * from Student #{#where} order by age desc")
// 增加一些条件
@Condition(l="no",o=Operator.LIKE,r="?1") // ?1的值,如果是null, 该行条件将不参与运算
@Condition(c=COperator.AND,l="name",o=Operator.LIKE,r="?2") // 参数 ?2,如果接收到的值为null,该条件不参与运算
//通过 ignoreNull=false 开启条件值即使是null也参与运算
@Condition(c=COperator.AND,l="age",o=Operator.GT,r="?3",ignoreNull=false) // ?3接收到的值若为null,该条件也参与运算.
@Condition(c=COperator.OR,l="dept",o=Operator.IN,r="(?4,?5,?6)")// dept in(?4,?5,?6)
@Condition(c=COperator.AND,l="name",o={Operator.NOT,Operator.LIKE},r="?7") // 等效于 name not like ?7
@Condition(c=COperator.OR,l="age",o=Operator.BETWEEN,r="?8 and ?9") // 等效于 age between ?8 and ?9
Student[] findAllStudent(... args ...);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

count

统计查询行数

@Query("select count(no) from student")
long count();
  • 1
  • 2
  • 1
  • 2

exists

判断是否存在

@Query("select * from student s where s.no=?1")
boolean exists(String no);
  • 1
  • 2
  • 1
  • 2

改操作

@Query("update student s set s.age=?3,s.name=?2 where  s.no=?1")
@Modifying
int update(String no,String name,int age); // 返回修改之后所影响的行数

@Modifying
@Query("DELETE FROM `userinfo` WHERE id=?1")
boolean deleteUserinfoById(int id);

@Query("update student s set s.age=?2 where  s.no=?1")
@Modifying
int update(String no,int age);

// 以实体bean格式,返回当前保存的数据
@Query("insert into student (no, name, sex, age, dept) values (?1, ?2, ?3, ?4, ?5)")
@Modifying(table="student",id="no")
// 注意: student的主键是字符串不会自增长,在此处需要用@Id标识
Student addStudent(@Id String no,String name,String sex,int age,String dept);

// 以Map格式,返回当前保存的数据
@Modifying(id="id",table="userinfo")
@Query("insert into #{#table} (name,age) values (?1, ?2)")
Map addUserInfo(String name,Integer age);

// 以JSON格式,返回当前保存的数据
@Modifying(id="id",table="userinfo")
@Query("insert into #{#table} (name,age) values (?1, ?2)")
JSONObject saveUserInfo2(String name,Integer age);

// 返回当前保存的数据的主键信息.
@Modifying(id="id",table="userinfo")
@Query("insert into #{#table} (name,age) values (?1, ?2)")
Primarykey saveUserInfo(String name,Integer age);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

@Before拦截器

  • 准备一个BeforeFilter
 /**
  * @author xixifeng ([email protected])
  */
 public class MyBeforeFilter1 extends BeforeFilter<Repository> {

    @Override
    public void doFilter(Repository repository, Method method, Object[] args) {

        // repository: 当前拦截到的实例
        // method: 当前拦截到的方法
        // args: 当前传递进来的参数

        // this.abortWith(returnVal); // 中断拦截器

    }
 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 注入Filter
// 可以同时标识多个@Before
@Before(MyBeforeFilter1.class)
@Before(MyBeforeFilter2.class)
@Before(MyBeforeFilter3.class)
public interface StudentDBService extends QueryRepository {
 // some code ... ...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

@After拦截器

/**
 * @author xixifeng ([email protected])
 */
public class MyAfterFilter extends AfterFilter<Repository> {

    @Override
    public Object doFilter(Repository repository, Method method, Object[] args, Object returnVal) {

        // repository: 当前拦截到的实例
        // method: 当前拦截到的method
        // args: 当前传递进来的参数
        // returnVal 即将返回的值

        // 在这里可以中途修改 returnVal

        return returnVal;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
// 可以同时标识多个@After
@After(MyAfterFilter.class)
@After(MyAfterFilter2.class)
public interface StudentDBService extends QueryRepository {
    // some code ... ...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

开源地址

http://www.oschina.net/p/fastquery


你可能感兴趣的:(java)