SpringData详解

   

 1.什么是SpringData?

Spring Data 项目的目的是为了简化构建基于 Spring 框架应用的数据访问计数,包括非关系数据库、Map-Reduce 框架、云数据服务等等;另外也包含对关系数据库的访问支持。

Spring Data 包含多个子项目:

  • Commons - 提供共享的基础框架,适合各个子项目使用,支持跨数据库持久化

  • Hadoop - 基于 Spring 的 Hadoop 作业配置和一个 POJO 编程模型的 MapReduce 作业

  • Key-Value  - 集成了 Redis 和 Riak ,提供多个常用场景下的简单封装

  • Document - 集成文档数据库:CouchDB 和 MongoDB 并提供基本的配置映射和资料库支持

  • Graph - 集成 Neo4j 提供强大的基于 POJO 的编程模型

  • Graph Roo AddOn - Roo support for Neo4j

  • JDBC Extensions - 支持 Oracle RAD、高级队列和高级数据类型

  • JPA - 简化创建 JPA 数据访问层和跨存储的持久层功能

  • Mapping - 基于 Grails 的提供对象映射框架,支持不同的数据库

  • Examples - 示例程序、文档和图数据库

  • Guidance - 高级文档


 看了这么多专业的介绍,其实Spring Data项目旨在为大家提供一种通用的编码模式,统一我们的API。


 2.HelloWorld展示
 学习任何东西,从一个简单易懂的DEMO学起,会非常重要,下面先来看一个简单的HelloWorlddemo
 直接看一下Dao层吧!
 
  1. <span style=“font-family:Comic Sans MS;font-size:18px;”>/**      
  2.  * @FileName: PersonRepotory.java    
  3.  * @Package:com.tgb.springdata.Entity    
  4.  * @Description: TODO   
  5.  * @author: LUCKY     
  6.  * @date:2015年11月8日 下午6:38:58    
  7.  * @version V1.0      
  8.  */  
  9. package com.tgb.springdata.Entity;  
  10.   
  11. import java.util.Date;  
  12. import java.util.List;  
  13.   
  14. import org.hibernate.type.TrueFalseType;  
  15. import org.springframework.data.jpa.repository.JpaRepository;  
  16. import org.springframework.data.jpa.repository.JpaSpecificationExecutor;  
  17. import org.springframework.data.jpa.repository.Modifying;  
  18. import org.springframework.data.jpa.repository.Query;  
  19. import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;  
  20. import org.springframework.data.repository.CrudRepository;  
  21. import org.springframework.data.repository.PagingAndSortingRepository;  
  22. import org.springframework.data.repository.Repository;  
  23. import org.springframework.data.repository.query.Param;  
  24.   
  25. /**   
  26.  * @ClassName: PersonRepotory    
  27.  * @Description: TODO   
  28.  * @author: LUCKY   
  29.  * @date:2015年11月8日 下午6:38:58      
  30.  */  
  31.   
  32. /* 
  33.  * 1.Repository是一个空接口,即是一个标记接口 
  34.  * 2.若我们定义的接口继承了Repository,则该接口会被IOC容器识别为一个Repository Bean 
  35.  * 注入到IOC容器中,进而可以在该接口中定义满足一定规则的接口 
  36.  * 3.实际上也可以通过一个注解@RepositoryDefination 注解来替代Repository接口 
  37.  */  
  38. /* 
  39.  * 在Repository子接口中声明方法 
  40.  * 1.不是随便声明的,而需要符合一定的规范 
  41.  * 2.查询方法以find|read|get开发 
  42.  * 3.涉及条件查询,条件的属性需要定义关键字连接 
  43.  * 4.要注意的额是,条件的属性以字母大写 
  44.  * 5.支持属性的级联查询,若当前类有符合条件的属性,则优先使用,则不使用级联属性 
  45.  * 若需要使用级联属性,则属性之间使用——进行连接 
  46.  */  
  47. //@RepositoryDefinition(domainClass=Person.class,idClass=Integer.class)  
  48. public interface PersonRepotory  extends JpaRepository<Person,Integer>,JpaSpecificationExecutor<Person>,PersonDao  {  
  49.   
  50.       
  51.     //根据lastname,来获取对应的Person  
  52.     Person getByLastName(String lastName);  
  53.       
  54.     //Where lastName like ?% and id<?  
  55.     List<Person> getByLastNameStartingWithAndIdLessThan(String lastName,Integer id);  
  56.       
  57.       
  58.     //Where lastName like ?% and id<?  
  59.     List<Person> getByLastNameEndingWithAndIdLessThan(String lastName,Integer id);  
  60.       
  61.     //where email In(?,?,?) Or birth < ?  
  62.     List<Person> getByEmailInOrBirthLessThan(List<String> emails,Date birth);  
  63.       
  64.     //where a.id>?  
  65.     List<Person> getByAddressIdGreaterThan(Integer id);  
  66.       
  67.     //查询id值最大的那个person  
  68.     //使用@Query注解可以自定义JPQL语句,语句可以实现更灵活的查询  
  69.     @Query(“SELECT p FROM Person p WHERE p.id=(SELECT max(p2.id) FROM Person p2)”)  
  70.     Person getMaxIdPerson();  
  71.       
  72.     //为@Query注解传递参数的方式1:使用占位符  
  73.     @Query(“SELECT P FROM Person P where P.lastName=?1 AND P.email=?2”)  
  74.     List<Person> testQueryAnnotationParams1(String lastName,String email);  
  75.       
  76.       
  77.       
  78.     //为@Query注解传递参数的方式2:使用命名参数方式  
  79.         @Query(“SELECT P FROM Person P where P.lastName=:lastName AND P.email=:email”)  
  80.         List<Person> testQueryAnnotationParams2(@Param(“email”)String email,@Param(“lastName”)String lastName);  
  81.           
  82.           
  83.         //Spring Data 运行在占位符上添加%%  
  84.         @Query(“select p from Person p where p.lastName like %?1% or p.email like %?2%”)  
  85.         List<Person> testQueryAnnotationLikeParam(String lastName,String email);  
  86.           
  87.         //设置nativeQuery=true 可以使用原生的sql查询  
  88.         @Query(value=“SELECT count(id) FROM jpa_persons”,nativeQuery=true)  
  89.         public long getTotalCount();  
  90.           
  91.           
  92.         //可以通过自定义的JPQL 完成update和delete操作,注意:JPQL不支持Insert操作  
  93.         //在@Query注解中编写JPQL语句,但必须使用@Modify进行修饰,以通知SpringData,这是一个Update或者Delete  
  94.         //Update或者delete操作,需要使用事务,此时需要定义Service层,在service层的方法上添加事务操作  
  95.         //默认情况下,SpringData的每个方法上有事务,但都是一个只读事务,他们不能完成修改操作  
  96.         @Modifying  
  97.         @Query(“update Person p set p.email=:email where id=:id”)  
  98.         void updatePersonEmail(@Param(“id”)Integer id,@Param(“email”)String email);  
  99.           
  100.           
  101. }  
  102. </span>  
<span style="font-family:Comic Sans MS;font-size:18px;">/**     
 * @FileName: PersonRepotory.java   
 * @Package:com.tgb.springdata.Entity   
 * @Description: TODO  
 * @author: LUCKY    
 * @date:2015年11月8日 下午6:38:58   
 * @version V1.0     
 */
package com.tgb.springdata.Entity;

import java.util.Date;
import java.util.List;

import org.hibernate.type.TrueFalseType;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.query.Param;

/**  
 * @ClassName: PersonRepotory   
 * @Description: TODO  
 * @author: LUCKY  
 * @date:2015年11月8日 下午6:38:58     
 */

/*
 * 1.Repository是一个空接口,即是一个标记接口
 * 2.若我们定义的接口继承了Repository,则该接口会被IOC容器识别为一个Repository Bean
 * 注入到IOC容器中,进而可以在该接口中定义满足一定规则的接口
 * 3.实际上也可以通过一个注解@RepositoryDefination 注解来替代Repository接口
 */
/*
 * 在Repository子接口中声明方法
 * 1.不是随便声明的,而需要符合一定的规范
 * 2.查询方法以find|read|get开发
 * 3.涉及条件查询,条件的属性需要定义关键字连接
 * 4.要注意的额是,条件的属性以字母大写
 * 5.支持属性的级联查询,若当前类有符合条件的属性,则优先使用,则不使用级联属性
 * 若需要使用级联属性,则属性之间使用——进行连接
 */
//@RepositoryDefinition(domainClass=Person.class,idClass=Integer.class)
public interface PersonRepotory  extends JpaRepository<Person,Integer>,JpaSpecificationExecutor<Person>,PersonDao  {


    //根据lastname,来获取对应的Person
    Person getByLastName(String lastName);

    //Where lastName like ?% and id<?
    List<Person> getByLastNameStartingWithAndIdLessThan(String lastName,Integer id);


    //Where lastName like ?% and id<?
    List<Person> getByLastNameEndingWithAndIdLessThan(String lastName,Integer id);

    //where email In(?,?,?) Or birth < ?
    List<Person> getByEmailInOrBirthLessThan(List<String> emails,Date birth);

    //where a.id>?
    List<Person> getByAddressIdGreaterThan(Integer id);

    //查询id值最大的那个person
    //使用@Query注解可以自定义JPQL语句,语句可以实现更灵活的查询
    @Query("SELECT p FROM Person p WHERE p.id=(SELECT max(p2.id) FROM Person p2)")
    Person getMaxIdPerson();

    //为@Query注解传递参数的方式1:使用占位符
    @Query("SELECT P FROM Person P where P.lastName=?1 AND P.email=?2")
    List<Person> testQueryAnnotationParams1(String lastName,String email);



    //为@Query注解传递参数的方式2:使用命名参数方式
        @Query("SELECT P FROM Person P where P.lastName=:lastName AND P.email=:email")
        List<Person> testQueryAnnotationParams2(@Param("email")String email,@Param("lastName")String lastName);


        //Spring Data 运行在占位符上添加%%
        @Query("select p from Person p where p.lastName like %?1% or p.email like %?2%")
        List<Person> testQueryAnnotationLikeParam(String lastName,String email);

        //设置nativeQuery=true 可以使用原生的sql查询
        @Query(value="SELECT count(id) FROM jpa_persons",nativeQuery=true)
        public long getTotalCount();


        //可以通过自定义的JPQL 完成update和delete操作,注意:JPQL不支持Insert操作
        //在@Query注解中编写JPQL语句,但必须使用@Modify进行修饰,以通知SpringData,这是一个Update或者Delete
        //Update或者delete操作,需要使用事务,此时需要定义Service层,在service层的方法上添加事务操作
        //默认情况下,SpringData的每个方法上有事务,但都是一个只读事务,他们不能完成修改操作
        @Modifying
        @Query("update Person p set p.email=:email where id=:id")
        void updatePersonEmail(@Param("id")Integer id,@Param("email")String email);


}
</span>

 在Spring Data JPA中通过继承接口就可以了,下面来看一下是如何来调用的

 

  1. <span style=“font-family:Comic Sans MS;font-size:18px;”>/**      
  2.  * @FileName: SpringDataTest.java    
  3.  * @Package:com.tgb.test    
  4.  * @Description: TODO   
  5.  * @author: LUCKY     
  6.  * @date:2015年11月8日 下午5:35:37    
  7.  * @version V1.0      
  8.  */  
  9. package com.tgb.test;  
  10.   
  11. import static org.junit.Assert.*;  
  12.   
  13. import java.sql.SQLException;  
  14. import java.util.ArrayList;  
  15. import java.util.Arrays;  
  16. import java.util.Date;  
  17. import java.util.List;  
  18.   
  19. import javax.persistence.criteria.CriteriaBuilder;  
  20. import javax.persistence.criteria.CriteriaQuery;  
  21. import javax.persistence.criteria.Path;  
  22. import javax.persistence.criteria.Predicate;  
  23. import javax.persistence.criteria.Root;  
  24. import javax.sql.DataSource;  
  25.   
  26. import org.junit.Test;  
  27. import org.springframework.context.ApplicationContext;  
  28. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  29. import org.springframework.data.domain.Page;  
  30. import org.springframework.data.domain.PageRequest;  
  31. import org.springframework.data.domain.Pageable;  
  32. import org.springframework.data.domain.Sort;  
  33. import org.springframework.data.domain.Sort.Direction;  
  34. import org.springframework.data.domain.Sort.Order;  
  35. import org.springframework.data.jpa.domain.Specification;  
  36.   
  37. import com.tgb.springdata.Entity.Person;  
  38. import com.tgb.springdata.Entity.PersonRepotory;  
  39. import com.tgb.springdata.Service.PersonService;  
  40.   
  41. /**   
  42.  * @ClassName: SpringDataTest    
  43.  * @Description: TODO   
  44.  * @author: LUCKY   
  45.  * @date:2015年11月8日 下午5:35:37      
  46.  */  
  47. public class SpringDataTest {  
  48.   
  49.     private PersonRepotory personRepotory=null;  
  50.     private PersonService personService;  
  51.     private ApplicationContext ctx=null;  
  52.     {  
  53.         ctx=new ClassPathXmlApplicationContext(“applicationContext.xml”);  
  54.         personRepotory=ctx.getBean(PersonRepotory.class);  
  55.         personService=ctx.getBean(PersonService.class);  
  56.     }  
  57.       
  58.       
  59.     @Test  
  60.     public void testKeyWorlds(){  
  61.         List<Person> persons=personRepotory.getByLastNameStartingWithAndIdLessThan(”BB”10);  
  62.         System.out.println(persons);  
  63.           
  64.         List<Person> persons1=personRepotory.getByLastNameEndingWithAndIdLessThan(”BB”10);  
  65.         System.out.println(persons);  
  66.         System.out.println(persons1);  
  67.           
  68.         persons=personRepotory.getByEmailInOrBirthLessThan(Arrays.asList(”aa@qq.com”,“bb@qq.com”),new Date());  
  69.         System.out.println(persons.size());  
  70.     }  
  71.       
  72.       
  73.       
  74.       
  75.       
  76.     @Test  
  77.     public void testDataSource() throws SQLException{  
  78.         DataSource dataSource=ctx.getBean(DataSource.class);  
  79.         System.out.println(dataSource.getConnection());  
  80.     }  
  81.       
  82.     @Test  
  83.     public void TestJpa(){  
  84.           
  85.     }  
  86.       
  87.     @Test  
  88.     public void testKeyWorlds2(){  
  89.         List<Person> persons=personRepotory.getByAddressIdGreaterThan(1);  
  90.         System.out.println(persons);  
  91.     }  
  92.       
  93.     @Test  
  94.     public void testQueryAnnotation(){  
  95.         Person person=personRepotory.getMaxIdPerson();  
  96. //      System.out.println(person);  
  97.           
  98.         List<Person> persons=personRepotory.testQueryAnnotationParams1(”AA”“bb”);  
  99.         System.out.println(persons);  
  100.           
  101.         List<Person> persons1=personRepotory.testQueryAnnotationParams2(”bb”“AA”);  
  102.         System.out.println(persons1);  
  103.     }  
  104.       
  105.       
  106.     @Test  
  107.     public void testModifing(){  
  108. //      personRepotory.updatePersonEmail(1, ”@@qq.com”);  
  109.         personService.updatePersonEmail(”aa@aa”1);  
  110.     }  
  111.       
  112.     @Test  
  113.     public void testQueryLikeAnnotationParam(){  
  114.         List<Person> persons=personRepotory.testQueryAnnotationLikeParam(”%AA%”“%b%”);  
  115.         System.out.println(persons);  
  116.           
  117.         long count=personRepotory.getTotalCount();  
  118.         System.out.println(count);  
  119.     }  
  120.       
  121.       
  122.       
  123.       
  124.     @Test  
  125.     public void HelloWorldSpringData(){  
  126.         PersonRepotory personRepotory=ctx.getBean(PersonRepotory.class);  
  127.         System.out.println(personRepotory.getClass().getName());  
  128.         Person person=personRepotory.getByLastName(”AA”);  
  129.         System.out.println(person);  
  130.           
  131.         }  
  132.       
  133.       
  134.     @Test  
  135.     public void testCrudRepository()  
  136.     {  
  137.         List<Person> persons=new ArrayList<Person>();  
  138.         for (int i = 1; i < 10000; i++) {  
  139.             Person person=new Person();  
  140.             person.setBirth(new Date());  
  141.             person.setEmail(”@2”+i+“ com”);  
  142.             persons.add(person);  
  143.         }  
  144.           
  145.         long startTime=System.currentTimeMillis();  
  146.         personService.savePersons(persons);  
  147.         long endTime=System.currentTimeMillis();  
  148.         System.out.println((endTime-startTime)/1000);  
  149.     }  
  150.       
  151.       
  152.     @Test  
  153.     public void testPagingAndSortingRespository(){  
  154.         //pageNumber是从0开始的  
  155.         int pageNumber=4;  
  156.         int pageSize=5;  
  157.         //PageAble 接口通常用的是PageRequest实现类,其中封装了需要分页的信息  
  158.         //排序相关的,sor封装了排序的信息  
  159.         Order order1=new Order(Direction.DESC, “id”);  
  160.           
  161.         Order order2=new Order(Direction.DESC, “email”);  
  162.         Sort sort=new Sort(order1,order2);  
  163.           
  164.           
  165.         Pageable pageable=new PageRequest(pageNumber, pageSize,sort);  
  166.         Page<Person> page=personRepotory.findAll(pageable);  
  167.         System.out.println(”总记录数”+page.getTotalElements());  
  168.         System.out.println(”当前第几页”+page.getNumber());  
  169.         System.out.println(”总页数”+page.getTotalPages());  
  170.         System.out.println(”当前页面的List”+page.getContent());  
  171.         System.out.println(”当前页面的记录数”+page.getNumberOfElements());  
  172.     }  
  173.       
  174.       
  175.     @Test  
  176.     public void testJpaRepository(){  
  177.         Person person=new Person();  
  178.         person.setBirth(new Date());  
  179.         person.setEmail(”aa”);  
  180.         person.setLastName(”xyz”);  
  181.         personRepotory.saveAndFlush(person);  
  182.           
  183.           
  184.     }  
  185.       
  186.       
  187.     /* 
  188.      * 实现带查询条件的分页效果 id>5 
  189.      * 调用JpaSpecificationExecutor的page<T> findAll(Speciation<T>,PageAble pageable) 
  190.      * specification:封装了JPA Criteria 查询的条件 
  191.      * pageable:封装了请求分页的消息,例如pageno,pagesize,sort 
  192.      */  
  193.     @Test  
  194.     public void testJpaSpeciationExecutor(){  
  195.         int pageNo=0;  
  196.         int pageSize=5;  
  197.         PageRequest pageRequest=new PageRequest(pageNo, pageSize);  
  198.         //通常使用Specification 的匿名内部类,  
  199.         Specification<Person> specification=new Specification<Person>() {  
  200.   
  201.         /* 
  202.          * @param root:代表的查询的实体类 
  203.          * @param query:可以从中得到Root对象,即告知JPA Criteria查询要查询哪一个实体类, 
  204.          * 还可以来添加查询条件,还可以结合EntityManager对象得到最终查询的TypedQuery 对象 
  205.          * @Param cb:criteriabuildre对象,用于创建Criteria相关的对象工程,当然可以从中获取到predicate类型 
  206.          * @return:代表一个查询条件 
  207.          */  
  208.             @Override  
  209.             public Predicate toPredicate(Root<Person> root,  
  210.                     CriteriaQuery<?> query, CriteriaBuilder cb) {  
  211. //              Path path=root.get(“id”);  
  212. //              Predicate predicate=cb.gt(path, 5);  
  213.                   
  214.                 Predicate p1=cb.like(root.get(”id”).as(String.class), “%”+“1”+“%”);  
  215.                 Predicate p2=cb.equal(root.get(”lastName”).as(String.class), “sd”);  
  216.                 Predicate p3=cb.like(root.get(”email”).as(String.class), “%s%”);  
  217. //              构建组合的Predicate示例:  
  218.                 Predicate p = cb.and(p3,cb.or(p1,p2));  
  219.                   
  220.                 return p;  
  221.             }  
  222.               
  223.         };  
  224.           
  225.         Page<Person> page=personRepotory.findAll(specification,pageRequest);  
  226.       
  227.         System.out.println(”总记录数”+page.getTotalElements());  
  228.         System.out.println(”当前第几页”+page.getNumber());  
  229.         System.out.println(”总页数”+page.getTotalPages());  
  230.         System.out.println(”当前页面的List”+page.getContent());  
  231.         System.out.println(”当前页面的记录数”+page.getNumberOfElements());  
  232.     }  
  233.       
  234.       
  235.     @Test  
  236.     public void testCustomRepositoryMethod(){  
  237.         personRepotory.test();  
  238.     }  
  239.       
  240.       
  241. }  
  242. </span>  
<span style="font-family:Comic Sans MS;font-size:18px;">/**     
 * @FileName: SpringDataTest.java   
 * @Package:com.tgb.test   
 * @Description: TODO  
 * @author: LUCKY    
 * @date:2015年11月8日 下午5:35:37   
 * @version V1.0     
 */
package com.tgb.test;

import static org.junit.Assert.*;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.sql.DataSource;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.jpa.domain.Specification;

import com.tgb.springdata.Entity.Person;
import com.tgb.springdata.Entity.PersonRepotory;
import com.tgb.springdata.Service.PersonService;

/**  
 * @ClassName: SpringDataTest   
 * @Description: TODO  
 * @author: LUCKY  
 * @date:2015年11月8日 下午5:35:37     
 */
public class SpringDataTest {

    private PersonRepotory personRepotory=null;
    private PersonService personService;
    private ApplicationContext ctx=null;
    {
        ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
        personRepotory=ctx.getBean(PersonRepotory.class);
        personService=ctx.getBean(PersonService.class);
    }


    @Test
    public void testKeyWorlds(){
        List<Person> persons=personRepotory.getByLastNameStartingWithAndIdLessThan("BB", 10);
        System.out.println(persons);

        List<Person> persons1=personRepotory.getByLastNameEndingWithAndIdLessThan("BB", 10);
        System.out.println(persons);
        System.out.println(persons1);

        persons=personRepotory.getByEmailInOrBirthLessThan(Arrays.asList("aa@qq.com","bb@qq.com"),new Date());
        System.out.println(persons.size());
    }





    @Test
    public void testDataSource() throws SQLException{
        DataSource dataSource=ctx.getBean(DataSource.class);
        System.out.println(dataSource.getConnection());
    }

    @Test
    public void TestJpa(){

    }

    @Test
    public void testKeyWorlds2(){
        List<Person> persons=personRepotory.getByAddressIdGreaterThan(1);
        System.out.println(persons);
    }

    @Test
    public void testQueryAnnotation(){
        Person person=personRepotory.getMaxIdPerson();
//      System.out.println(person);

        List<Person> persons=personRepotory.testQueryAnnotationParams1("AA", "bb");
        System.out.println(persons);

        List<Person> persons1=personRepotory.testQueryAnnotationParams2("bb", "AA");
        System.out.println(persons1);
    }


    @Test
    public void testModifing(){
//      personRepotory.updatePersonEmail(1, "@@qq.com");
        personService.updatePersonEmail("aa@aa", 1);
    }

    @Test
    public void testQueryLikeAnnotationParam(){
        List<Person> persons=personRepotory.testQueryAnnotationLikeParam("%AA%", "%b%");
        System.out.println(persons);

        long count=personRepotory.getTotalCount();
        System.out.println(count);
    }




    @Test
    public void HelloWorldSpringData(){
        PersonRepotory personRepotory=ctx.getBean(PersonRepotory.class);
        System.out.println(personRepotory.getClass().getName());
        Person person=personRepotory.getByLastName("AA");
        System.out.println(person);

        }


    @Test
    public void testCrudRepository()
    {
        List<Person> persons=new ArrayList<Person>();
        for (int i = 1; i < 10000; i++) {
            Person person=new Person();
            person.setBirth(new Date());
            person.setEmail("@2"+i+" com");
            persons.add(person);
        }

        long startTime=System.currentTimeMillis();
        personService.savePersons(persons);
        long endTime=System.currentTimeMillis();
        System.out.println((endTime-startTime)/1000);
    }


    @Test
    public void testPagingAndSortingRespository(){
        //pageNumber是从0开始的
        int pageNumber=4;
        int pageSize=5;
        //PageAble 接口通常用的是PageRequest实现类,其中封装了需要分页的信息
        //排序相关的,sor封装了排序的信息
        Order order1=new Order(Direction.DESC, "id");

        Order order2=new Order(Direction.DESC, "email");
        Sort sort=new Sort(order1,order2);


        Pageable pageable=new PageRequest(pageNumber, pageSize,sort);
        Page<Person> page=personRepotory.findAll(pageable);
        System.out.println("总记录数"+page.getTotalElements());
        System.out.println("当前第几页"+page.getNumber());
        System.out.println("总页数"+page.getTotalPages());
        System.out.println("当前页面的List"+page.getContent());
        System.out.println("当前页面的记录数"+page.getNumberOfElements());
    }


    @Test
    public void testJpaRepository(){
        Person person=new Person();
        person.setBirth(new Date());
        person.setEmail("aa");
        person.setLastName("xyz");
        personRepotory.saveAndFlush(person);


    }


    /*
     * 实现带查询条件的分页效果 id>5
     * 调用JpaSpecificationExecutor的page<T> findAll(Speciation<T>,PageAble pageable)
     * specification:封装了JPA Criteria 查询的条件
     * pageable:封装了请求分页的消息,例如pageno,pagesize,sort
     */
    @Test
    public void testJpaSpeciationExecutor(){
        int pageNo=0;
        int pageSize=5;
        PageRequest pageRequest=new PageRequest(pageNo, pageSize);
        //通常使用Specification 的匿名内部类,
        Specification<Person> specification=new Specification<Person>() {

        /*
         * @param root:代表的查询的实体类
         * @param query:可以从中得到Root对象,即告知JPA Criteria查询要查询哪一个实体类,
         * 还可以来添加查询条件,还可以结合EntityManager对象得到最终查询的TypedQuery 对象
         * @Param cb:criteriabuildre对象,用于创建Criteria相关的对象工程,当然可以从中获取到predicate类型
         * @return:代表一个查询条件
         */
            @Override
            public Predicate toPredicate(Root<Person> root,
                    CriteriaQuery<?> query, CriteriaBuilder cb) {
//              Path path=root.get("id");
//              Predicate predicate=cb.gt(path, 5);

                Predicate p1=cb.like(root.get("id").as(String.class), "%"+"1"+"%");
                Predicate p2=cb.equal(root.get("lastName").as(String.class), "sd");
                Predicate p3=cb.like(root.get("email").as(String.class), "%s%");
//              构建组合的Predicate示例:
                Predicate p = cb.and(p3,cb.or(p1,p2));

                return p;
            }

        };

        Page<Person> page=personRepotory.findAll(specification,pageRequest);

        System.out.println("总记录数"+page.getTotalElements());
        System.out.println("当前第几页"+page.getNumber());
        System.out.println("总页数"+page.getTotalPages());
        System.out.println("当前页面的List"+page.getContent());
        System.out.println("当前页面的记录数"+page.getNumberOfElements());
    }


    @Test
    public void testCustomRepositoryMethod(){
        personRepotory.test();
    }


}
</span>

 或许会感到奇怪,为何Dao只单纯的是一个接口,没有实现类呢?其实这就是Spring Data JPA为我们封装了,只要按照Spring Data JPA的规范来定义,就会自动为我们生成一个默认的代理实现类。


 3.Repository 接口

•基础的 Repository提供了最基本的数据访问功能,其几个子接口则扩展了一些功能。它们的继承关系如下: 
–Repository:仅仅是一个标识,表明任何继承它的均为仓库接口类
–CrudRepository:继承Repository,实现了一组CRUD相关的方法 
–PagingAndSortingRepository:继承CrudRepository,实现了一组分页排序相关的方法 
–JpaRepository:继承PagingAndSortingRepository,实现一组JPA规范相关的方法 
–自定义的 XxxxRepository需要继承 JpaRepository,这样的XxxxRepository接口就具备了通用的数据访问控制层的能力。
–JpaSpecificationExecutor:不属于Repository体系,实现一组JPACriteria查询相关的方法 


 4.@Query 注解
 
•这种查询可以声明在 Repository方法中,摆脱像命名查询那样的约束,将查询直接在相应的接口方法中声明,结构更为清晰,这是Springdata 的特有实现。
//查询id值最大的那个person
//使用@Query注解可以自定义JPQL语句,语句可以实现更灵活的查询
@Query(“SELECT p FROM Person p WHERE p.id=(SELECT max(p2.id) FROM Person p2)”)

Person getMaxIdPerson();


 5.@Modifying 注解

 @Query 与 @Modifying这两个annotation一起声明,可定义个性化更新操作,例如只涉及某些字段更新时最为常用,示例如下

//可以通过自定义的JPQL 完成update和delete操作,注意:JPQL不支持Insert操作
//在@Query注解中编写JPQL语句,但必须使用@Modify进行修饰,以通知SpringData,这是一个Update或者Delete
//Update或者delete操作,需要使用事务,此时需要定义Service层,在service层的方法上添加事务操作
//默认情况下,SpringData的每个方法上有事务,但都是一个只读事务,他们不能完成修改操作
@Modifying
@Query(“update Person p set p.email=:email where id=:id”)
void updatePersonEmail(@Param(“id”)Integer id,@Param(“email”)String email);



 更多有关的内容,请参考http://blog.csdn.net/z69183787/article/details/30265243http://www.cnblogs.com/WangJinYang/p/4257383.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值