Spring Data JPA

张开发
2026/4/15 14:15:33 15 分钟阅读

分享文章

Spring Data JPA
Spring Data JPAJPAJava Persistence API即java持久化API它的出现主要是为了简化持久层开发以及整合ORM技术结束Hibernate、TopLink、JDO等ORM框架各自为营的局面。JPA是在吸收现有ORM框架的基础上发展而来易于使用伸缩性强。总的来说JPA包括以下三方面的技术ORM映射元数据支持XML和注解两种元数据的形式元数据描述对象和表之间的映射关系API操作实体对象来执行CRUD操作查询语言通过面向对象而非面向数据库的查询语言查询数据避免程序的SQL语句紧密耦合Sping Data JPA官方解释Spring Data JPA是Spring Data家族的一部分可以轻松实现基于JPA的存储库。此模块处理对基于JPA的数据访问层的增强支持。它使构建使用数据访问技术的Spring驱动应用程序变得更加容易。在相当长的一段时间内实现应用程序的数据访问层一直很麻烦。必须编写太多样板代码来执行简单查询以及执行分页和审计。Spring Data JPA旨在减少实际需要的工作量来显著改善数据访问层的实现。SpringBoot 整合Spring Data JPA导入依赖dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-jpa/artifactId /dependency数据库配置spring.datasource.driver-class-namecom.mysql.cj.jdbc.Driver spring.datasource.urljdbc:mysql://localhost:3306/chapter05?characterEncodingutf8serverTimezoneUTC spring.datasource.usernameroot spring.datasource.passwordroot #表示Jpa对应的数据库是mysql spring.jpa.show-sqltrue #项目启动时根据实体类更新数据库中的表 spring.jpa.hibernate.ddl-autoupdatespring.jpa.hibernate.ddl-auto:create每次运行程序时都会重新创建表故而数据会丢失create-drop每次运行程序时会先创建表结构然后程序结束时清空表update每次运行程序没有表时会创建表如果对象发生改变会更新表结构原有数据不会清空只会更新推荐使用validate运行程序会校验数据于数据库的字段类型是否相同字段不同会报错none禁用DDL处理Spring Data JPA的使用创建实体类import lombok.Data; import javax.persistence.*; Data Entity(name t_book) public class Book { Id GeneratedValue(strategy GenerationType.IDENTITY) private Integer id; Column(name book_name) private String name; Column(name book_author) private String author; private Float price; Transient private String description; }代码解释Entity注解表示该类是一个实体类在项目启动时会根据该类自动生成一张表表的名称即Entity注解中name的值如果不配置name默认表名为类名所有的实体类都要有主键Id注解表示该属性是一个主键GneeratedValue注解表示主键自动生成strategy则表示主键的生成策略默认情况下生成的表中字段的名称时实体类中属性的名称通过Column注解可以定制生成的字段的属性name表示该属性对应的数据表中字段的名称nullable表示该字段非空Transient注解表示在生成数据库的表时该属性被忽略即不生成对应的字段JPA自带的几种主键生成策略TABLE使用一个特定的数据库表格来保存主键SEQUENCE根据底层数据库的序列来生成主键条件是数据库支持序列。这个值要于generator一起使用generator指定生成主键的生成器IDENTITY主键由数据库自动生成主要支持自动增长的数据库如mysqlAUTO主键由程序控制也是GenerationType的默认值Dao层创建BookDao接口继承JpaRepository代码如下import com.example.demo.domain.Book; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Component; import java.util.List; Component public interface BookDao extends JpaRepositoryBook,Integer { //查询以某个字符开始的所有书 ListBook getBooksByAuthorStartingWith(String author); //查询单价大于某个值的所有书 ListBook getBooksByPriceGreaterThan(Float price); Query(value select * from t_book where id(select max(id) from t_book),nativeQuery true) Book getMaxIdBook(); Query(select b from t_book b where b.id:id and b.author:author) ListBook getBookByIdAndAuthor(Param(author) String author,Param(id) Integer id); Query(select b from t_book b where b.id?2 and b.name like %?1%) ListBook getBookByIdAndName(String name,Integer id); }代码解释自定义BookDao继承自JpaRepositiory。JpaRepositiory中提供了一些基本的数据操作方法有基本的增删改查、分页查询、排序查询等在Spring Data JPA中只要方法的定义符合既定规范Spring Data就能分析出开发者意图从而避免开发者定义SQLService层import com.example.demo.dao.BookDao; import com.example.demo.domain.Book; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import java.util.List; Service public class BookService { Autowired BookDao bookDao; //save方法由JpaRepository接口提供 public void addBook(Book book){ bookDao.save(book); } //分页查询 public PageBook getBookByPage(Pageable pageable){ return bookDao.findAll(pageable); } public ListBook getBooksByAuthorStartingWith(String author){ return bookDao.getBooksByAuthorStartingWith(author); } public ListBook getBooksByPriceGreaterThan(Float price){ return bookDao.getBooksByPriceGreaterThan(price); } public Book getMaxIdBook(){ return bookDao.getMaxIdBook(); } public ListBook getBookByIdAndName(String name,Integer id){ return bookDao.getBookByIdAndName(name,id); } public ListBook getBookByIdAndAuthor(String author,Integer id){ return bookDao.getBookByIdAndAuthor(author,id); } }Controller层创建BookContrller实现对数据的测试代码如下import com.example.demo.domain.Book; import com.example.demo.service.BookService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; RestController public class BookController { Autowired BookService bookService; GetMapping(value /findAll) public void findAll(){ PageRequest pageRequest PageRequest.of(2,3); PageBook page bookService.getBookByPage(pageRequest); System.out.println(总页数:page.getTotalPages()); System.out.println(总记录数:page.getTotalElements()); System.out.println(查询结果:page.getContent()); //从0开始记所以加上1 System.out.println(当前页数:(page.getNumber()1)); System.out.println(当前记录数:page.getNumberOfElements()); System.out.println(每页记录数:page.getSize()); } GetMapping(value search) public void search(){ ListBook bs1 bookService.getBookByIdAndAuthor(鲁迅,7); ListBook bs2 bookService.getBooksByAuthorStartingWith(吴); ListBook bs3 bookService.getBookByIdAndName(西,8); ListBook bs4 bookService.getBooksByPriceGreaterThan(30F); Book b bookService.getMaxIdBook(); System.out.println(bs1:bs1); System.out.println(bs2:bs2); System.out.println(bs3:bs3); System.out.println(bs4:bs4); System.out.println(b:b); } GetMapping(value /save) public void save(){ Book book new Book(); book.setAuthor(鲁迅); book.setName(呐喊); book.setPrice(23F); bookService.addBook(book); } }代码解释在findAll接口中首先通过调用PageRequest中的of方法构造PageRequest对象。of方法接收两个参数第一个参数是页数从0开始计数第二个参数是每页显示的条数分页Override public ListPerson findAllPerson(String name, Integer currentPage, Integer pagesize) { Pageable page PageRequest.of(currentPage - 1, pagesize); if(namenull || .equals(name)) return personRepository.findAll(page).getContent(); return personRepository.findAllByName(name,page); }Repository public interface PersonRepository extends JpaRepositoryPerson,Integer { Query(value select * from persion where name like %?1%,nativeQuery true) ListPerson findAllByName(String name, Pageable page); Query(value select * from persion where id ?1,nativeQuery true) Person findByyid(Integer id); Modifying Transactional Query(value delete from persion where id in (?1),nativeQuery true) void delall(String[] isd); }

更多文章