SpringBoot整合SpringDataJPA
一、SpringBootData JPA介绍
SpringData:其实SpringData就是Spring提供了一个操作数据的框架。而SpringData JPA只是SpringData框架下的一个基于JPA标准操作数据的模块。
SpringData JPA:基于JPA的标准数据进行操作。简化操作持久层的代码。只需要编写接口就可以。
二、SpringBoot整合SpringData JPA
1、导入maven依赖
在原有的SprigBoot的maven依赖的基础下加上JPA的依赖
2、application.properties文件中添加配置
3、实体类
import javax.persistence.*; @Entity @Table(name="t_users") 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; public Roles getRoles() { return roles; } public void setRoles(Roles roles) { this.roles = roles; } 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; } @Override public String toString() { final StringBuffer sb = new StringBuffer("Users{"); sb.append("id=").append(id); sb.append(", name='").append(name).append('\''); sb.append(", age=").append(age); sb.append(", address='").append(address).append('\''); sb.append(", roles=").append(roles); sb.append('}'); return sb.toString(); } }
4、编写Dao接口
import org.springframework.data.jpa.repository.JpaRepository; import com.bjsxt.pojo.Users; /** * 参数一 T :当前需要映射的实体 * 参数二 ID :当前映射的实体中的OID的类型 * */ public interface UsersRepository extends JpaRepository<Users,Integer> { }
6、在pom文件中添加测试启动器的坐标
7、测试
三、SpringBoot JPA提供的核心接口
1、Repository接口
2、CrudRepository接口
3、PagingAndSortingRepository接口
4、JpaRepository接口
5、JPASpecificationExecutor接口
四、Repository接口的使用
提供了方法名称命名查询方式
提供了基于@Query注解查询与更新
1、dao层接口(方法名称命名查询方式)
import com.bjsxt.pojo.Users; import org.springframework.data.repository.Repository; import java.util.List; /** * 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注解查询与更新)
import com.bjsxt.pojo.Users; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import java.util.List; /** * 〈一句话功能简述〉<br> * Repository @Query * * @author admin * @create 2019/5/22 * @since 1.0.0 */ 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 com.bjsxt.pojo.Users; import org.springframework.data.repository.CrudRepository; public interface UsersRepositoryCrudRepository extends CrudRepository<Users,Integer> { }
2、测试
@Test public void testCrudRepositorySave() { Users users=new Users(); users.setName("青衫"); users.setAge(30); users.setAddress("湖南怀化"); this.usersRepositoryCrudRepository.save(users); } @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 com.bjsxt.pojo.Users; 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 S 7ff7 ort.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 com.bjsxt.pojo.Users; 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、实体类
import javax.persistence.*; import java.util.HashSet; import java.util.Set; /** * 〈一句话功能简述〉<br> * 〈〉 * * @author admin * @create 2019/5/23 * @since 1.0.0 */ @Entity @Table(name = "t_roles") 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<>(); 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; } }
package com.bjsxt.pojo; import javax.persistence.*; @Entity @Table(name="t_users") 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; public Roles getRoles() { return roles; } public void setRoles(Roles roles) { this.roles = roles; } 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; } @Override public String toString() { final StringBuffer sb = new StringBuffer("Users{"); sb.append("id=").append(id); sb.append(", name='").append(name).append('\''); sb.append(", age=").append(age); sb.append(", address='").append(address).append('\''); sb.append(", roles=").append(roles); sb.append('}'); return sb.toString(); } }
3、dao层接口编写
/** * 参数一 T :当前需要映射的实体 * 参数二 ID :当前映射的实体中的OID的类型 * */ public interface UsersRepository extends JpaRepository<Users,Integer> { }
4、测试
/** * 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.App; 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、实体类
/** * Copyright (C), 2015-2019, XXX有限公司 * FileName: Menus * Author: admin * Date: 2019/5/23 14:06 * Description: * History: * <author> <time> <version> <desc> * 作者姓名 修改时间 版本号 描述 */ package com.bjsxt.pojo; import javax.persistence.*; import java.util.HashSet; import java.util.Set; /** * 〈一句话功能简述〉<br> * 〈〉 * * @author admin * @create 2019/5/23 * @since 1.0.0 */ @Entity @Table(name = "t_menus") 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<>(); public Set<Roles> getRoles() { return roles; } public void setRoles(Set<Roles> roles) { this.roles = roles; } 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; } @Override public String toString() { final StringBuffer sb = new StringBuffer("Menus{"); sb.append("menusId=").append(menusId); sb.append(", menusName='").append(menusName).append('\''); sb.append(", menusUrl='").append(menusUrl).append('\''); sb.append(", fatherId=").append(fatherId); sb.append('}'); return sb.toString(); } }
/** * Copyright (C), 2015-2019, XXX有限公司 * FileName: Roles * Author: admin * Date: 2019/5/23 11:02 * Description: * History: * <author> <time> <version> <desc> * 作者姓名 修改时间 版本号 描述 */ package com.bjsxt.pojo; import javax.persistence.*; import java.util.HashSet; import java.util.Set; /** * 〈一句话功能简述〉<br> * 〈〉 * * @author admin * @create 2019/5/23 * @since 1.0.0 */ @Entity @Table(name = "t_roles") 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<>(); @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<>(); public Set<Menus> getMenus() { return menus; } public void setMenus(Set<Menus> menus) { this.menus = menus; } 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; } }
7、dao层接口
/** * Copyright (C), 2015-2019, XXX有限公司 * FileName: RolesRepository * Author: admin * Date: 2019/5/23 14:21 * Description: * History: * <author> <time> <version> <desc> * 作者姓名 修改时间 版本号 描述 */ package com.bjsxt.dao; import com.bjsxt.pojo.Roles; import org.springframework.data.jpa.repository.JpaRepository; /** * 〈一句话功能简述〉<br> * 〈〉 * * @author admin * @create 2019/5/23 * @since 1.0.0 */ 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.App; 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); } } }
- spring boot 整合spring data jpa
- 2.SpringBoot整合SpringDataJpa
- SpringBoot整合Spring Data JPA、MySQL、Druid并使用Mockito实现单元测试
- spring boot 整合 spring data jpa
- SpringBoot 2.x(三):搭建开发环境(整合Spring Data JPA)
- SpringBoot-整合-SpringData jpa -简单实用(8)
- springBoot整合springData Jpa
- springboot干货——(七)springboot整合Spring Data JPA
- springboot整合spring data jpa
- springBoot入门总结(三)整合SpringDataJPA
- Springboot整合springdata JPA
- spring-boot、spring-data-jpa、hibernate整合
- springboot整合spring data jpa 动态查询
- Spring Boot整合Spring MVC、Spring、Spring Data JPA(Hibernate)
- spring boot 整合spring data jpa
- SpringBoot整合SpringData(JPA)
- springboot 入门教程(6)--- 整合Spring data JPA实现CRUD(附源码)
- springboot后台服务搭建(三 整合mysql、spring-data-jpa)
- Spring Boot + Spring Data JPA 项目整合开发记录(持续更新)
- Spring Boot1.52 Spring Security Spring Data Jpa 整合