概念
Spring Data JPA 是 Spring Data 系列的一部分,可以轻松实现基于 JPA 的存储库。 该模块处理对基于 JPA 的数据访问层的增强的支持。 这使得使用数据访问技术构建Spring 的应用程序变得更加容易。
传统方式访问数据库JDBC驱动
创建Maven项目
- maven工程的目录结构
|– pom.xml
|– src
| |– main
| |-- java | |
– resources
| |-- filters |
– test
| |-- java | |
– resources
| |-- filters |
– it
|-- assembly |
– site
|– LICENSE.txt
|– NOTICE.txt
|– README.txt - 添加依赖12345678910111213<!--MySQL Driver--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.38</version></dependency><!--junit--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.10</version><scope>test</scope></dependency>
数据表准备
- Create database 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);
开发JDBCUtil工具类
- 获取Connection,关闭Connection、Statement、ResultSet
- 注意事项
配置的属性放置在配置文件中,通过代码的方式将配置文件中的属性加载进程序建立对象模型,DAO
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152package com.imooc.domain;/*** Student实体类*/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;}@Overridepublic String toString() {return "Student{" +"id=" + id +", name='" + name + '\'' +", age=" + age +'}';}}
使用Spring JDBC的方式操作数据库
添加依赖
|
|
配置beans.xml
|
|
开发Spring JDBC版本的query和save方法
|
|
传统方式访问数据库的缺点
- DAO里面代码很多
- DAOImpl有很多重复的代码
- 开发分页和其他功能需要重新封装
Spring Data JPA快速起步
开发环境搭建
pom.xml
|
|
beans.xml
|
|
Spring data JPA进阶
Repository接口讲解
- Repository是Spring Data的核心接口,不提供任何方法
- Public interface Repository
{ } @RepositoryDefinition
注解的使用- Repository是一个空接口,也叫做标记接口(没有包含方法声明的接口)
- 如果我们定义的EmployeeRepository extends Repository,如果我们自己的接口没有继承Repository接口,会报错
- 添加注解能够达到不用extends Repository接口 的功能1234@RepositoryDefinition(domainClass = Employee.class, idClass = Integer.class)public interface EmployeeRepository{public Employee findByName(String name);}
Repository子接口讲解
- CrudRepository:继承Repository,实现CRUD相关的方法
- PagingAndSortingRepositoy:继承CrudRepository,实现了分页排序相关的方法
- JPARepository:继承PagingAndSortingRepository,实现JPA规范相关的方法
Repository中查询方法定义规则和使用
接口代码:
1234567891011public interface EmployeeRepository extends Repository<Employee, Integer>{public Employee findByName(String name);// where name like ?% and age < ?public List<Employee> findByNameStartingWithAndAgeLessThan(String name, Integer age);// where name like %? and age < ?public List<Employee> findByNameEndingWithAndAgeLessThan(String name, Integer age);// where name in (?,?) or age < ?public List<Employee> findByNameInOrAgeLessThan(List<String> names, Integer age);// where name in (?,?) and age < ?public List<Employee> findByNameInAndAgeLessThan(List<String> names, Integer age);}按照方法命名规则来使用的话的弊端:
- 方法名比较常:约定大于配置
- 对于一些复杂查询,很难实现
4. Query注解的使用
1. 在Repository方法中使用,不需要遵循查询方法命名规则
|
|
2. 只需要将@Query定义在Repository中的方法之上即可
3. 支持命名参数和索引参数的使用
|
|
4. 支持本地查询
|
|
5. 更新和删除操作整合事务的使用
1. `@Modifying`注解使用
2. `@Modifying`结合@Query注解执行更新操作
2. `@Transactional`在Spring Data中的使用
4. 事务在Spring中的使用:
* 事务一般是在Service层
* @Query、@Modifying、@Transactional的综合使用
Spring Data JPA高级
CrudRepository接口使用详解
PagingAndSortingRepository接口使用详解
- 分页和排序
带排序的查询
12345678910111213@Testpublic void testPage() {//page: index是从0开始的Pageable pageable = new PageRequest(0,5);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());}带排序的分页查询
123456789101112131415@Testpublic void testPageAndSort() {Sort.Order order = new Sort.Order(Sort.Direction.DESC, "id");Sort sort = new Sort(order);//page: index是从0开始的Pageable pageable = new PageRequest(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接口使用详解
- 封装了JPA Criteria查询条件