SpringDataJPA快速入门

SpringDataJPA快速入门

前言

之前在学习 SpringBoot 框架的时候,使用到了 SpringData JPA,但是当时只是简单的查询,没有用到稍微复杂的查询。

JPA 的 JPQL 语法规则对于简单的查询实属利器,大大加快了开发速度。不久前,在公司将用户推荐功能单独抽取出为一个独立项目,由于公司一直沿用的底层框架太老,只能使用 JDK1.6,JDK 1.9都出来了,实在不能忍?,果断引入了 SpringData JPA。

然后最近公司其他同事接手了该项目,但是不太了解 SpringData JPA 的使用,于是有了此文,不会就可以直接让他看本篇博客了哈哈。

环境准备

这里不讲解 SpringData JPA 与框架的整合,只讲解 JPA 语法的使用

Entity 实体类

@Entity // 表示为一个实体类
@Table("employee") // 表名 public class Employee { @Id //主键标识注解 @GeneratedValue // 主键生成方式 private Integer id; private String name; private Integer age; //Getter/Setter省略 }

Repository 接口

// 继承 JpaRepository 接口,第一个参数为查询的实体类,第二个为实体类的主键数据类型
public interface EmployeeRepository extends JpaRepository<Employee, Integer>{ }

插入测试数据

@Test
public void testAdd() throws Exception { for (int i = 0; i < 100; i++) { Employee employee = new Employee(); employee.setAge(i); employee.setName("test" + i); employeeRepository.save(employee); } }

JPA 查询语法讲解

使用 JPQL 进行查询

// 新增/更新
employeeRepository.save(employee);

// where name = ?1
employeeRepository.findByName("test1")

// where name = ?1 and age = ?2 employeeRepository.findByNameAndAge("test1", 20); // where age between ?1 and ?2 【包含头尾】 List<Employee> byAgeBetween = employeeRepository.findByAgeBetween(10, 16); // where age < ?1 List<Employee> list = employeeRepository.findByAgeLessThan(10); // where age > ?1 List<Employee> list = employeeRepository.findByAgeGreaterThan(90); // where name is null 【不包含为空字符串的数据】 List<Employee> list = employeeRepository.findByNameIsNull(); // where name like "test9%" 以test9为开头的name List<Employee> list = employeeRepository.findByNameLike("test9%"); 或者 List<Employee> employees = employeeRepository.findByNameStartingWith("test") // where name like "test_" 以test开头,且后面只模糊匹配一位 List<Employee> list2 = employeeRepository.findByNameLike("test_"); // where name like "%6" 模糊匹配以6结尾的 List<Employee> employees = employeeRepository.findByNameEndingWith(6) // where name in (?1, ?2) List<String> names = Arrays.asList("test1", "test2"); List<Employee> employees = employeeRepository.findByNameIn(names); // where age <> ?1 List<Employee> employees = employeeRepository.findByAgeNot(99); // where name = ?1 order by age desc List<Employee> findByNameOrderByAgeDesc(String name); 

使用自定义 Sql 以及 原生 Sql 查询

/** EmployeeRepository.java 添加方法 */

// 根据姓名与年龄查找,[通过占位符获取参数值]
@Query("select o from Employee o where name = ?1 and age = ?2") List<Employee> queryEmployeeByParams(String name, Integer age); // 根据姓名与年龄查找,[通过命名参数获取参数值],必须使用 @Param 注解 @Query("select o from Employee o where name = :name and age = :age") List<Employee> queryEmployeeByParams2(@Param("name") String name, @Param("age") Integer age); // 原生SQL,与上面不同的是,上面使用的是对象名称以及对象属性名称,Native SQL使用数据库表名以及字段名 @Query(nativeQuery = true, value = "select * from employee where name = :name and age = :age") List<Employee> queryEmployeeByParams3(@Param("name") String name, @Param("age") Integer age); 

JPA 更新操作

/** 需要搭配使用 @Query 与 @Modifying 和 @Transactional 注解使用*/ @Modifying @Query("update Employee o set o.age = ?2 where o.id = ?1") Integer updateAge(Integer id, Integer age); 

在 Service 层调用

@Autowired
private EmployeeRepository employeeRepository;

@Transactional // 必须开启事务 public void update(Integer id, Integer age) { employeeRepository.save(id, age); }

分页查询

// EmployeeRepository 接口定义
Page<Employee> findByNameStartingWith(String name, Pageable pageable); // 测试类 EmployeeRepositoryTest.java // 普通分页查询 @Test public void testFindByNameStartingWith() { // 注意 page 从 0 开始 Pageable request = new PageRequest(0, 10); Page<Employee> result = employeeRepository.findByNameStartingWith("test", request); for (Employee employee : result.getContent()) { System.out.println(employee); } } // 带排序条件的分页查询 @Test public void testFindByNameStartingWith() { Sort.Order order = new Sort.Order(Sort.Direction.DESC, "id"); Sort sort = new Sort(order); Pageable request = new PageRequest(0, 10, sort); Page<Employee> result = employeeRepository.findByNameStartingWith("test", request); for (Employee employee : result.getContent()) { System.out.println(employee); } }

动态 SQL 查询

在 Java 开发中,动态 SQL 是必不可少的,JPA 也可以实现,Repository 多继承一个接口 JpaSpecificationExecutor 即可。

// 修改之前的 EmployeeRepository, 使其多继承 JpaSpecificationExecutor 接口
public interface EmployeeRepository extends JpaRepository<Employee, Integer>, JpaSpecificationExecutor<Employee>{ // ...... } Pageable request = new PageRequest(0, 10); Specification<Employee> specification = new Specification<Employee>() { public Predicate toPredicate(Root<Employee> root, CriteriaQuery<?> query, CriteriaBuilder cb) { Path<Integer> path = root.get("age"); return cb.gt(path, 50); } }; Page<Employee> all = employeeRepository.findAll(specification, request);

后记

这里感谢一下慕课网,快速入门多亏了 imooc 上的课程。

参考课程:

  • https://www.imooc.com/learn/821

转载于:https://www.cnblogs.com/zt007/p/11578445.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值