SpringBoot中整合SpringDataJPA

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

一、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

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提供的核心接口

Repository接口

CrudRepository接口

PagingAndSortingRepository接口

JpaRepository接口

JPASpecificationExecutor接口

四、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);
}

五、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);
}

六、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);
  }
}

七、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);
  }
}

八、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);
  }
}

九、关联映射操作

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);
        }
    }
}


目录
相关文章
|
10月前
|
JSON Java 数据库
SpringBoot整合SpringDataJPA
SpringBoot整合SpringDataJPA
85 0
|
SQL 前端开发 Java
基于Springboot+SpringDataJpa+Mysql智能停车管理系统
基于Springboot+SpringDataJpa+Mysql智能停车管理系统
199 0
基于Springboot+SpringDataJpa+Mysql智能停车管理系统
|
SQL 设计模式 JSON
基于SpringBoot+SpringDataJPA+Mysql的课表排课及实验室机房管理系统
基于SpringBoot+SpringDataJPA+Mysql的课表排课及实验室机房管理系统
217 0
基于SpringBoot+SpringDataJPA+Mysql的课表排课及实验室机房管理系统
|
Java 测试技术 Spring
SpringBoot整合SpringDataJPA
通过前面多篇文件对SpringDataJPA的介绍,相信大家应该已经对SpringDataJPA很熟悉了,使用起来还是蛮方便的,只是在整合的时候需要添加大量的配置文件,本文来给大家介绍下SpringBoot整合SpringDataJPA的过程
SpringBoot整合SpringDataJPA
|
1天前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的宠物服务中心的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的宠物服务中心的详细设计和实现(源码+lw+部署文档+讲解等)
17 6
基于SpringBoot+Vue+uniapp的宠物服务中心的详细设计和实现(源码+lw+部署文档+讲解等)
|
1天前
|
JavaScript Java 测试技术
基于SpringBoot+Vue的房地产销售管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue的房地产销售管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
18 8
|
1天前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的房地产销售管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的房地产销售管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
17 7
|
1天前
|
JavaScript Java 测试技术
基于SpringBoot+Vue的成都某幼儿园兴趣班报名管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue的成都某幼儿园兴趣班报名管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
23 7
|
1天前
|
JavaScript Java 测试技术
基于SpringBoot+Vue的果蔬种植销售一体化服务平台的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue的果蔬种植销售一体化服务平台的详细设计和实现(源码+lw+部署文档+讲解等)
22 6
|
1天前
|
JavaScript Java 测试技术
基于SpringBoot+Vue的护肤品推荐系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue的护肤品推荐系统的详细设计和实现(源码+lw+部署文档+讲解等)
14 6