SpringDataJPA主要有以下五个核心接口:Repository,CurdRepository,PagingAndSortingRepository,JpaRepository,JpaSpecificationExecutor
下面让我们来创建一个简单的Springboot例子来演示一下吧
application.properties文件
#jdbc配置
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springboot
spring.datasource.username=root
spring.datasource.password=123456
#连接池配置,首先需要导入druid包
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
#设置自动建表,显示sql语句
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
实体类
import lombok.Data; //lokbom工具包,节省代码
import javax.persistence.*; //jpa注解,表示都是持久层
@Entity
@Table(name="t_users")
@Data
public class Users {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
@Column(name="id")
private Integer id;
@Column(name="name")
private String name;
@Column(name="age")
private Integer age;
@Column(name="address")
private String address;
}
这样环境就基本搭建好了,下面开始演视
Repository
仅仅是一个标识,表明任何继承它的均为仓库接口类,方便Spring自动扫描识别。提供了方法命名操作方式
import com.example.springboot.pojo.Users;
import org.springframework.data.repository.Repository;
import java.util.List;
/*
Repository<T, ID> T指类型,ID指id类型
Repository接口的方法名称命名查询
*/
public interface UsersRepository extends Repository<Users,Integer> {
//方法的名称必须要遵循驼峰式命名规则
void save(Users users);
void deleteById(Integer id);
List<Users> findByName(String name);
List<Users> findByNameAndAge(String name,Integer age);
}
下面进行使用SpringbootApplicationTests测试
报错了?由图看出是时区错误,这都是因为安装mysql的时候时区设置的不正确 mysql默认的是美国的时区,而我们中国大陆要比他们迟8小时,采用+8:00格式。SpringBoot2.1在你没有指定MySQL驱动版本的情况下它自动依赖的驱动是8.0.12很高的版本,这是由于数据库和系统时区差异所造成的,在jdbc连接的url后面加上serverTimezone=GMT即可解决问题再一个解决办法就是使用低版本的MySQL jdbc驱动,5.1.45不会存在时区的问题.
改过驱动后,再来重试
CurdRepository
继承Repository,实现了一组CRUD相关的方法
/*
*CurdRepository源代码
*/
package org.springframework.data.repository;
import java.util.Optional;
@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> {
<S extends T> S save(S var1);
<S extends T> Iterable<S> saveAll(Iterable<S> var1);
Optional<T> findById(ID var1);
boolean existsById(ID var1);
Iterable<T> findAll();
Iterable<T> findAllById(Iterable<ID> var1);
long count();
void deleteById(ID var1);
void delete(T var1);
void deleteAll(Iterable<? extends T> var1);
void deleteAll();
}
实现代码:
import com.example.springboot.pojo.Users;
import org.springframework.data.repository.CrudRepository;
public interface UserCrudRepository extends CrudRepository<Users,Integer> {
}
PagingAndSortingRepository
继承CrudRepository,实现了一组分页排序相关的方法
/*
*PagingAndSortingRepository源代码
*/
package org.springframework.data.repository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {
Iterable<T> findAll(Sort var1);
Page<T> findAll(Pageable var1);
}
实现代码:
import com.example.springboot.pojo.Users;
import org.springframework.data.repository.PagingAndSortingRepository;
public interface UserPagingAndSortingRepository extends PagingAndSortingRepository<Users,Integer> {
}
JpaRepository
继承PagingAndSortingRepository,实现一组JPA规范相关的方法
/*
*JpaRepository源代码
*/
package org.springframework.data.jpa.repository;
import java.util.List;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.QueryByExampleExecutor;
@NoRepositoryBean
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
List<T> findAll();
List<T> findAll(Sort var1);
List<T> findAllById(Iterable<ID> var1);
<S extends T> List<S> saveAll(Iterable<S> var1);
void flush();
<S extends T> S saveAndFlush(S var1);
void deleteInBatch(Iterable<T> var1);
void deleteAllInBatch();
T getOne(ID var1);
<S extends T> List<S> findAll(Example<S> var1);
<S extends T> List<S> findAll(Example<S> var1, Sort var2);
}
代码实现:
import com.example.springboot.pojo.Users;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UsersJpaRepository extends JpaRepository<Users,Integer> {
}
JpaSpecificationExecutor
比较特殊,不属于Repository体系,实现一组JPA Criteria查询相关的方法
/*
*JpaSpecificationExecutor源代码
*/
package org.springframework.data.jpa.repository;
import java.util.List;
import java.util.Optional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.lang.Nullable;
public interface JpaSpecificationExecutor<T> {
Optional<T> findOne(@Nullable Specification<T> var1);
List<T> findAll(@Nullable Specification<T> var1);
Page<T> findAll(@Nullable Specification<T> var1, Pageable var2);
List<T> findAll(@Nullable Specification<T> var1, Sort var2);
long count(@Nullable Specification<T> var1);
}
代码实现:
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface UsersJpaSpecificationExecutor extends JpaRepository<Users, Integer>, JpaSpecificationExecutor<Users> {
}
测试全部代码:
package com.example.springboot;
import com.example.springboot.dao.*;
import com.example.springboot.pojo.Users;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
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 org.springframework.test.context.junit4.SpringRunner;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootApplicationTests {
@Autowired
private UsersRepository usersRepository;
@Autowired
private UserCrudRepository userCrudRepository;
@Autowired
private UserPagingAndSortingRepository userPagingAndSortingRepository;
@Autowired
private UsersJpaRepository usersJpaRepository;
@Autowired
private UsersJpaSpecificationExecutor usersJpaSpecificationExecutor;
/**
* JpaSpecificationExecutor单条件查询
*/
@Test
public void testJpaSpecificationExecutor1() {
/**
* Specification<Users>:用于封装查询条件
*/
Specification<Users> spec = new Specification<Users>() {
//Predicate:封装了 单个的查询条件
/**
* Root<Users> root:查询对象的属性的封装。
* CriteriaQuery<?> query:封装了我们要执行的查询中的各个部分的信息,select from order by
* CriteriaBuilder cb:查询条件的构造器。定义不同的查询条件
*/
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
/**
* 参数一:查询的条件属性
* 参数二:条件的值
*/
Predicate pre = cb.equal(root.get("name"), "李四");
return pre;
}
};
List<Users> list = usersJpaSpecificationExecutor.findAll(spec);
for (Users users : list) {
System.out.println(users);
}
}
/**
* JpaSpecificationExecutor 多条件测试
*/
@Test
public void testJpaSpecificationExecutor2() {
Specification<Users> spec = new Specification<Users>() {
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
List<Predicate> list = new ArrayList<>();
list.add(cb.equal(root.get("name"),"李四"));
list.add(cb.equal(root.get("age"),20));
Predicate[] arr = new Predicate[list.size()];
return cb.and(list.toArray(arr));
}
};
List<Users> list = usersJpaSpecificationExecutor.findAll(spec);
for (Users users : list) {
System.out.println(users);
}
}
/**
* JpaSpecificationExecutor 多条件测试第二种写法
*/
@Test
public void testJpaSpecificationExecutor3() {
Specification<Users> spec = new Specification<Users>() {
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
return cb.or(cb.and(cb.equal(root.get("name"),"李四"),cb.equal(root.get("age"),20)),cb.equal(root.get("id"), 2));
}
};
Sort sort = new Sort(new Order(Direction.DESC,"id"));
List<Users> list = usersJpaSpecificationExecutor.findAll(spec,sort);
for (Users users : list) {
System.out.println(users);
}
}
/**
* JapRepository 排序测试
*/
@Test
public void testJpaRepositorySort() {
//Order 定义排序规则
Order order = new Order(Direction.DESC,"id");
//Sort对象封装了排序规则
Sort sort = new Sort(order);
List<Users> list = usersJpaRepository.findAll(sort);
for (Users users : list) {
System.out.println(users);
}
}
/**
* PagingAndSortingRepository 排序测试
*/
@Test
public void testPagingAndSortingRepositorySort() {
Order order = new Sort.Order(Sort.Direction.DESC,"id");
Sort sort = new Sort(order); //Sort已过时,但仍可用
List<Users> list = (List<Users>)userPagingAndSortingRepository.findAll(sort);
for (Users users : list) {
System.out.println(users);
}
}
/**
* PagingAndSortingRepository 分页测试
*/
@Test
public void testPagingAndSortingRepositoryPaging() {
//Pageable:封装了分页的参数,当前页,每页显示的条数。注意:他的当前页是从0开始。
//PageRequest(page,size) page:当前页。size:每页显示的条数
Pageable pageable = new PageRequest(1, 2); //PageRequest已过时,但仍可用
Page<Users> page = this.userPagingAndSortingRepository.findAll(pageable);
System.out.println("总条数:"+page.getTotalElements());
System.out.println("总页数"+page.getTotalPages());
List<Users> list = page.getContent();
for (Users users : list) {
System.out.println(users);
}
}
/**
* PagingAndSortingRepository 排序+分页
*/
@Test
public void testPagingAndSortingRepositorySortAndPaging() {
Sort sort = new Sort(new Sort.Order(Direction.DESC, "id"));
Pageable pageable = new PageRequest(1, 2, sort);
Page<Users> page = userPagingAndSortingRepository.findAll(pageable);
System.out.println("总条数:"+page.getTotalElements());
System.out.println("总页数"+page.getTotalPages());
List<Users> list = page.getContent();
for (Users users : list) {
System.out.println(users);
}
}
/*
*CrudRepository保存测试
*/
@Test
public void crudSave() {
Users users=new Users();
users.setName("李四");
users.setAge(20);
users.setAddress("天上地下");
userCrudRepository.save(users);
}
/*
*CrudRepository查询测试
*/
@Test
public void crudfindById() {
Users users=new Users();
users.setName("王五");
users.setAge(20);
users.setAddress("天涯海角");
System.out.println(userCrudRepository.findById(2));
}
/*
*Repository根据命名保存测试
*/
@Test
public void save() {
Users users=new Users();
users.setName("李四");
users.setAge(18);
users.setAddress("天上人间");
usersRepository.save(users);
}
/*
*Repository根据命名删除测试
*/
@Test
public void deleteById() {
usersRepository.deleteById(1);
}
/*
*Repository根据命名按姓名查找测试
*/
@Test
public void testFindByName() {
List<Users> list = usersRepository.findByName("李四");
for (Users users : list) {
System.out.println(users);
}
}
}
更多关于Spring Data JPA请访问:https://spring.io/projects/spring-data-jpa