借鉴来源:Spring Boot整合 Jpa教程
新建springboot项目 , 勾选 web , mysql , jpa
重点: 导包 、JPA 配置、 注解 、 JpaRepository接口
pom.xml中 依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.17</version>
</dependency>
application.properties 中 进行 数据库基本信息配置以及Jpa基本配置 , 注意MySQL数据库版本, 8.0之前和8.0之后配置不同
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.url=jdbc:mysql://192.168.20.40/jpa?characterEncoding=utf8&useSSL=false&zeroDateTimeBehavior=convertToNull
spring.jpa.show-sql=true
spring.jpa.database=mysql
spring.jpa.database-platform=mysql
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
创建实体类
package com.example.jpa.Entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity(name = "t_book") //@Entity注解的name属性表示自定义生成的表名。
public class Book {
@Id //@Id注解表示这个字段是一个id
@GeneratedValue(strategy = GenerationType.IDENTITY) //@GeneratedValue注解表示主键的自增长策略
private Integer id;
private String name;
private String author;
@Override
public String toString() {
return "Book{" +
"id=" + id +
", name='" + name + '\'' +
", author='" + author + '\'' +
'}';
}
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 String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
启动Spring Boot项目,就会发现数据库中多了一个名为t_book的表了。
创建Dao接口
package com.example.jpa.Dao;
import com.example.jpa.Entity.Book;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
public interface BookDao extends JpaRepository<Book,Integer> {
//findBookById findBookByIdGreaterThan findBookByIdLessThanOrNameContaining 规范命名
Book findBookById(Integer id);
List<Book> findBookByIdGreaterThan(Integer id);
List<Book> findBookByIdLessThanOrNameContaining(Integer id,String name);
@Query(value = "select * from t_book where id=(select max(id) from t_book)",nativeQuery = true)
Book getMaxIdBook();
@Query(value = "insert into t_book(name,author) values(?1,?2)",nativeQuery = true)
@Modifying
@Transactional
Integer addBook(String name,String author);
@Query(value = "insert into t_book(name,author) values(:name,:author)",nativeQuery = true)
@Modifying
@Transactional
Integer addBook2(@Param("name") String name, @Param("author")String author);
}
在Spring Data中,只要按照既定的规范命名方法,Spring Data Jpa就知道你想干嘛,这样就不用写SQL了,那么规范是什么呢?参考下图:
测试
package com.example.jpa;
import com.example.jpa.Dao.BookDao;
import com.example.jpa.Entity.Book;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import java.awt.print.Pageable;
import java.util.List;
import java.util.Optional;
@SpringBootTest
class JpaApplicationTests {
@Autowired
BookDao bookDao;
@Test
public void contextLoads() {
Book book=new Book();
book.setName("三国演义");
book.setAuthor("罗贯中");
//insert into t_book (author, name) values (?, ?)
bookDao.save(book); //save 会再存一个进去 , 不会比较是否存在
}
@Test
public void update(){
Book book=new Book();
book.setAuthor("luoguanzhong");
book.setName("sanguoyanyi");
book.setId(4);
// Hibernate: select book0_.id as id1_0_0_, book0_.author as author2_0_0_, book0_.name as name3_0_0_ from t_book book0_ where book0_.id=?
// Hibernate: update t_book set author=?, name=? where id=?
bookDao.saveAndFlush(book); //会先查有没有 , 有就update , 没有就insert
}
@Test
public void delete(){
//Hibernate: select book0_.id as id1_0_0_, book0_.author as author2_0_0_, book0_.name as name3_0_0_ from t_book book0_ where book0_.id=?
//Hibernate: delete from t_book where id=?
bookDao.deleteById(2); //先查找再删除
}
@Test
public void find1(){
//Hibernate: select book0_.id as id1_0_0_, book0_.author as author2_0_0_, book0_.name as name3_0_0_ from t_book book0_ where book0_.id=?
//Book{id=3, name='sanguoyanyi', author='luoguanzhong'}
//Hibernate: select book0_.id as id1_0_, book0_.author as author2_0_, book0_.name as name3_0_ from t_book book0_
//[Book{id=1, name='三国演义', author='罗贯中'}, Book{id=3, name='sanguoyanyi', author='luoguanzhong'}, Book{id=4, name='sanguoyanyi', author='luoguanzhong'}]
// Book bookById = bookDao.findBookById(3);
// Optional 类既可以含有对象也可以为空 , 可以避免空指针异常
Optional<Book> byId = bookDao.findById(3);
System.out.println(byId.get());
List<Book> all=bookDao.findAll();
System.out.println(all);
}
@Test
public void find3(){
// Hibernate: select book0_.id as id1_0_, book0_.author as author2_0_, book0_.name as name3_0_ from t_book book0_ limit ?
// Hibernate: select count(book0_.id) as col_0_0_ from t_book book0_
PageRequest pageable= PageRequest.of(0,2 );
Page<Book> page = bookDao.findAll(pageable);
System.out.println("总记录数:"+page.getTotalElements());
System.out.println("当前页记录数:"+page.getNumberOfElements());
System.out.println("每页记录数:"+page.getSize());
System.out.println("获取总页数:"+page.getTotalPages());
System.out.println("查询结果:"+page.getContent());
System.out.println("当前页(从0开始计):"+page.getNumber());
System.out.println("是否为首页:"+page.isFirst());
System.out.println("是否为尾页:"+page.isLast());
//总记录数:3
//当前页记录数:2
//每页记录数:2
//获取总页数:2
//查询结果:[Book{id=1, name='三国演义', author='罗贯中'}, Book{id=3, name='sanguoyanyi', author='luoguanzhong'}]
//当前页(从0开始计):0
//是否为首页:true
//是否为尾页:false
}
@Test
public void find4(){
//Hibernate: select book0_.id as id1_0_, book0_.author as author2_0_, book0_.name as name3_0_ from t_book book0_ where book0_.id=?
//Book{id=3, name='sanguoyanyi', author='luoguanzhong'}
Book book=bookDao.findBookById(3);
System.out.println(book);
}
@Test
public void find5(){
//Hibernate: select book0_.id as id1_0_, book0_.author as author2_0_, book0_.name as name3_0_ from t_book book0_ where book0_.id>?
//[]
//Hibernate: select book0_.id as id1_0_, book0_.author as author2_0_, book0_.name as name3_0_ from t_book book0_ where book0_.id<? or book0_.name like ? escape ?
//[Book{id=1, name='三国演义', author='罗贯中'}, Book{id=3, name='sanguoyanyi', author='luoguanzhong'}, Book{id=4, name='sanguoyanyi', author='luoguanzhong'}]
List<Book> list = bookDao.findBookByIdGreaterThan(4);
System.out.println(list);
List<Book> list1 = bookDao.findBookByIdLessThanOrNameContaining(5, "水");
System.out.println(list1);
}
@Test
public void find6(){
//Hibernate: select * from t_book where id=(select max(id) from t_book)
//Book{id=6, name='python', author='老刘'}
Book book=bookDao.getMaxIdBook();
System.out.println(book);
}
@Test
public void test7(){
//Hibernate: insert into t_book(name,author) values(?,?)
//Hibernate: insert into t_book(name,author) values(?,?)
Integer r1 = bookDao.addBook2("java", "小刘");
System.out.println(r1);
Integer r2 = bookDao.addBook("python", "老刘");
System.out.println(r2);
}