SpringBoot总结之Spring Data Jpa
一、Spring Data Jpa简介
JPA(Java Persistence API)定义了一系列对象持久化的标准,目前实现这一规范的产品有Hibernate、TopLink等。
Spring Data JPA 框架,主要针对的就是 Spring 唯一没有简化到的业务逻辑代码,至此,开发者连仅剩的实现持久层业务逻辑的工作都省了,唯一要做的,就只是声明持久层的接口,其他都交给 Spring Data JPA 来帮你完成!
二、Spring Data Jpa 基本 crud 实现
基本crud很简单,只要dao层接口继承JpaRepository即可,然后就可以使用相关api
server: port: 8080 servlet: context-path: /springtest02 spring: datasource: driver-class-name: oracle.jdbc.driver.OracleDriver url: jdbc:oracle:thin:@192.168.12.84:1521/test username: test password: test jpa: show-sql: true
@Entity @Table(name="t_rdb") public class Rdb { @Id private int t_id; private String name; private String pwd; private int age; public int getT_id() { return t_id; } public void setT_id(int t_id) { this.t_id = t_id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
package top.ruandb.dao; import org.springframework.data.jpa.repository.JpaRepository; import top.ruandb.entity.Rdb; public interface RdbDao extends JpaRepository<Rdb,Integer>{ }
package top.ruandb; import java.util.List; 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.SpringRunner; import org.springframework.web.bind.annotation.RequestMapping; import top.ruandb.dao.RdbDao; import top.ruandb.entity.Rdb; @RunWith(SpringRunner.class) @SpringBootTest public class Springtest02ApplicationTests { @Autowired private RdbDao rdbDao; //增加 @Test public void save() { Rdb r = new Rdb(); r.setT_id(2); r.setName("rdb"); r.setPwd("123"); r.setAge(18); rdbDao.save(r); } //修改 @Test public void update() { Rdb r = new Rdb(); r.setT_id(2); r.setName("rdb"); r.setPwd("123"); r.setAge(19); rdbDao.save(r); } //删除 @Test public void delete() { rdbDao.deleteById(1); } //查询 @Test public void find() { List<Rdb> l =rdbDao.findAll(); for(Rdb r : l) { System.out.println(r.getName()); } } }
三、自定义查询@Query
@Query注解可以直接通过写sql来查询数据,分为两种
1)hql
@Query(value = "select name,author,price from Book b where b.price>?1 and b.price<?2") List<Book> findByPriceRange(long price1, long price2); @Query(value = "select name,author,price from Book b where b.name like %:name%") List<Book> findByNameMatch(@Param("name") String name);
2)本地sql
所谓本地sql查询,就是使用原生的sql语句(根据数据库的不同,在sql的语法或结构方面可能有所区别)进行查询数据库的操作。
@Query(value = "select * from book b where b.name=?1", nativeQuery = true) List<Book> findByName(String name);
四、动态查询 Specification
通常业务场景中有很多条件是组合插叙的,这就需要用到动态查询
要实现动态查询dao接口除了继承JpaRepository,还要继承JpaSpecificationExecutor。
public interface RdbDao extends JpaRepository<Rdb,Integer>,JpaSpecificationExecutor<Rdb>{ @Query("select r from Rdb r where r.name=?1") public List<Rdb> findByName(String name); @Query(value="select * from t_rdb",nativeQuery=true) public List<Rdb> frndAll(); }
@SuppressWarnings("serial") @Test public void findAll() { Rdb rdb = new Rdb(); rdb.setName("b"); List<Rdb> l = rdbDao.findAll(new Specification<Rdb>() { @Override public Predicate toPredicate(Root<Rdb> root, CriteriaQuery<?> query, CriteriaBuilder cb) { Predicate predicate = cb.conjunction(); if (rdb != null) { // like条件 if (rdb.getName() != null && !rdb.getName().equals(" ")) { predicate.getExpressions().add(cb.like(root.get("name"), "%" + rdb.getName().trim() + "%")); } // 等于条件 if (rdb.getT_id() > 0) { predicate.getExpressions().add(cb.equal(root.get("t_id"), rdb.getT_id())); } // 大于条件(大于10岁) predicate.getExpressions().add(cb.gt(root.get("age"), 10)); // 小于条件(小于20岁) predicate.getExpressions().add(cb.lt(root.get("age"), 20)); } return predicate; } }); for (Rdb r : l) { System.out.println(r.toString()); } }