• springboot11 JPA


    一、JPA

    1. JPA 介绍

    JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。Sun引入新的JPA ORM规范出于两个原因:其一,简化现有Java EE和Java SE应用开发工作;其二,Sun希望整合ORM技术,实现天下归一 。 其实在5.0出现发布之前,市面上有诸如、Hibernate 、OpenJPA 、TopLink 等一些列 ORM框架,并且hibernate已经很受大众喜爱了,后来hibernate在3.2版本正式接入JPA 规范,表示自己即属于JPA的框架的具体实现。 一句话概括: JPA 是一种规范、 Hibernate 是这种规范的最好实现。

    Dao最受欢迎的两个框架: MyBatis ----不是JPA体系 ----- 需要写sql语句 | Hibernate --- JPA 体系 -----可以不用写sql语句

    2. ORM介绍

    Object Relational Mapping : 对象关系映射 。 ORM的思想其实就是让 表 和 JavaBean 形成一种映射关系 , 并且让表里面的字段 和JavaBean 里面的成员形成映射关系。

    01

    3. JPA 入门

    此处就以一个简单的保存案例来实现JPA 入门吧。

    • 添加JPA 依赖
    // 在maven 搜索关键字  persistence 即可  hibernate的核心依赖,会包含它对JPA规范的升级,所以这个依赖可以不加 
    //compile group: 'javax.persistence', name: 'persistence-api', version: '1.0'
    
    //不要忘记了添加mysql数据库依赖
    compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.17'
    
    //下面要添加hibernate的依赖,因为JPA 只是一套规范而已,不是具体的实现,JPA的实现有很多,
    //这里采用hibernate作为我们的实现,所以需要添加hibernate的依赖库
    //compile group: 'org.hibernate', name: 'hibernate-core', version: '4.3.9.Final'
    
    //hibernate实体管理者,对接JPA规范的管理员  这是hibernate为了迎合JPA的规范做出来的。
    compile group: 'org.hibernate', name: 'hibernate-entitymanager', version: '4.3.9.Final'
    
    • 定义实体类
    @Entity(name="t_user")
    public class User {
        private static final String TAG = "User";
    
        private int id;
        private String name;
        private int age ;
    
    
        @Id
        @GeneratedValue
        public int getId() {
            return id;
        }
        
        //剩下的get 和 set方法
        ...
    }
        
    
    • 定义配置文件

    必须要说明一点,配置文件的名字需要固定,必须叫:persistence.xml , 而且也必须放在 META-INF下面,不能直接放在resource下面。需要在resource下面,新建META-INF 文件夹,然后在放置 xml文件

    <?xml version="1.0" encoding="UTF-8"?>
    <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
        
    
    
        <!--持久化单元,数据库 & 实体类 & 具体实现方式配置单元-->
        <persistence-unit name="user">
    
            <!--声明提供者,也就是说具体实现,因为JPA 只是规范,这里使用hibernate作为具体实现-->
            <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    
            <!--表示实体类有哪些-->
            <class>com.itheima.bean.User</class>
    
            <!--数据库连接参数-->
            <properties>
                <!--使用jpa的配置-->
                <!--<property name="javax.persistence.jdbc.url" 	
    								value="jdbc:mysql://localhost:3306/test"/>
                <property name="javax.persistence.jdbc.user" value="root"/>
                <property name="javax.persistence.jdbc.password" value="root"/>
                <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/> -->
    
                <!--也可以使用hibernate的配置为了以后无缝对接,还是建议使用上面的规范化的JPA 配置-->
                <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/test"/>
                <property name="hibernate.connection.username" value="root"/>
                <property name="hibernate.connection.password" value="root"/>
                <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
    
                <!--表示自动建表-->
                <property name="hibernate.hbm2ddl.auto" value="update"/>
            </properties>
    
        </persistence-unit>
    </persistence>
    
    • 测试代码
    @Test
        public  void testJPA(){
    
            //创建实体管理工厂 , 参数的user 来自于配置文件的配置单元名字。
            EntityManagerFactory factory = Persistence.createEntityManagerFactory("user");
    
            //创建实体管理员
            EntityManager manager = factory.createEntityManager();
    
            //获取事务对象
            EntityTransaction transaction = manager.getTransaction();
    
            //开启事务
            transaction.begin();
    
            //构建实体对象
            User user = new User();
            user.setName("zhangsan");
            user.setAge(18);
    
    
            //持久化,也就是保存到数据库
            manager.persist(user);
            
            //提交事务
            transaction.commit();
            
             //关闭管理员
        	manager.close();
    
            //关闭工厂,一般不关闭,后面也不用关心这个了。
            factory.close();
        }
    

    4. 入门详解

    a. 注解解释

    @Entity : 表示该类是一个实体,也就是和表形成映射,可以添加属性来指定对应的表

    ​ 如:@Entity(name="t_user")

    @Table : 指定表名,可以不写,可以在entity注解上直接表示标识表名。

    ​ 如 : @Table(name="t_user")

    @Id : 用于表示主键,指定哪一个属性和主键对应 可以在变量上声明,也可以在get方法上声明,建议统一。

    @GeneratedValue : 用于表示主键生成策略 主键生成策略,提供的有4种

    • 主键策略解释
    1、AUTO 自动选择一个最适合底层数据库的主键生成策略。如MySQL会自动对应auto increment。这个是默认选项,即如果只写@GeneratedValue,等价于@GeneratedValue(strategy=GenerationType.AUTO)。注意在mysql5 + hibernate 5的版本测试下,会产生另外一张表,用于记录主键值。 可以在核心配资文件中添加此属性来达到native效果
    	<property name="hibernate.id.new_generator_mappings">false</property>
    
    2、IDENTITY 表自增长字段,Oracle不支持这种方式。
    
    3、SEQUENCE 通过序列产生主键,MySQL不支持这种方式。
    
    4、TABLE 通过表产生主键,框架借由表模拟序列产生主键,使用该策略可以使应用更易于数据库移植。不同的JPA实现商生成的表名是不同的,如 OpenJPA生成openjpa_sequence_table表,Hibernate生成一个hibernate_sequences表,而TopLink则生成sequence表。这些表都具有一个序列名和对应值两个字段,如SEQ_NAME和SEQ_COUNT。
    
    • 关于UUID策略

    通常我们建表,主键都是int类型,但是其实在开发的时候,有些表也会建成String类型,也就是varchar类型 , 并且有时候我们要主键唯一,这时候需要使用到uuid策略了。JPA并没有提供UUID 策略, 好在hibernate提供了这种策略的支持。

    //声明uuid这种策略类型。然后给定一个别名,叫做jpa-uuid  这个注解是hibernate提供的注解, jpa的注解没有
    @GenericGenerator(name="jpa-uuid" ,strategy="uuid") 
    
    //表示对应 t_student 这个表
    @Entity(name="t_student")
    public class Student {
    
    	private String id;
    	private String name;
    	private int age;
    	private String phone;
    	private String address;
    	
    	//指定使用你的主键策略是 jpa-uuid这个名称对一个你的类型,其实就是指定了主键是uuid 。 
        //由hibernate来维护主键。
        @Id 
    	@GeneratedValue(generator="jpa-uuid")
    	public String getId() {
    		return id;
    	}
      	... 
    }
    
    

    b. xml配置解释

    • xml必须放在META-INF下面,名字也必须固定是persistence.xml
    • xml其实就是用于表示怎么连接数据库,具体干活的是JPA实现是什么, 以及有哪些映射实体类。

    img02

    • 具体的属性名称,可以参考pdf文档。 第八章节

    img03

    • 关于hibernate的配置,请参考hibernate的pdf文档

    img04

    c. 测试代码解释

    代码没有什么好解释的了,必须要有实体管理员工厂,然后获取到管理员,后续就可以操作了。 可以稍稍解释下即可

    5. CRUD

    JPA 有一个要求就是写入操作,需要使用事务,否则数据不会到达数据库。

    1. 增加

     @Test
    public  void testJPA(){
    
        //创建实体管理工厂 , 参数的user 来自于配置文件的配置单元名字。
        EntityManagerFactory factory = Persistence.createEntityManagerFactory("user");
    
        //创建实体管理员
        EntityManager manager = factory.createEntityManager();
    
        //获取事务对象
        EntityTransaction transaction = manager.getTransaction();
    
        //开启事务
       transaction.begin();
    
        //构建实体对象
        User user = new User();
        user.setName("zhangsan");
        user.setAge(28);
    
    
        //持久化,也就是保存到数据库
        manager.persist(user);
    
        //提交事务
        transaction.commit();
        
         //关闭管理员
        manager.close();
    
        //关闭工厂,一般不关闭,后面也不用关心这个了。
        factory.close();
    }
    

    2. 删除

    需要删除某条记录,需要先把它查询出来,然后才能删除。

    @Test
    public  void testDelete(){
    
        //创建实体管理工厂 , 参数的user 来自于配置文件的配置单元名字。
        EntityManagerFactory factory = Persistence.createEntityManagerFactory("user");
    
        //创建实体管理员
        EntityManager manager = factory.createEntityManager();
    
        //获取事务对象
        EntityTransaction transaction = manager.getTransaction();
    
        //开启事务
        transaction.begin();
    
        //查询主键为1的用户
        User u = manager.find(User.class,1);
    
        //删除用户
        manager.remove(u);
    
        //提交事务
        transaction.commit();
        
        //关闭管理员
        manager.close();
    
        //关闭工厂,一般不关闭,后面也不用关心这个了。
        factory.close();
    }
    
    

    3. 修改

    修改也一样,需要先查询,然后修改后,在持久化。

     @Test
        public  void testUpdate(){
    
            //创建实体管理工厂 , 参数的user 来自于配置文件的配置单元名字。
            EntityManagerFactory factory = Persistence.createEntityManagerFactory("user");
    
            //创建实体管理员
            EntityManager manager = factory.createEntityManager();
    
            //获取事务对象
           EntityTransaction transaction = manager.getTransaction();
    
            //开启事务
            transaction.begin();
    
    
            //查询主键为1的用户
            User u = manager.find(User.class,2);
            u.setAge(102);
    
            //这句可以不写,因为查询出来的user对象已经是持久态,直接操作它也可以修改数据库
           // manager.persist(u);
           /* //删除用户
            manager.remove(u);*/
    
            //提交事务
           transaction.commit();
        
            //关闭管理员
        	manager.close();
    
            //关闭工厂,一般不关闭,后面也不用关心这个了。
            factory.close();
    
        }
    

    4. 查询

     @Test
    public  void testQuery(){
    
        //创建实体管理工厂 , 参数的user 来自于配置文件的配置单元名字。
        EntityManagerFactory factory = Persistence.createEntityManagerFactory("user");
    
        //创建实体管理员
        EntityManager manager = factory.createEntityManager();
    
        //不支持写* 
        Query query = manager.createQuery("select t from User t");
    
        List<User> list = query.getResultList();
    
        System.out.println("list=" + list);
        
        //关闭管理员
        manager.close();
        
        //关闭工厂,一般不关闭,后面也不用关心这个了。
        factory.close();
    }
    

    6. 对象时态

    这个状态主要是针对我们操作的持久化类对象。 有四种状态

    • 瞬时态

    对象仅仅是创建出来(new对象),没有和EntityManager 产生关系

    • 持久态

    和EntityManager建立关系,被持久化,保存到数据库或者刚从数据库查询出来。

    • 脱管态

    已经持久化过了,现在要脱离管理。 提交事务,或者清除EntityManager都会走向这个状态。

    • 删除态

    该状态只有在JPA 范畴里面才有,单独拿hibernate来说,没有这个状态。只有调用了EntityManager

    的remove方法,才会走到这个状态。

    img05

    7. 多表关系确立

    最好使用例子引出关系确立的重要性。

    a. 多对一

    此处以分类 & 商品的关系来解释

    • 分类 Category
    @Entity(name="category")
    public class Category {
    
        private int id;
        private String name;
    
    
        @Id
        @GeneratedValue
        public int getId() {
            return id;
        }
        
        //剩下的get &  set方法
        ...
    }
    
    • 商品 Product

    商品在这个关系里面扮演的是外键的关系,是多方的角色,也就是一种商品分类,可以有很多件商品。所以从商品的位置出发,它和分类的关系是多对一的关系。

    @Entity(name="product")
    public class Product {
    
        private int id ;
        private String name;
        private double price;
    
        //表示该商品属于哪一种分类。
        private Category category;
    
    
        @Id
        @GeneratedValue
        public int getId() {
            return id;
        }
    
    	// @ManyToOne表示是多对一关系 optional =false 表示该外键不能为空
       @ManyToOne(optional = false)
        
        //@JoinColumn name=cid 通俗的意思是: 拿什么列来作为外键,
        //这里指定cid , 表示生成的是外键名称叫做cid
       @JoinColumn(name="cid")
       public Category getCategory() {
            return category;
        }
        
        ...
    }
    

    b. 一对多

    一对多,比前面的多对一稍微麻烦一点,而且一对多必须双方都配上注解,否则生成的关系会比较乱。

    • 分类 Category

    区别只是一方 category 里面多了一个注解 @OneToMany

    @Entity(name="category")
    public class Category {
    
        private int id;
        private String name;
    
    
        private Set<Product> productSet = new HashSet<Product>();
    
        @Id
        @GeneratedValue
        public int getId() {
            return id;
        }
    
    
        //mappedBy 表示和谁形成映射关系,也表示谁来维护这层关系。
        @OneToMany(mappedBy = "category")
        public Set<Product> getProductSet() {
            return productSet;
        }
    
        //剩下的get & set 方法
        ...
    }
    
    • 商品 Product
    @Entity(name="product")
    public class Product {
    
        private int id ;
        private String name;
        private double price;
    
    
        //表示该商品属于哪一种分类。
        private Category category;
    
    
        @Id
        @GeneratedValue
        public int getId() {
            return id;
        }
    
    
       @ManyToOne(optional = false)
       @JoinColumn(name="cid")
       public Category getCategory() {
            return category;
        }
    
        //剩下的get & set方法
        ...
    }
    

    8 . 查询

    1. 对象导航查询

    所谓对象导航查询的意思是: 如果A表和B表存在主外键关系(一对多 | 多对一 ),那么在查询A表的时候, 也会顺便查询与该条记录关联的B表记录信息。如分类和商品的关系, 如果查询手机分类,那么会顺便把商品表中属于手机分类的商品给查询出来。

    
    

    二、SpringData JPA

    1. 介绍

    在JavaEE 5.0发布的时候,sun公司就提出了jpa的规范,希望整合ORM技术,实现天下归一 。 虽然我们学过的orm技术只有hibernate、但是其实orm技术还有其他的一些方案,比如Apache的 openJPA。 Spring 作为业务逻辑层框架,起到承上启下的作用。所以它对JPA的这些技术实现做了一套封装。大家只要按照规范来配置即可,甚至你们的dao层实现都不用实现了,它在内部给你实现,如果我们想换到其他的jpa实现方案,那么只需要修改配置即可。 这就是我们要说的Spring Data JPA。

    JPA

    Hibernate | Open Jap | Toplink ....

    Spring Data JPA ---> 对Dao层的代码再一次升级封装 。 统一的JPA的实现,在封装。

    2. 入门

    1. 搭建环境 (建表)

    • 添加依赖
    //mysql驱动
    compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.17'
    
    //springboot 依赖
    compile("org.springframework.boot:spring-boot-starter-web:1.5.10.RELEASE")
    
    //spring data jpa 注意: 不要引入错了,要找的组是springboot的依赖。如下面这条注释的是错误的。
    //因为我们使用了SpringBoot,所以采用的库,也要是springboot组下的。
    //compile group: 'org.springframework.data', name: 'spring-data-jpa', version: '1.11.3.RELEASE'
    
    
    compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '1.5.10.RELEASE'
    
    • 添加配置文件

    同样还是那个 application.properties , 位于 resources 下面

    #连接数据库
    spring.datasource.url=jdbc:mysql://localhost:3306/test
    spring.datasource.username=root
    spring.datasource.password=root
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    
    
    #hibernate配置
    # 自动建表 update:表示有表则直接使用,无表就新建
    spring.jpa.hibernate.ddl-auto=update
    
    # 表示在操作时,输出sql语句
    spring.jpa.show-sql=true
    
    • 实体类
    //name :用于表示构建出来的表名
    @Entity(name="t_user")
    public class User {
        private static final String TAG = "User";
        private int id;
        private String name;
        private int age ;
    
    
      
        @Id
        @GeneratedValue
        public int getId() {
            return id;
        }
        
        //剩余的get & set方法代码
        ...
    }    
    

    2. 添加数据

    上面仅仅是完成了表的创建工作,实际上还并没有看出来SpringData JPA 有什么厉害之处,现在就要往表里面添加数据了。

    • controller
    @RestController
    public class UserController {
    
        //这里要注入业务逻辑层引用
        @Autowired
        private UserService userService;
    
    
        @RequestMapping("/save")
        public String save(){
    
            User user = new User();
            user.setName("奥巴马");
            user.setAge(58);
    
            //调用业务逻辑层
            userService.save(user);
            return "save success~!";
        }
    }
    
    • service
    public interface UserService {
    
        void save(User user);
    }
    
    ---------------------------------------------------------------
    
    @Service
    @Transactional
    public class UserServiceImpl implements UserService {
    
        //这里要注入UserDao引用
        @Autowired
        private UserDao userDao;
    
        @Override
        public void save(User user) {
            userDao.save(user);
        }
    }
        
    
    • dao

    注意: dao层只有一个接口而已,方法没有,其实是父类CrudRepository 已经定义了一些常用的方法,我们可以直接拿过来用即可。真正我们在业务逻辑层拿到的是 SimpleJPARepository 这个类的实例。它其实就是实现了CrudRepository接口方法。

    public interface UserDao extends CrudRepository<User, Integer> {
        
    }
    

    三、 通用接口介绍

    经过上面的入门例子,大家也看到了,spring data对于我们编程确实方便了许多。我们无需关心dao层的实现,只需要简单的照着规则去写代码即可,spring data jpa 最重要的就是我们的dao层继承的接口。接下来给大家着重说明它的几个接口。

    1. Repository

    这个接口是所有接口的父接口,也就是它就是老大了。所有我们后面用的接口都是从这位兄弟身上扩展来的。 下图是Repository 这个接口的继承体系,图中的UserDao 和 MyRepository 是我自己写的,大家不用理会。 不过要声明的是: 这个Repository 是一个空接口!!!,里面没有任何方法.

    01

    package org.springframework.data.repository;
    
    import java.io.Serializable;
    /**
     * Central repository marker interface. Captures the domain type to manage as well as the domain type's id type. General
     * purpose is to hold type information as well as being able to discover interfaces that extend this one during
     * classpath scanning for easy Spring bean creation.
     * <p>
     * Domain repositories extending this interface can selectively expose CRUD methods by simply declaring methods of the
     * same signature as those declared in {@link CrudRepository}.
     * 
     * @see CrudRepository
     * @param <T> the domain type the repository manages
     * @param <ID> the type of the id of the entity the repository manages
     * @author Oliver Gierke
     */
    public interface Repository<T, ID extends Serializable> {
    
    }
    

    这个repository虽然是个空接口,我们自己来继承它,虽然没有任何要实现的方法,但是我们可以自己写,自己声明方法,这也是允许D~~ ,话不多说,走起~~~

    • 自定义接口 MyRepository
    public interface MyRepository extends Repository<User, Integer> {
    
    	/**
    	 * 根据用户id查询用户
    	 * @param uid
    	 * @return
    	 */
    	User findByUid(int uid);
    
    }
    
    • service层代码
    public interface UserService {
    
    	User findByUid(int uid);
    }
    
    ------------------------------
    @Service
    @Transactional  //现在仍然是查询这个注解可以不写,为了免得大家记太多,我就索性都打开了。
    public class UserServiceImpl implements UserService {	
    	@Autowired
    	private MyRepository repository;
    
    	@Override
    	public User findByUid(int uid) {
    		return repository.findByUid(uid);
    	}
    
    }  
      
    
    • 测试代码
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:applicationContext.xml")
    public class TestJpa {
    	
    	@Autowired
    	private UserService userService;
      
    	@Test
    	public void testFindByUid(){
    		System.out.println(userService.findByUid(1));
    		
    	}
    }
    
    • 结果:

    03

    • 疑问:

    写到这,有的同学绝对会有疑问, 这都可以,那这也行的话,我写一个叫做 fUid() 或者叫做 zhaoUserByUid() 这样的方法名,行不行呢? 答案是: NO!

    因为我们声明的是接口,具体的实现类还是由人家的spring做出来的。spring胃口比较挑剔,而且为了满足大众化的口味,就做出了一些命名上的要求,大家要慢慢习惯这种要求,这也正是它的另一个框架Spring Boot的口号习惯优于配置 。 下图摘自 Spring Data JPA 文档对方法关键字的描述。

    如:我们想按照用户的name 查询, 那么可以写成 findByName 以此类推

    04

    05

    如果觉得这些关键字记不住,那么spring可以允许我们程序员自己定义自己的方法名。

    2. 自定义方法名

    这个小节主要讲述的是,我们可以自己定义自己的方法名,你爱叫啥叫啥,随意。

    • Dao接口
    public interface MyRepository extends Repository<User, Integer> {
    
    
    	@Query("from User  where uid = ?1") //?1 表示取第一个参数uid 来替代这个?。
    	User selectUser(int uid);
    
    }
    
    
    • Service
    public interface UserService {
    
    	User selectUser(int uid);
    }
    
    
    • 测试代码
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:applicationContext.xml")
    public class TestJpa {
    	
    	@Autowired
    	private UserService userService;
    
    	@Test
    	public void testSelectUser(){
    		System.out.println(userService.selectUser(1));
    		
    	}
    }
    
    

    虽然我们可以自己定义方法名,但是这种做法稍微有点麻烦,所以建议少用这种写法。 只有在以后执行多表查询的时候,我们才需要这么做。

    3. CrudRepository

    这个接口是扩展了repository, 在这个接口里面默认给大家声明好了一些增删改查的方法,此处给大家演练一个查询所有用户的操作

    • Dao
    public interface UserDao extends CrudRepository<User, Integer> {
    	//查询所有的用户
    }
    
    
    • Service
    @Service
    //@Transactional
    public class UserServiceImpl implements UserService {
    	
    	@Autowired
    	private UserDao userDao;
    
    	@Override
    	public List<User> findAll() {
    		return (List<User>) userDao.findAll();
    	}
    
    }
    
    
    • 测试
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:applicationContext.xml")
    public class TestJpa {
    	
    	@Autowired
    	private UserService userService;
    	
    	@Test
    	public void testFindAll(){
    		List<User> list= userService.findAll();
    		System.out.println("list="+list);
    	}
    }
    
    

    4.PagingAndSortingRepository

    这个接口是是CrudRepository的扩展接口,除了兼备增删改查之外,它还扩展了分页查询&排序的效果。

    以下是这个接口的代码声明

    @NoRepositoryBean
    public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {
    
    	/**
    	 * Returns all entities sorted by the given options.
    	 * 
    	 * @param sort
    	 * @return all entities sorted by the given options
    	 */
    	Iterable<T> findAll(Sort sort);
    
    	/**
    	 * Returns a {@link Page} of entities meeting the paging restriction provided in the {@code Pageable} object.
    	 * 
    	 * @param pageable
    	 * @return a page of entities
    	 */
    	Page<T> findAll(Pageable pageable);
    }
    
    • Dao
    public interface UserDao extends PagingAndSortingRepository<User, Integer> {
    	//查询所有的用户
    }
    
    
    • Service
    public interface UserService {
    	
    	
    	/**
    	 * 返回值是page 这个类型是springdatajpa定义好的。其实就和
    	 * 我们自己平常写的PageBean 一样。
    	 * @param pageable
    	 * @return
    	 */
    	Page<User> findByPage(Pageable pageable);
    }
    
    ---------------------------------------------------------
      
      @Service
    //@Transactional
    public class UserServiceImpl implements UserService {
    	
    	@Autowired
    	private UserDao userDao;
    
    	@Override
    	public Page<User> findByPage(Pageable pageable) {
    		return userDao.findAll(pageable);
    	}
    
    }
    
    • 测试
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:applicationContext.xml")
    public class TestJpa {
    	
    	@Autowired
    	private UserService userService;
    	
    	@Test
    	public void testFindByPage(){
    		//这里ctrl + T 看实现类,然后找PageRequest ,别说你不会哈~~
    		// page : page表示请求的页码数, 从0开始,0就代表第一页大家。
    		//size : 表示每页拿多少条记录
    		Pageable pageable = new PageRequest(1, 2);
    		Page<User> page = userService.findByPage(pageable);
    		
          //当前是第几页 这个页码从0开始的,大家可以加上1表示从1开始。
    		System.out.println(page.getNumber()); 
    		System.out.println(page.getTotalPages()); //总页数
    		System.out.println(page.getSize()); //每页个数
    		System.out.println(page.getTotalElements()); //总记录数
    		System.out.println(page.getContent()); //总页数
    	}
    }
    

    重点:

    多表关系建立
    	@ManyToOne  @OneToMany
    
    SpringDataJPA 完成CRUD
    	CrudRepository
    
    

  • 相关阅读:
    ios app相互调用
    Nginx连接频率限制
    nginx 基于域名的虚拟主机
    nginx基于多端口的虚拟主机
    Nginx基于多ip的虚拟主机
    多文件上传
    thinkphp5模型关联
    原生查询和查询构造器
    thinkphp5请求和响应
    thinkphp验证器
  • 原文地址:https://www.cnblogs.com/xiaocongcong888/p/9436309.html
Copyright © 2020-2023  润新知