版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq1021979964/article/details/88760928
SpringBoot整合JPA
Spring Data:
Spring Data是Spring提供了一个操作数据的框架。而Spring Data Jpa只是Spring Data框架下的一个基于JPA标准操作数据的模块。
Spring Data JPA:
基于JPA的标准对数据进行操作。简化操作持久层的代码。只需要编写接口就可以了。
Spring Data JPA提供的核心接口:
1.Repository接口
提供方法名称命名查询方式
提供基于@Query注解查询与更新
2.CrudRepository接口
继承Repository接口,实现CRUD相关操作
3.PagingAndSortingRepository接口
继承CrudRepository接口,实现分页排序相关操作
4.JpaRepository接口
继承PagingAndSortingRepository接口,实现JPA规范相关操作
5.JPASpecificationExecutor接口
不属于Repository体系,单独存在,提供多条件的支持,并且可以在查询中添加分页和排序
直接写案例测试这五个接口
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-boot-kevin</artifactId>
<groupId>com.kevin</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>08-spring-boot-jpa</artifactId>
<dependencies>
<!-- springBoot的启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- thymeleaf的启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- springboot整合jpa需要的依赖包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- druid连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
<!-- 测试工具的启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
</project>
application.yml
spring:
#配置数据源
datasource:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/ssm_crud?characterEncoding=utf-8
username: root
password: 123456
#使用druid连接池
type: com.alibaba.druid.pool.DruidDataSource
jpa:
hibernate:
#正向工程,如果数据中没有表,则会创建一张表再更新数据,存在,则会直接更新数据
ddl-auto: update
#打印执行sql语句
show-sql: true
启动类
package com.kevin;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
/**
* @author kevin
* @version 1.0
* @description SpringBoot整合JPA
* Spring Data:Spring Data是Spring提供了一个操作数据的框架。而Spring Data Jpa只是Spring Data框架下的一个基于JPA标准操作数据的模块。
* Spring Data JPA:基于JPA的标准对数据进行操作。简化操作持久层的代码。只需要编写接口就可以了。
*
* Spring Data JPA提供的核心接口:
* 1.Repository接口
* 提供方法名称命名查询方式
* 提供基于@Query注解查询与更新
* 2.CrudRepository接口
* 继承Repository接口,实现CRUD相关操作
* 3.PagingAndSortingRepository接口
* 继承CrudRepository接口,实现分页排序相关操作
* 4.JpaRepository接口
* 继承PagingAndSortingRepository接口,实现JPA规范相关操作
* 5.JPASpecificationExecutor接口
* 不属于Repository体系,单独存在,提供多条件的支持,并且可以在查询中添加分页和排序
*
* @createDate 2019/3/20
*/
@SpringBootApplication
@EnableJpaRepositories(basePackages = "com.kevin.dao")
public class JpaApplication {
public static void main(String[] args) {
SpringApplication.run(JpaApplication.class,args);
}
}
Users用户实体类
package com.kevin.entity;
import javax.persistence.*;
/**
* @author kevin
* @version 1.0
* @description 用户实体类
* @createDate 2019/3/20
*/
@Entity // 表示该类为实体类
@Table(name="t_users") // 对应数据库中的表名
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;
@ManyToOne(cascade = CascadeType.PERSIST) // ManyToOne表示多对一,cascade = CascadeType.PERSIST属性是级联操作
@JoinColumn(name = "roles_id") // 维护外键
private Roles roles; // 对应的角色
public Users() {
}
public Users(String name, Integer age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
@Override
public String toString() {
return "Users{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
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;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Roles getRoles() {
return roles;
}
public void setRoles(Roles roles) {
this.roles = roles;
}
}
Roles角色实体类
package com.kevin.entity;
import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
/**
* @author kevin
* @version 1.0
* @description 角色实体类
* 一对多
* 一个角色对应多个用户
* @createDate 2019/3/21
*/
@Entity
@Table(name = "t_roles")
public class Roles {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="roleid")
private Integer roleid;
@Column(name="rolename")
private String rolename;
@OneToMany(mappedBy = "roles") // 一对多
private Set<Users> users = new HashSet<>(); // 多个用户
// cascade = CascadeType.PERSIST:开启级联操作。fetch = FetchType.EAGER:设置为立即加载。
@ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER) // 多对多
// @JoinTable:映射中间表信息,name:中间表的表名,joinColumns:当前表中的主键所关联的中间表中的外键
@JoinTable(name = "t_roles_menus", joinColumns = @JoinColumn(name = "role_id"),inverseJoinColumns = @JoinColumn(name = "menus_id"))
private Set<Menus> menus = new HashSet<>();
public Integer getRoleid() {
return roleid;
}
public void setRoleid(Integer roleid) {
this.roleid = roleid;
}
public String getRolename() {
return rolename;
}
public void setRolename(String rolename) {
this.rolename = rolename;
}
public Set<Users> getUsers() {
return users;
}
public void setUsers(Set<Users> users) {
this.users = users;
}
public Set<Menus> getMenus() {
return menus;
}
public void setMenus(Set<Menus> menus) {
this.menus = menus;
}
@Override
public String toString() {
return "Roles{" +
"roleid=" + roleid +
", rolename='" + rolename + '\'' +
", users=" + users +
", menus=" + menus +
'}';
}
}
Menus菜单实体类
package com.kevin.entity;
import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
/**
* @author kevin
* @version 1.0
* @description 菜单表
* 多对多
* 多个菜单对应多个角色
* @createDate 2019/3/21
*/
@Entity
@Table(name = "t_menus")
public class Menus {
@Id // 表示主键
@GeneratedValue(strategy = GenerationType.IDENTITY) // 主键规则
@Column(name = "menusid") // 列名
private Integer menusid;
@Column(name = "menusname")
private String menusname;
@Column(name = "menusurl")
private String menusurl;
@Column(name = "fatherid")
private Integer fatherid;
@ManyToMany(mappedBy = "menus") // 多对多,mappedBy:Roles中关联的字段名称
private Set<Roles> roles = new HashSet<>();
public Integer getMenusid() {
return menusid;
}
public void setMenusid(Integer menusid) {
this.menusid = menusid;
}
public String getMenusname() {
return menusname;
}
public void setMenusname(String menusname) {
this.menusname = menusname;
}
public String getMenusurl() {
return menusurl;
}
public void setMenusurl(String menusurl) {
this.menusurl = menusurl;
}
public Integer getFatherid() {
return fatherid;
}
public void setFatherid(Integer fatherid) {
this.fatherid = fatherid;
}
public Set<Roles> getRoles() {
return roles;
}
public void setRoles(Set<Roles> roles) {
this.roles = roles;
}
@Override
public String toString() {
return "Menus{" +
"menusid=" + menusid +
", menusname='" + menusname + '\'' +
", menusurl='" + menusurl + '\'' +
", fatherid=" + fatherid +
'}';
}
}
1.Repository接口方法命名查询
package com.kevin.dao;
import com.kevin.entity.Users;
import org.springframework.data.repository.Repository;
import java.util.List;
/**
* @author kevin
* @version 1.0
* @description Repository接口的使用:方法名称命名查询的使用
* @createDate 2019/3/20
*/
public interface UsersRepositoryByName extends Repository<Users,Integer> {
// 方法命名规则:必须要遵循驼峰式命名规则。findBy(关键字)+属性名称(首字母要大写)+查询条件(首字母要大写)
// 根据名字查询
List<Users> findByName(String name);
// 根据名字和年龄查询
List<Users> findByNameAndAge(String name,Integer age);
// 根据名字用通配符做查询
List<Users> findByNameLike(String name);
}
1.Repository接口中@Query
package com.kevin.dao;
import com.kevin.entity.Users;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* @author kevin
* @version 1.0
* @description Repository接口的使用:@Query的使用
*
* @createDate 2019/3/20
*/
@Transactional
public interface UsersRepositoryQueryAnnotation extends Repository<Users, Integer> {
// @Query查询
// @Query 以对象HQL语句查询。根据名字作为条件查询
@Query("from Users where name = :name")
List<Users> queryByNameUseHQL(@Param("name") String name);
// @Query 以对象SQL语句查询。根据名字作为条件查询,使用标准的SQL
@Query(value="select * from t_users where name = ? ",nativeQuery = true)
List<Users> queryByNameUseSQL(String name);
// @Query更新
// @Query根据id更新name
@Query("update Users set name = :name where id = :id")
@Modifying
void updateUsersNameById(@Param("name")String name, @Param("id") Integer id);
}
2.CrudRepository接口的使用
package com.kevin.dao;
import com.kevin.entity.Users;
import org.springframework.data.repository.CrudRepository;
/**
* @author kevin
* @version 1.0
* @description CrudRepository接口的使用:主要是完成一些增删改查的操作。
* CrudRepository接口继承了Repository接口
* @createDate 2019/3/20
*/
public interface UsersCrudRepository extends CrudRepository<Users,Integer> {
}
3.PagingAndSortRepository接口的使用
package com.kevin.dao;
import com.kevin.entity.Users;
import org.springframework.data.repository.PagingAndSortingRepository;
/**
* @author kevin
* @version 1.0
* @description PagingAndSortingRepository的使用。主要是排序,分页等
* @createDate 2019/3/20
*/
public interface UsersPagingAndSortingRepository extends PagingAndSortingRepository<Users,Integer> {
}
4.JPARepository接口在Users的使用
package com.kevin.dao;
import com.kevin.entity.Users;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* @author kevin
* @version 1.0
* @description JpaRepository接口的使用,对继承的父接口中的方法的返回值进行适配。
* 参数一 T :当前需要映射的实体类
* 参数二 ID :当前映射的实体类中的OID的类型
* @createDate 2019/3/20
*/
public interface UsersJpaRepository extends JpaRepository<Users,Integer> {
}
4.JPARepository接口在Roles的使用
package com.kevin.dao;
import com.kevin.entity.Roles;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* @author kevin
* @version 1.0
* @description 操作Roles表
* @createDate 2019/3/21
*/
public interface RolesJpaRepository extends JpaRepository<Roles,Integer> {
}
5.JpaSpecificationExecutor接口的使用
package com.kevin.dao;
import com.kevin.entity.Users;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
/**
* @author kevin
* @version 1.0
* @description JpaSpecificationExecutor的使用,提供多条件的支持,并且可以在查询中添加分页和排序
* @createDate 2019/3/21
*/
public interface UsersJpaSpecificationExecutor extends JpaRepository<Users, Integer>, JpaSpecificationExecutor<Users> {
}
以下的测试方法使用了SpringBoot中的Test
测试Repository中方法名称查询和@Query
package com.kevin.test;
import com.kevin.JpaApplication;
import com.kevin.dao.UsersJpaRepository;
import com.kevin.dao.UsersRepositoryByName;
import com.kevin.dao.UsersRepositoryQueryAnnotation;
import com.kevin.entity.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.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* @author kevin
* @version 1.0
* @description 测试Repository功能,方法名称命名与@Quert功能
* @createDate 2019/3/20
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = JpaApplication.class)
public class UsersRepositoryTest {
@Autowired
private UsersRepositoryByName usersRepositoryByName;
@Autowired
private UsersRepositoryQueryAnnotation usersRepositoryQueryAnnotation;
// Repository---方法名称命名测试,根据名字作为条件查询
@Test
public void testFindByName(){
List<Users> list = this.usersRepositoryByName.findByName("kevin");
for (Users user : list) {
System.out.println(user.toString());
}
}
// Repository---方法名称命名测试,根据名字和年龄作为条件查询
@Test
public void testFindByNameAndAge(){
List<Users> list = this.usersRepositoryByName.findByNameAndAge("kevin",22);
for (Users user : list) {
System.out.println(user.toString());
}
}
// Repository---方法名称命名测试,根据名字做通配符查询
@Test
public void testFindByNameLike(){
List<Users> list = this.usersRepositoryByName.findByNameLike("co%");
for (Users user : list) {
System.out.println(user.toString());
}
}
// Repository---@Quert测试,根据名字查询HQL
@Test
public void testQueryByNameUseHQL(){
List<Users> list = this.usersRepositoryQueryAnnotation.queryByNameUseHQL("coco");
for (Users user : list) {
System.out.println(user.toString());
}
}
// Repository---@Quert测试,根据名字查询SQL
@Test
public void testQueryByNameUseSQL(){
List<Users> list = this.usersRepositoryQueryAnnotation.queryByNameUseSQL("kevin");
for (Users user : list) {
System.out.println(user.toString());
}
}
// Repository---@Quert测试,根据id更新name
@Test
@Transactional //@Transactional与@Test一起使用时,会自动回滚
@Rollback(false) // 取消自动回滚
public void testUpdateUsersNameById(){
this.usersRepositoryQueryAnnotation.updateUsersNameById("tomcat",1);
}
}
测试CrudRepository接口
package com.kevin.test;
import com.kevin.JpaApplication;
import com.kevin.dao.UsersCrudRepository;
import com.kevin.entity.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.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.List;
/**
* @author kevin
* @version 1.0
* @description 测试CrudRepository,增删改查功能
* @createDate 2019/3/20
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = JpaApplication.class)
public class UsersCrudRepositoryTest {
@Autowired
private UsersCrudRepository usersCrudRepository;
// CrudRepository测试,新增功能
@Test
public void testCrudRepositorySave(){
Users user = new Users();
user.setAddress("上海");
user.setAge(22);
user.setName("java");
this.usersCrudRepository.save(user);
}
// CrudRepository测试,更新功能,save方法即是插入又是更新
@Test
public void testCrudRepositoryUpdate(){
Users user = new Users();
user.setAddress("上海");
user.setAge(22);
user.setName("scala");
user.setId(4);
this.usersCrudRepository.save(user);
}
// CrudRepository测试,查询功能,根据id查询
@Test
public void testCrudRepositoryFindById(){
Users user = this.usersCrudRepository.findById(1).get();
System.out.println(user.toString());
}
// CrudRepository测试,查询功能,查询全部
@Test
public void testCrudRepositoryFindAll(){
List<Users> users = (List<Users>) this.usersCrudRepository.findAll();
for (Users user:users) {
System.out.println(user);
}
}
// CrudRepository测试,删除功能,根据id删除
@Test
public void testCrudRepositoryDeleteById(){
this.usersCrudRepository.deleteById(5);
}
}
测试PagingAndSortingRepository接口
package com.kevin.test;
import com.kevin.JpaApplication;
import com.kevin.dao.UsersPagingAndSortingRepository;
import com.kevin.entity.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.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import java.util.List;
/**
* @author kevin
* @version 1.0
* @description 测试PagingAndSortRepository排序与分页功能
* @createDate 2019/3/20
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = JpaApplication.class)
public class UsersPagingAndSortingRepositoryTest {
@Autowired
private UsersPagingAndSortingRepository usersRepositoryPagingAndSorting;
// PagingAndSortingRepository 排序功能
@Test
public void testPagingAndSortingRepositorySort(){
// Order定义排序规则。降序
Order order = new Order(Direction.DESC,"id");
//Sort对象封装了排序规则
Sort sort = new Sort(order);
List<Users> list = (List<Users>)this.usersRepositoryPagingAndSorting.findAll(sort);
for (Users user:list) {
System.out.println(user.toString());
}
}
// PagingAndSortingRepository 分页功能
@Test
public void testPagingAndSortingRepositoryPaging(){
// Pageable:封装了分页的参数,当前页,每页显示的条数。注意:它的当前页从0开始
// PageRequest(page,size)page:当前页。size:每页显示的条数
Pageable pageable = new PageRequest(0,2);
Page<Users> list = this.usersRepositoryPagingAndSorting.findAll(pageable);
System.out.println("总条数:"+list.getTotalElements());
System.out.println("总页数:"+list.getTotalPages());
for (Users user:list) {
System.out.println(user.toString());
}
}
// PagingAndSortingRepository 排序+分页功能
@Test
public void testPagingAndSortingRepositorySortAndPaging(){
// 根据id进行升序排序
Sort sort = new Sort(new Order(Direction.ASC,"id"));
// 根据0开始显示两条数据,并排序
Pageable pageable = new PageRequest(0,2,sort);
Page<Users> list = this.usersRepositoryPagingAndSorting.findAll(pageable);
System.out.println("总条数:"+list.getTotalElements());
System.out.println("总页数:"+list.getTotalPages());
for (Users user:list) {
System.out.println(user.toString());
}
}
}
测试JPARepository接口
package com.kevin.test;
import com.kevin.JpaApplication;
import com.kevin.entity.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.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.List;
/**
* @author kevin
* @version 1.0
* @description 测试JpaRepository,具体功能最多
* @createDate 2019/3/21
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = JpaApplication.class)
public class UsersJpaRepositoryTest {
@Autowired
private com.kevin.dao.UsersJpaRepository usersJpaRepository;
// JpaRepository 新增或更新功能,save方法会判断,如果数据库没有该条数据则插入,存在则更新
@Test
public void testSave(){
Users users = new Users();
users.setAddress("广州");
users.setAge(22);
users.setName("cnq");
this.usersJpaRepository.save(users);
}
// JpaRepository 查询功能,根据id查询
@Test
public void testFindById(){
Users user = this.usersJpaRepository.findById(1).get();
System.out.println(user);
}
// JpaRepository 查询功能,查询全部
@Test
public void testFindAll(){
List<Users> list = this.usersJpaRepository.findAll();
for (Users user:list) {
System.out.println(user);
}
}
// JpaRepository 删除功能,根据id查询
@Test
public void testDeleteById(){
this.usersJpaRepository.deleteById(6);
}
// JpaRepository 删除功能,根据对象删除
@Test
public void testDelete(){
Users users = new Users();
users.setAddress("广州");
users.setAge(22);
users.setName("cnq");
users.setId(6);
this.usersJpaRepository.delete(users);
}
}
测试JpaSpecificationExcutor接口
package com.kevin.test;
import com.kevin.JpaApplication;
import com.kevin.dao.UsersJpaSpecificationExecutor;
import com.kevin.entity.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.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
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;
/**
* @author kevin
* @version 1.0
* @description 测试JpaSpecificationExecutor功能,多条件查询
* @createDate 2019/3/21
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = JpaApplication.class)
public class UsersJpaSpecificationExecutorTest {
@Autowired
private UsersJpaSpecificationExecutor usersJpaSpecificationExecutor;
// JpaSpecificationExecutor 单条件查询
@Test
public void testJpaSpecificationExecutor1(){
// Specification<Users>:用于封装查询条件
Specification<Users> specification = 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) {
// 定义查询条件:where name = 'coco'
// cb.equal(arg0,arg1) 参数一:查询的属性。参数二:条件的值
Predicate pre = cb.equal(root.get("name"), "coco");
return pre;
}
};
List<Users> list = this.usersJpaSpecificationExecutor.findAll(specification);
for (Users user:list) {
System.out.println(user);
}
}
// JpaSpecificationExecutor 多条件查询,方式一
@Test
public void testJpaSpecificationExecutor2(){
// Specification<Users>:用于封装查询条件
Specification<Users> specification = 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) {
// 定义查询条件:where name = 'coco' and age = 20
// cb.equal(arg0,arg1) 参数一:查询的属性。参数二:条件的值
List<Predicate> list = new ArrayList<Predicate>();
list.add(cb.equal(root.get("name"), "coco"));
list.add(cb.equal(root.get("age"), "20"));
// 定义Predicate[],将list转为Predicate[]后返回
Predicate[] arr = new Predicate[list.size()];
return cb.and( list.toArray(arr));
}
};
List<Users> list = this.usersJpaSpecificationExecutor.findAll(specification);
for (Users user:list) {
System.out.println(user);
}
}
// JpaSpecificationExecutor 多条件查询,方式二
@Test
public void testJpaSpecificationExecutor3(){
// Specification<Users>:用于封装查询条件
Specification<Users> specification = 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) {
// cb.equal(arg0,arg1) 参数一:查询的属性。参数二:条件的值
// 定义查询条件:where name = 'coco' and age = 20 or id = 1
return cb.or(cb.and(cb.equal(root.get("name"), "coco"), cb.equal(root.get("age"), "20")),
cb.equal(root.get("id"), "1")); // 先与后或
//return cb.and(cb.equal(root.get("name"), "coco"),cb.equal(root.get("age"), "20")); // 与
//return cb.or(cb.equal(root.get("name"), "coco"),cb.equal(root.get("age"), "20")); // 或
}
};
// 如果需要做降序排序
Sort sort = new Sort(new Sort.Order(Sort.Direction.DESC,"id"));
// 根据条件查询
List<Users> list = this.usersJpaSpecificationExecutor.findAll(specification,sort);
for (Users user:list) {
System.out.println(user);
}
}
}
测试一对多
package com.kevin.test;
import com.kevin.JpaApplication;
import com.kevin.dao.UsersJpaRepository;
import com.kevin.entity.Roles;
import com.kevin.entity.Users;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
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.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author kevin
* @version 1.0
* @description 测试一对多关联
* @createDate 2019/3/21
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = JpaApplication.class)
public class OneToManyTest {
@Autowired
private UsersJpaRepository usersJpaRepository;
// 一对多关联关系 添加功能
@Test
public void testSave(){
// 创建一个用户
Users users = new Users();
users.setAddress("深圳");
users.setAge(24);
users.setName("老杨");
// 创建一个角色
Roles roles = new Roles();
roles.setRolename("管理员");
// 关联
roles.getUsers().add(users);
users.setRoles(roles);
// 保存,sql语句会先操作roles角色表再操作users用户表
this.usersJpaRepository.save(users);
}
// 一对多关联关系 查询功能
@Test
public void testFind(){
// 根据id查出用户
Users findById = this.usersJpaRepository.findById(7).get();
System.out.println(findById);
// 级联获取到用户的角色
Roles roles = findById.getRoles();
System.out.println(roles.getRolename());
}
}
测试多对多
package com.kevin.test;
import com.kevin.JpaApplication;
import com.kevin.dao.RolesJpaRepository;
import com.kevin.entity.Menus;
import com.kevin.entity.Roles;
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.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.Set;
/**
* @author kevin
* @version 1.0
* @description 测试多对多关联
* @createDate 2019/3/21
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = JpaApplication.class)
public class ManyToManyTest {
@Autowired
private RolesJpaRepository rolesJpaRepository;
// 多对多关联关系 添加功能
@Test
public void testSave(){
// 创建角色对象
Roles r = new Roles();
r.setRolename("项目经理");
// 创建菜单对象
Menus menus = new Menus();
menus.setMenusname("xxx管理系统");
menus.setFatherid(0);
Menus menus2 = new Menus();
menus2.setMenusname("项目管理");
menus2.setFatherid(1);
// 关联
r.getMenus().add(menus);
r.getMenus().add(menus2);
menus.getRoles().add(r);
menus2.getRoles().add(r);
// 保存
this.rolesJpaRepository.save(r);
}
// 多对多关联关系 查询功能
@Test
public void testFind(){
Roles roles = this.rolesJpaRepository.findById(2).get();
System.out.println(roles.getRolename());
Set<Menus> menus = roles.getMenus();
for (Menus menus2:menus) {
System.out.println(menus2);
}
}
}