Spring Data学习

什么是Spring Data

       主旨:provide a familiar and consistent,Spring-based programming model for data access

       历史:2010,作者Rod Johnso,Spring Source项目

       网址:http://projects.spring.io/spring-data/#quick-start

 

Spring Data子项目

       Spring Data JPA

       Spring Data MongoDB

       Spring Data Redis

       Spring Data Solr

       ...

传统方式访问数据库

创建项目,导入依赖

<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.38</version>
</dependency>

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.10</version>
</dependency>

创建数据库和表

CREATE DATABASE spring_data;
USE spring_data;
CREATE TABLE student(
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(20) NOT NULL,
`age` INT NOT NULL,
PRIMARY KEY(`id`)
);

INSERT INTO student (`name`, `age`) VALUES("zhangsan", "20");
INSERT INTO student (`name`, `age`) VALUES("lisi", "21");
INSERT INTO student (`name`, `age`) VALUES("wangwu", "22");
INSERT INTO student (`name`, `age`) VALUES("zhaoliu", "23");

JDBCUtil工具类

db.properties

jdbc.url = jdbc:mysql://localhost:3306/spring_data
jdbc.user = root
jdbc.password = 1234
jdbc.driverClass = com.mysql.jdbc.Driver

JDBCUtil工具类

import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class JDBCUtil {
    public static Connection getConnection() throws Exception {
        InputStream is = JDBCUtil.class.getClassLoader().getResourceAsStream("db.properties");
        Properties properties = new Properties();
        properties.load(is);

        String url = properties.getProperty("jdbc.url");
        String user = properties.getProperty("jdbc.user");
        String password = properties.getProperty("jdbc.password");
        String driverClass = properties.getProperty("jdbc.driverClass");

        Class.forName(driverClass);
        Connection connection = DriverManager.getConnection(url, user, password);
        return connection;
    }

    public static void release(ResultSet resultSet, Statement statement, Connection connection){
        if (resultSet != null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (statement != null){
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (connection != null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

创建数据模型和DAO及其实现类

public class Student {
    private int id;
    private String name;
    private int age;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
import cn.zjut.domain.Student;

import java.util.List;

public interface StudentDao {
    List<Student> query();
    void save(Student student);
}

 

import cn.zjut.dao.StudentDao;
import cn.zjut.domain.Student;
import cn.zjut.util.JDBCUtil;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

public class StudentDaoImpl implements StudentDao {
    @Override
    public List<Student> query() {
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        List<Student> list = new ArrayList<>();
        try {
            connection = JDBCUtil.getConnection();
            String sql = "select * from student";
            statement = connection.prepareStatement(sql);
            resultSet = statement.executeQuery();
            while (resultSet.next()){
                int id = resultSet.getInt("id");
                String name = resultSet.getString("name");
                int age = resultSet.getInt("age");
                Student student = new Student();
                student.setId(id);
                student.setName(name);
                student.setAge(age);
                list.add(student);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtil.release(resultSet, statement, connection);
        }
        return list;
    }

    @Override
    public void save(Student student) {
        Connection connection = null;
        PreparedStatement statement = null;
        try {
            connection = JDBCUtil.getConnection();
            String sql = "insert into student (`name`, `age`) values (?, ?)";
            statement = connection.prepareStatement(sql);
            statement.setString(1, student.getName());
            statement.setInt(2, student.getAge());
            statement.executeUpdate();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            JDBCUtil.release(null, statement, connection);
        }
    }
}
public class StudentDaoTest {
    @Test
    public void testQuery(){
        StudentDao studentDao = new StudentDaoImpl();
        studentDao.query().stream().forEach(student -> System.out.println(student));
    }

    @Test
    public void testSave(){
        StudentDao studentDao = new StudentDaoImpl();
        Student student = new Student();
        student.setName("test");
        student.setAge(25);
        studentDao.save(student);
    }
}

Spring JdbcTemplate

添加依赖

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-beans</artifactId>
  <version>5.1.0.RELEASE</version>
</dependency>

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-core</artifactId>
  <version>5.1.0.RELEASE</version>
</dependency>

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>5.1.0.RELEASE</version>
</dependency>

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-expression</artifactId>
  <version>5.1.0.RELEASE</version>
</dependency>

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-jdbc</artifactId>
  <version>5.1.0.RELEASE</version>
</dependency>

实现StudentDao接口 

import cn.zjut.dao.StudentDao;
import cn.zjut.domain.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowCallbackHandler;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class StudentDaoSpringJdbcImpl implements StudentDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public List<Student> query() {
        List<Student> list = new ArrayList<>();
        String sql = "select `id`, `name`, `age` from student";
        jdbcTemplate.query(sql, new RowCallbackHandler() {
            @Override
            public void processRow(ResultSet resultSet) throws SQLException {
                int id = resultSet.getInt("id");
                String name = resultSet.getString("name");
                int age = resultSet.getInt("age");
                Student student = new Student();
                student.setId(id);
                student.setName(name);
                student.setAge(age);
                list.add(student);
            }
        });
        return list;
    }

    @Override
    public void save(Student student) {
        String sql = "insert into student (`name`, `age`) values (?, ?)";
        jdbcTemplate.update(sql, new Object[]{student.getName(), student.getAge()});
    }
}

创建Dao的Spring配置文件 applicationContext.xm,并进行相应配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">

    <context:property-placeholder location="classpath:db.properties"/>
    <context:annotation-config/>
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.user}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="driverClassName" value="${jdbc.driverClass}"/>
    </bean>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <bean id="studentDao" class="cn.zjut.dao.impl.StudentDaoSpringJdbcImpl" >

    </bean>
</beans>

测试类

import cn.zjut.dao.StudentDao;
import cn.zjut.domain.Student;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class StudentDaoSpringJdbcImplTest {
    private ApplicationContext applicationContext = null;
    @Before
    public void init(){
        applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        System.out.println("init");
    }

    @After
    public void destroy(){
        applicationContext = null;
        System.out.println("destroy");
    }

    @Test
    public void testQuery(){
        StudentDao studentDao = (StudentDao) applicationContext.getBean("studentDao");
        studentDao.query().stream().forEach(student -> System.out.println(student));
    }

    @Test
    public void testSave(){
        StudentDao studentDao = (StudentDao) applicationContext.getBean("studentDao");
        Student student = new Student();
        student.setName("maba");
        student.setAge(24);
        studentDao.save(student);
    }
}

弊端分析

       Dao has many many code

       DaoImpl has many duplicate code

       Develop the page and other functions

Spring Data JPA快速起步

       开发环境搭建

       Spring Data JPA HelloWord开发

导入依赖

 

<dependency>
  <groupId>org.springframework.data</groupId>
  <artifactId>spring-data-jpa</artifactId>
  <version>2.0.8.RELEASE</version>
</dependency>

<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-entitymanager</artifactId>
  <version>5.3.3.Final</version>
</dependency>

Spring配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:jpa="http://www.springframework.org/schema/data/jpa"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/data/jpa
       http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

    <context:property-placeholder location="classpath:db.properties"/>
    <!--配置数据源-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.user}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="driverClassName" value="${jdbc.driverClass}"/>
    </bean>
    <!--配置EntityManagerFactory-->
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"></bean>
        </property>
        <property name="packagesToScan" value="cn.zjut"/>
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
    </bean>
    <!--配置事务管理器-->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>
    <!--配置支持事务的注解-->
    <tx:annotation-driven transaction-manager="transactionManager"/>
    <!--配置spring data jpa-->
    <jpa:repositories base-package="cn.zjut" entity-manager-factory-ref="entityManagerFactory"/>

    <context:component-scan base-package="cn.zjut"/>
</beans>

数据实体类

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

/**
 * 先开发实体类,再生成数据表
 */
@Entity
public class Employee {
    private Integer id;
    private String name;
    private Integer age;
    @GeneratedValue
    @Id
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }
    @Column(length =20)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

创建EmployeeRepository

import cn.zjut.domain.Employee;
import org.springframework.data.repository.Repository;

public interface EmployeeRepository extends Repository<Employee, Integer> {
    Employee findByName(String name);
}

创建测试类

import cn.zjut.domain.Employee;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class EmployeeRepositoryTest {
    private ApplicationContext applicationContext = null;
    private EmployeeRepository employeeRepository = null;
    @Before
    public void init(){
        applicationContext = new ClassPathXmlApplicationContext("applicationContext-new.xml");
        employeeRepository = applicationContext.getBean(EmployeeRepository.class);
        System.out.println("init");
    }

    @After
    public void destroy(){
        applicationContext = null;
        System.out.println("destroy");
    }

    @Test
    public void testFindByName(){
        Employee employee = employeeRepository.findByName("zhangsan");
        System.out.println(employee);
    }
}

Repository 

       Reposity

       RepositoryDefinition

       Repository Query Specifications

       Query Annotation

       Update/Delete/Transaction

Repository Hierarchy

       CrudRepository

       PagingAndSortingRepository

       JpaRepository

       JpaSpecificationExecutor

Repository接口

       Repository接口时Spring Data的和新街口,不提供任何方法

       public interface Repository<T, ID extends Serializable>{}

       @RepositoryDefinition注解的使用

Repository接口定义

public interface Repository<T, ID> {
}

       Repository是一个空接口,标记接口,没有方法声明的接口

       自定义接口EmployeeRepository继承Repository则会交由Spring管理

       @RepositoryDefinition(domainClass = Employee.class, idClass = Integer.class),该注解可以使得接口不用继承Repository接口

Repository子接口详解

       CrudRepository:继承Repository,实现了CRUD相关方法

       PagingAndSortingRepository:继承CrudRepository,实现了分页排序相关方法

      JpaRepository:继承PagingAndSortingRepository,实现JPA相关方法

Repository中查询方法定义规则和使用

       了解Spring Data中查询方法名称的定义规则

       使用Spring Data完成复杂查询方法名称的命名

 

测试案例

数据表中增加测试数据

INSERT INTO employee (`name`, `age`) VALUES("test1", "20");
INSERT INTO employee (`name`, `age`) VALUES("test2", "21");
INSERT INTO employee (`name`, `age`) VALUES("test3", "22");
INSERT INTO employee (`name`, `age`) VALUES("test4", "23");
INSERT INTO employee (`name`, `age`) VALUES("test5", "24");
INSERT INTO employee (`name`, `age`) VALUES("test6", "25");
INSERT INTO employee (`name`, `age`) VALUES("test16", "26");

按照规则声明方法

List<Employee> findByNameStartingWithAndAgeLessThan(String name, Integer age);
List<Employee> findByNameEndingWithAndAgeLessThan(String name, Integer age);
List<Employee> findByNameInAndAgeLessThan(List<String> name, Integer age);
List<Employee> findByNameInOrAgeLessThan(List<String> name, Integer age);

编写测试方法

 

@Test
public void testFindByNameStartingWithAndAgeLessThan(){
    employeeRepository.findByNameStartingWithAndAgeLessThan("test", 24).stream().forEach(employee -> System.out.println(employee));
}

@Test
public void testFindByNameEndingWithAndAgeLessThan(){
    employeeRepository.findByNameEndingWithAndAgeLessThan("6", 30).stream().forEach(employee -> System.out.println(employee));
}

@Test
public void testFindByNameInAndAgeLessThan(){
    List<String> name = new ArrayList<>();
    name.add("test1");
    name.add("test2");
    name.add("test3");
    name.add("test4");
    employeeRepository.findByNameInAndAgeLessThan(name, 22).stream().forEach(employee -> System.out.println(employee));
}

@Test
public void testFindByNameInOrAgeLessThan(){
    List<String> name = new ArrayList<>();
    name.add("test1");
    name.add("test2");
    name.add("test3");
    name.add("test4");
    employeeRepository.findByNameInOrAgeLessThan(name, 22).stream().forEach(employee -> System.out.println(employee));
}

对于按照方法命名规则来使用的话,有弊端:

       方法名会比较长:约定大于配置

       对于一些复杂查询,是很难实现

Query注解的使用

       在Repository方法中使用,不需要遵循查询方法命名规则

       只需要将@Query定义在Repository中方法之上即可

       命名参数及索引参数使用

       本地查询

声明自定义方法

@Query("select o from Employee o where id = (select max(id) from Employee t)")
public Employee getEmployeeByMaxId();

@Query("select o from Employee o where o.name = ?1 and o.age = ?2")
public List<Employee> queryParam(String name, Integer age);

@Query("select o from Employee o where o.name=:name and o.age=:age")
public List<Employee> queryParamOtherWay(@Param("name") String name, @Param("age") Integer age);

@Query("select o from Employee o where o.name like %?1%")
List<Employee> queryLike1(String name);

@Query("select o from Employee o where o.name like %:name%")
List<Employee> queryLike2(@Param("name") String name);

@Query(nativeQuery = true, value = "select count(1) from employee")
public long getCount();

 编写测试方法

@Test
public void testGetEmployeeByMaxId(){
    Employee employee = employeeRepository.getEmployeeByMaxId();
    System.out.println(employee);
}

@Test
public void testQueryParam(){
    employeeRepository.queryParam("zhangsan", 19).stream().forEach(employee -> System.out.println(employee));
}

@Test
public void testQueryParamOtherWay(){
    employeeRepository.queryParamOtherWay("zhangsan", 19).stream().forEach(employee -> System.out.println(employee));
}

@Test
public void testQueryLike1(){
    employeeRepository.queryLike1("test").stream().forEach(employee -> System.out.println(employee));
}

@Test
public void testQueryLike2(){
    employeeRepository.queryLike2("test1").stream().forEach(employee -> System.out.println(employee));
}

@Test
public void testGetCount(){
    long count = employeeRepository.getCount();
    System.out.println(count);
}

更新及删除操作整合事务的使用

        @Mpdifying注解使用

        @Modifying结合@Query注解执行更新操作

        @Transactional在Spring Data中的使用

声明方法

    @Modifying
    @Query("update Employee o set o.age = :age where o.id = :id")
    public void update(@Param("id") Integer id, @Param("age") Integer age);
}

创建EmployeeService类并在方法上添加事务注解

import cn.zjut.repository.EmployeeRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class EmployeeService {
    @Autowired
    private EmployeeRepository employeeRepository;

    @Transactional
    public void update(Integer id, Integer age){
        employeeRepository.update(id, age);
    }
}

编写测试类

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class EmployeeServiceTest {
    private ApplicationContext applicationContext = null;
    private EmployeeService employeeService = null;
    @Before
    public void init(){
        applicationContext = new ClassPathXmlApplicationContext("applicationContext-new.xml");
        employeeService = applicationContext.getBean(EmployeeService.class);
        System.out.println("init");
    }

    @After
    public void destroy(){
        applicationContext = null;
        System.out.println("destroy");
    }

    @Test
    public void testUpdate(){
        employeeService.update(1,30);
    }
}

 事务在Spring Data中使用

       事务一般是在Service层

       @Query、@Modifying、@Transactional综合使用

CrudRepository接口使用详解

       save(entity)

       save(entities)

       findOne(id)

       exists(id)

       findAll()

       delete(id)

       delete(entity)

       delete(entities)

       deleteAll()

修改实体类对象换一个数据表

import javax.persistence.*;

/**
 * 先开发实体类,再生成数据表
 */
@Entity
@Table(name = "test_employee")
public class Employee {
    private Integer id;
    private String name;
    private Integer age;
    @GeneratedValue
    @Id
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }
    @Column(length =20)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

创建EmployeeCrudRepository接口

import cn.zjut.domain.Employee;
import org.springframework.data.repository.CrudRepository;

public interface EmployeeCrudRepository extends CrudRepository<Employee, Integer> {

}

Service中添加方法

@Transactional
public void save(List<Employee> employees){
    employeeCrudRepository.saveAll(employees);
}

编写测试类

import cn.zjut.domain.Employee;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.ArrayList;
import java.util.List;

public class EmployeeCrudRepositoryTest {
    private ApplicationContext applicationContext = null;
    private EmployeeService employeeService = null;
    @Before
    public void init(){
        applicationContext = new ClassPathXmlApplicationContext("applicationContext-new.xml");
        employeeService = applicationContext.getBean(EmployeeService.class);
        System.out.println("init");
    }

    @After
    public void destroy(){
        applicationContext = null;
        System.out.println("destroy");
    }

    @Test
    public void testSave(){
        List<Employee> employees = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            Employee employee = new Employee();
            employee.setName("test"+i);
            employee.setAge(100 - i);
            employees.add(employee);
        }
        employeeService.save(employees);
    }
}

 PageAndSortingRepository接口使用详解

       该接口包含分页和排序功能

       带排序的查询:findAll(Sort sort)

       带排序的分页查询:findAll(Pageable pageable)

创建EmployeePagingAndSortingRepository接口

import cn.zjut.domain.Employee;
import org.springframework.data.repository.PagingAndSortingRepository;

public interface EmployeePagingAndSortingRepository extends PagingAndSortingRepository<Employee, Integer> {
}

编写测试类

import cn.zjut.domain.Employee;
import org.junit.After;
import org.junit.Before;
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;

public class EmployeePagingAndSortingRepositoryTest {
    private ApplicationContext applicationContext = null;
    private EmployeePagingAndSortingRepository employeePagingAndSortingRepository = null;
    @Before
    public void init(){
        applicationContext = new ClassPathXmlApplicationContext("applicationContext-new.xml");
        employeePagingAndSortingRepository = applicationContext.getBean(EmployeePagingAndSortingRepository.class);
        System.out.println("init");
    }

    @After
    public void destroy(){
        applicationContext = null;
        System.out.println("destroy");
    }

    @Test
    public void testPage(){
        // Pageable pageable = new PageRequest(0,5);//已过时
        Pageable pageable = PageRequest.of(1,9);
        Page<Employee> page = employeePagingAndSortingRepository.findAll(pageable);
        System.out.println("查询总页数:" + page.getTotalPages());
        System.out.println("查询记录数:" + page.getTotalElements());
        System.out.println("查询当前页码:" + (page.getNumber() + 1));
        System.out.println("查询页面集合:" + page.getContent());
        System.out.println("查询的当前页面记录数:" + page.getNumberOfElements());
    }

    @Test
    public void testPageAndSort(){
        Sort.Order order = new Sort.Order(Sort.Direction.DESC, "id");
        Sort sort = Sort.by(order);
        Pageable pageable = PageRequest.of(0,5, sort);
        Page<Employee> page = employeePagingAndSortingRepository.findAll(pageable);
        System.out.println("查询总页数:" + page.getTotalPages());
        System.out.println("查询记录数:" + page.getTotalElements());
        System.out.println("查询当前页码:" + (page.getNumber() + 1));
        System.out.println("查询页面集合:" + page.getContent());
        System.out.println("查询的当前页面记录数:" + page.getNumberOfElements());
    }
}

JpaRepository接口使用详解

       findALL

       findAll(Sort sort)

       save(entities)

       flush

       deleteInBatch(entities)

创建EmployeJpaRepository接口

import cn.zjut.domain.Employee;
import org.springframework.data.jpa.repository.JpaRepository;

public interface EmployeJpaRepository extends JpaRepository<Employee, Integer> {
}

编写测试类

import cn.zjut.domain.Employee;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.domain.Example;

import java.util.Optional;

public class EmployeeJpaRepositoryTest {
    private ApplicationContext applicationContext = null;
    private EmployeJpaRepository employeJpaRepository = null;
    @Before
    public void init(){
        applicationContext = new ClassPathXmlApplicationContext("applicationContext-new.xml");
        employeJpaRepository = applicationContext.getBean(EmployeJpaRepository.class);
        System.out.println("init");
    }

    @After
    public void destroy(){
        applicationContext = null;
        System.out.println("destroy");
    }

    @Test
    public void testFind(){
        Optional<Employee> employee = employeJpaRepository.findById(99);
        System.out.println(employee);
        System.out.println(employeJpaRepository.existsById(10));
        System.out.println(employeJpaRepository.existsById(102));
    }
}

 JpaSpecificationExecutor接口使用详解

       Specification封装了JPA Criteria查询条件

编写EmployeJpaSpecificationExecutorRepository接口

import cn.zjut.domain.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

public interface EmployeJpaSpecificationExecutorRepository
        extends JpaRepository<Employee, Integer>, JpaSpecificationExecutor<Employee> {
}

 编写测试类

import cn.zjut.domain.Employee;
import org.junit.After;
import org.junit.Before;
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.jpa.domain.Specification;

import javax.persistence.criteria.*;

public class EmployeeJpaSpecificationExecutorRepositoryTest {
    private ApplicationContext applicationContext = null;
    private EmployeJpaSpecificationExecutorRepository employeJpaSpecificationExecutorRepository = null;
    @Before
    public void init(){
        applicationContext = new ClassPathXmlApplicationContext("applicationContext-new.xml");
        employeJpaSpecificationExecutorRepository = applicationContext.getBean(EmployeJpaSpecificationExecutorRepository.class);
        System.out.println("init");
    }

    @After
    public void destroy(){
        applicationContext = null;
        System.out.println("destroy");
    }

    @Test
    public void testQuery(){
        Sort.Order order = new Sort.Order(Sort.Direction.DESC, "id");
        Sort sort = Sort.by(order);
        Pageable pageable = PageRequest.of(0,5, sort);

        Specification<Employee> specification = new Specification<Employee>() {

            @Override
            public Predicate toPredicate(Root<Employee> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                Path path = root.get("age");
                return  criteriaBuilder.gt(path, 50);
            }
        };

        Page<Employee> page = employeJpaSpecificationExecutorRepository.findAll(specification,pageable);
        System.out.println("查询总页数:" + page.getTotalPages());
        System.out.println("查询记录数:" + page.getTotalElements());
        System.out.println("查询当前页码:" + (page.getNumber() + 1));
        System.out.println("查询页面集合:" + page.getContent());
        System.out.println("查询的当前页面记录数:" + page.getNumberOfElements());
    }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

       

 

 

 

 

       

 

       

 

 

 

 

 

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值