SpringBoot中整合SpringDataJPA

一、SpringBootData JPA介绍

SpringData:其实SpringData就是Spring提供了一个操作数据的框架。而SpringData JPA只是SpringData框架下的一个基于JPA标准操作数据的模块
SpringData JPA:基于JPA的标准数据进行操作。简化操作持久层的代码。只需要编写接口就可以

二、SpringBoot整合SpringData JPA

1、导入maven依赖

在原有的SprigBoot的maven依赖的基础上加上JPA的依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

2、application.properties文件中添加配置

spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

spring.jpa.hibernate.ddl-auto=update
表示为已存在的表添加以前没有的属性,但不替换已经存在的表的数据类型和值
spring.jpa.show-sql=true
表示打印执行sql

3、实体类

@Entity
@Table(name = "t_users")
@Data
@ToString
public class Users {
    @Id    //主键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)    //表示多方
    @JoinColumn(name = "role_id")    //维护一个外键,外键在Users一侧
    private Roles roles;
}

4、编写Dao接口

import org.springframework.data.jpa.repository.JpaRepository;
import com.bjsxt.pojo.Users;
/**
 * 参数一 T :当前需要映射的实体
 * 参数二 ID :当前映射的实体中的OID的类型
 *
 */
public interface UsersRepository extends JpaRepository<Users,Integer> {
}

三、SpringBoot JPA提供的核心接口

  1. Repository接口
  2. CrudRepository接口
  3. PagingAndSortingRepository接口
  4. JpaRepository接口
  5. JPASpecificationExecutor接口

1、Repository接口的使用

提供了 方法名称命名 \color{#FF0000}{方法名称命名} 方法名称命名查询方式
提供了基于 @ Q u e r y 注解 \color{#FF0000}{@Query注解} @Query注解查询与更新

1、dao层接口(方法名称命名查询方式)

/**
 * Repository接口方法名称命名查询
 */
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);
}

2、测试

/**
 * Repository
 */
@Test
public void UsersRepositoryByName(){
	List<Users> list=this.usersRepositoryByName.findByName("张三");
	for (Users users:list){
		System.out.println(users);
	}
}
@Test
public void findByNameAndAge(){
	List<Users> list=this.usersRepositoryByName.findByNameAndAge("张三",20);
	for (Users users:list){
		System.out.println(users);
	}
}
@Test
public void findByNameLike() {
	List<Users> list = this.usersRepositoryByName.findByNameLike("张%");
	for (Users users : list) {
		System.out.println(users);
	}
}

3、dao层接口编写(基于@Query注解查询与更新)

public interface UsersRepositoryQueryAnnotation extends JpaRepository<Users,Integer> {
    @Query("from Users where name = ?")
    List<Users> queryByNameUseHQL(String name);
    @Query(value = "select * from t_user where name=?",nativeQuery = true)
    List<Users> queryByNameUseSQL(String name);
    @Query("update Users set name=? where id=?")
    @Modifying  //需要执行一个更新操作
    void updateUsersNameById(String name,Integer id);
}

4、测试

/**
 * Repository--@Query测试
 */
@Test
public void testQueryByNameUseSQL() {
	List<Users> list = this.usersRepositoryQueryAnnotation.queryByNameUseSQL("张三");
	for (Users users : list) {
		System.out.println(users);
	}
}
/**
 * Repository--@Query测试
 */
@Test
@Transactional //@Transactional与@Test 一起使用时 事务是自动回滚的。
@Rollback(false) //取消自动回滚
public void testUpdateUsersNameById() {
	this.usersRepositoryQueryAnnotation.updateUsersNameById("张三三", 1);
}

2、CrudRepository接口的使用

CrudRepository接口,主要是完成一些增删改查的操作。注意:CrudRepository接口继承了Repository接口

1、编写dao层接口

import org.springframework.data.repository.CrudRepository;
public interface UsersRepositoryCrudRepository extends CrudRepository<Users,Integer> {
}

2、测试

@Test
public void testCrudRepositoryUpdate() {
	Users users=new Users();
	users.setId(4);
	users.setName("青");
	users.setAge(18);
	users.setAddress("怀化");
	this.usersRepositoryCrudRepository.save(users);
}
@Test
public void testCrudRepositoryFindOne() {
	Users users=this.usersRepositoryCrudRepository.findOne(4);
	System.out.println(users);
}
@Test
public void testCrudRepositoryFindAll() {
	List<Users> list= (List<Users>) this.usersRepositoryCrudRepository.findAll();
	for (Users user:list){
		System.out.println(user);
	}
}
@Test
public void testCrudRepositoryDeleteById() {
	this.usersRepositoryCrudRepository.delete(4);
}

3、PagingAndSortingRepository接口的使用

该接口提供了分页与排序的操作,注意:该接口继承了CrudRepository接口

1、编写dao层

import org.springframework.data.repository.PagingAndSortingRepository;
public interface UsersRepositoryPagingAndSorting extends PagingAndSortingRepository<Users,Integer> {
}

2、测试

@Test
public void testPagingAndSortingRepositorySort() {
	//Order	定义了排序规则
	Sort.Order order=new Sort.Order(Sort.Direction.DESC,"id");
	//Sort对象封装了排序规则
	Sort sort=new Sort(order);
	List<Users> list= (List<Users>) this.usersRepositoryPagingAndSorting.findAll(sort);
	for (Users users:list){
		System.out.println(users);
	}
}
@Test
public void testPagingAndSortingRepositoryPaging() {
	//Pageable:封装了分页的参数,当前页,煤业显示的条数。注意:它的当前页是从0开始
	//PageRequest(page,size):page表示当前页,size表示每页显示多少条
	Pageable pageable=new PageRequest(1,2);
	Page<Users> page=this.usersRepositoryPagingAndSorting.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);
	}
}
@Test
public void testPagingAndSortingRepositorySortAndPaging() {
	Sort sort=new Sort(new Sort.Order(Sort.Direction.DESC,"id"));
	Pageable pageable=new PageRequest(0,2,sort);
	Page<Users> page=this.usersRepositoryPagingAndSorting.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);
	}
}

4、JpaRepository接口

该接口继承了PagingAndSortingRepository。对继承的父接口中方法的返回值进行适配

1、dao层接口编写

/**
 * 参数一 T :当前需要映射的实体
 * 参数二 ID :当前映射的实体中的OID的类型
 *
 */
public interface UsersRepository extends JpaRepository<Users,Integer> {
}

2、测试

/**
* JpaRepository	排序测试
 */
@Test
public void testJpaRepositorySort() {
	//Order	定义了排序规则
	Sort.Order order=new Sort.Order(Sort.Direction.DESC,"id");
	//Sort对象封装了排序规则
	Sort sort=new Sort(order);
	List<Users> list= this.usersRepository.findAll(sort);
	for (Users users:list){
		System.out.println(users);
	}
}

5、JPASpecificationExecutor接口

该接口主要是提供了多条件查询的支持,并且可以在查询中添加排序与分页。注意JPASpecificationExecutor是单独存在的。完全独立

1、dao层接口编写

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
/**
 * 〈一句话功能简述〉<br> 
 *  JpaSpecificationExecutor
 *
 * @author admin
 * @create 2019/5/23
 * @since 1.0.0
 */
public interface UserRepositorySpecification extends JpaRepository<Users,Integer>,JpaSpecificationExecutor<Users> {
}

2、测试

/**
 * JpaSpecificationExecutor		单条件查询
 */
@Test
public void testJpaSpecificationExecutor1() {
	/**
	 * Specification:用于封装查查询条件
	 */
	Specification<Users> spec=new Specification<Users>() {
		//Predicate:封装了单个查询条件
		/**
		 * @param root		对查询对象属性的封装
		 * @param criteriaQuery	封装了我们要执行的查询中的各个部分的信息,select from order
		 * @param criteriaBuilder	查询条件的构造器
		 * @return
		 */
		@Override
		public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
			//where name="张三"
			/**
			 * 参数一:查询的属性
			 * 参数二:条件的值
			 */
			Predicate predicate=criteriaBuilder.equal(root.get("name"),"张三");
			return predicate;
		}
	};
	List<Users> list=this.userRepositorySpecification.findAll(spec);
	for (Users users:list){
		System.out.println(users);
	}
}
/**
 * JpaSpecificationExecutor		多条件查询方式一
 */
@Test
public void testJpaSpecificationExecutor2() {
	/**
	 * Specification:用于封装查查询条件
	 */
	Specification<Users> spec=new Specification<Users>() {
		//Predicate:封装了单个查询条件
		/**
		 * @param root		对查询对象属性的封装
		 * @param criteriaQuery	封装了我们要执行的查询中的各个部分的信息,select from order
		 * @param criteriaBuilder	查询条件的构造器
		 * @return
		 */
		@Override
		public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
			//where name="张三" and age=20
			/**
			 * 参数一:查询的属性
			 * 参数二:条件的值
			 */
			List<Predicate> list=new ArrayList<>();
			list.add(criteriaBuilder.equal(root.get("name"),"张三"));
			list.add(criteriaBuilder.equal(root.get("age"),20));
			Predicate[] arr=new Predicate[list.size()];
			return criteriaBuilder.and(list.toArray(arr));
		}
	};
	List<Users> list=this.userRepositorySpecification.findAll(spec);
	for (Users users:list){
		System.out.println(users);
	}
}
/**
 * JpaSpecificationExecutor		多条件查询方式二
 */
@Test
public void testJpaSpecificationExecutor3() {
	/**
	 * Specification:用于封装查查询条件
	 */
	Specification<Users> spec=new Specification<Users>() {
		//Predicate:封装了单个查询条件
		/**
		 * @param root		对查询对象属性的封装
		 * @param criteriaQuery	封装了我们要执行的查询中的各个部分的信息,select from order
		 * @param criteriaBuilder	查询条件的构造器
		 * @return
		 */
		@Override
		public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
			//where name="张三" and age=20
			/**
			 * 参数一:查询的属性
			 * 参数二:条件的值
			 */
			/*List<Predicate> list=new ArrayList<>();
			list.add(criteriaBuilder.equal(root.get("name"),"张三"));
			list.add(criteriaBuilder.equal(root.get("age"),20));
			Predicate[] arr=new Predicate[list.size()];*/
			//(name='张三' and age=20) or id=2
			return criteriaBuilder.or(criteriaBuilder.and(criteriaBuilder.equal(root.get("name"),"张三"),criteriaBuilder.equal(root.get("age"),20)),criteriaBuilder.equal(root.get("id"),1));
		}
	};
	Sort sort=new Sort(new Sort.Order(Sort.Direction.DESC,"id"));
	List<Users> list=this.userRepositorySpecification.findAll(spec,sort);
	for (Users users:list){
		System.out.println(users);
	}
}

6、关联映射操作

1、一对多的关联关系

  • 需求:角色与用户的一对多的关联关系
  • 角色:一方
  • 用户:多方

2、实体类

/**
 * @author xhy
 * @version 1.0
 * @date 2021/6/28 17:14
 * @description
 */
@Entity
@Table(name = "t_roles")
@Data
@ToString
public class Roles {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "role_id")
    private Integer roleId;
    @Column(name = "role_name")
    private String roleName;
    @OneToMany(mappedBy = "roles")
    private Set<Users> users=new HashSet<>();
}
@Entity
@Table(name = "t_roles")
@Data
@ToString
public class Menus {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "menus_id")
    private Integer menusId;
    @Column(name = "menus_name")
    private String menusName;
    @Column(name = "menus_url")
    private String menusUrl;
    @Column(name = "father_id")
    private Integer fatherId;
    @ManyToMany(mappedBy = "menus")
    private Set<Roles> roles = new HashSet<>();
}

3、dao层接口编写

/**
 * 参数一 T :当前需要映射的实体
 * 参数二 ID :当前映射的实体中的OID的类型
 *
 */
public interface UsersRepository extends JpaRepository<Users,Integer> {
}

4、测试

package com.bjsxt.test;
import com.bjsxt.dao.RolesRepository;
import com.bjsxt.pojo.Menus;
import com.bjsxt.pojo.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;
/**
 * 〈一句话功能简述〉<br> 
 * 多对多的关联关系的测试
 *  * @author admin
 * @create 2019/5/23
 * @since 1.0.0
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = App.class)
public class ManyToManyTest {

    @Autowired
    private RolesRepository rolesRepository;
    /**
     * 添加测试
     */
    @Test
    public void testSave(){
        //创建角色对象
        Roles roles=new Roles();
        roles.setRoleName("项目经理");
        //创建菜单对象
        Menus menus=new Menus();
        menus.setMenusName("xxxx管理系统");
        menus.setFatherId(0);
        Menus menus2=new Menus();
        menus2.setFatherId(1);
        menus2.setMenusName("项目管理");
        //关联
        roles.getMenus().add(menus);
        roles.getMenus().add(menus2);
        menus.getRoles().add(roles);
        menus2.getRoles().add(roles);
        //保存
        this.rolesRepository.save(roles);
    }
    /**
     * 查询操作
     */
    @Test
    public void testFind(){
        Roles roles=this.rolesRepository.findOne(2);
        System.out.println(roles.getRoleName());
        Set<Menus> menus=roles.getMenus();
        for (Menus menu:menus){
            System.out.println(menu);
        }
    }
}

5、多对多的关联关系

  • 角色与菜单多对多关联关系
  • 菜单:多方
  • 角色:多方

6、在Roles中添加以下内容

@ManyToMany(cascade = CascadeType.PERSIST,fetch = FetchType.EAGER)
  //映射中间表  joinColumns:当前表中的主键关联中间表的外键
  @JoinTable(name = "t_roles_menus",joinColumns =@JoinColumn(name = "role_id"),inverseJoinColumns = @JoinColumn(name = "menu_id"))
  private Set<Menus> menus=new HashSet<>();

7、dao层接口

import org.springframework.data.jpa.repository.JpaRepository;
public interface RolesRepository extends JpaRepository<Roles,Integer> {
}

8、测试

/**
 * Copyright (C), 2015-2019, XXX有限公司
 * FileName: ManyToManyTest
 * Author:   admin
 * Date:     2019/5/23 14:19
 * Description:
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.bjsxt.test;
import com.bjsxt.dao.RolesRepository;
import com.bjsxt.pojo.Menus;
import com.bjsxt.pojo.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;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = App.class)
public class ManyToManyTest {

    @Autowired
    private RolesRepository rolesRepository;
    /**
     * 添加测试
     */
    @Test
    public void testSave(){
        //创建角色对象
        Roles roles=new Roles();
        roles.setRoleName("项目经理");
        //创建菜单对象
        Menus menus=new Menus();
        menus.setMenusName("xxxx管理系统");
        menus.setFatherId(0);
        Menus menus2=new Menus();
        menus2.setFatherId(1);
        menus2.setMenusName("项目管理");
        //关联
        roles.getMenus().add(menus);
        roles.getMenus().add(menus2);
        menus.getRoles().add(roles);
        menus2.getRoles().add(roles);
        //保存
        this.rolesRepository.save(roles);
    }
    /**
     * 查询操作
     */
    @Test
    public void testFind(){
        Roles roles=this.rolesRepository.findOne(2);
        System.out.println(roles.getRoleName());
        Set<Menus> menus=roles.getMenus();
        for (Menus menu:menus){
            System.out.println(menu);
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rsun04551

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值