JPA(Java Persistence API)即java持久化API,它的出现主要是为了简化持久层开发以及整合ORM技术,结束Hibernate、TopLink、JDO等ORM框架各自为营的局面。JPA是在吸收现有ORM框架的基础上发展而来,易于使用,伸缩性强。总的来说,JPA包括以下三方面的技术:
Spring Data JPA是Spring Data家族的一部分,可以轻松实现基于JPA的存储库。此模块处理对基于JPA的数据访问层的增强支持。它使构建使用数据访问技术的Spring驱动应用程序变得更加容易。
在相当长的一段时间内,实现应用程序的数据访问层一直很麻烦。必须编写太多样板代码来执行简单查询以及执行分页和审计。Spring Data JPA旨在减少实际需要的工作量来显著改善数据访问层的实现。
导入依赖:
org.springframework.boot
spring-boot-starter-data-jpa
数据库配置:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/chapter05?characterEncoding=utf8&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
#表示Jpa对应的数据库是mysql
spring.jpa.show-sql=true
#项目启动时根据实体类更新数据库中的表
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.ddl-auto:
创建实体类:
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;
}
代码解释:
JPA自带的几种主键生成策略:
创建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 JpaRepository {
//查询以某个字符开始的所有书
List getBooksByAuthorStartingWith(String author);
//查询单价大于某个值的所有书
List 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")
List getBookByIdAndAuthor(@Param("author") String author,@Param("id") Integer id);
@Query("select b from t_book b where b.id2 and b.name like %?1%")
List getBookByIdAndName(String name,Integer id);
}
代码解释:
创建BookService,代码如下:
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 Page getBookByPage(Pageable pageable){
return bookDao.findAll(pageable);
}
public List getBooksByAuthorStartingWith(String author){
return bookDao.getBooksByAuthorStartingWith(author);
}
public List getBooksByPriceGreaterThan(Float price){
return bookDao.getBooksByPriceGreaterThan(price);
}
public Book getMaxIdBook(){
return bookDao.getMaxIdBook();
}
public List getBookByIdAndName(String name,Integer id){
return bookDao.getBookByIdAndName(name,id);
}
public List getBookByIdAndAuthor(String author,Integer id){
return bookDao.getBookByIdAndAuthor(author,id);
}
}
创建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);
Page 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(){
List bs1 = bookService.getBookByIdAndAuthor("鲁迅",7);
List bs2 = bookService.getBooksByAuthorStartingWith("吴");
List bs3 = bookService.getBookByIdAndName("西",8);
List 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);
}
}
代码解释:
数据库数据:
调用httP://127.0.0.1:8080/findAll接口:
总页数:3
总记录数:7
查询结果:[Book(id=7, name=故事新编, author=鲁迅, price=22.0, description=null)]
当前页数:3
当前记录数:1
每页记录数:3
调用httP://127.0.0.1:8080/save接口:
Hibernate: insert into t_book (book_author, book_name, price) values (?, ?, ?)
调用httP://127.0.0.1:8080/search接口:
bs1:[Book(id=8, name=呐喊, author=鲁迅, price=23.0, description=null)]
bs2:[Book(id=3, name=西游记, author=吴承恩, price=29.0, description=null)]
bs3:[Book(id=3, name=西游记, author=吴承恩, price=29.0, description=null)]
bs4:[Book(id=2, name=红楼梦, author=曹雪芹, price=35.0, description=null), Book(id=5, name=围城, author=钱钟书, price=33.0, description=null)]
b:Book(id=8, name=呐喊, author=鲁迅, price=23.0, description=null)