什么是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());
}
}