微人事第五天:Springboot整合Jpa
1. JPA是什么
Java Persistence API:用于对象持久化的 API
Java EE 5.0 平台标准的 ORM 规范,使得应用程序以统一的方式访问持久层
2. JPA和Hibernate的关系
JPA 是 Hibernate 的一个抽象(就像JDBC和JDBC驱动的关系);
JPA 是规范:JPA 本质上就是一种 ORM 规范,不是ORM 框架,这是因为 JPA 并未提供 ORM 实现,它只是制订了一些规范,提供了一些编程的 API 接口,但具体实现则由 ORM 厂商提供实现;
Hibernate 是实现:Hibernate 除了作为 ORM 框架之外,它也是一种 JPA 实现
从功能上来说, JPA 是 Hibernate 功能的一个子集
3.JPA的优势
标准化: 提供相同的 API,这保证了基于JPA 开发的企业应用能够经过少量的修改就能够在不同的 JPA 框架下运行。
简单易用,集成方便: JPA 的主要目标之一就是提供更加简单的编程模型,在 JPA 框架下创建实体和创建 Java 类一样简单,只需要使用 javax.persistence.Entity 进行注解;JPA 的框架和接口也都非常简单。
可媲美JDBC的查询能力: JPA的查询语言是面向对象的,JPA定义了独特的JPQL,而且能够支持批量更新和修改、JOIN、GROUP BY、HAVING 等通常只有 SQL 才能够提供的高级查询特性,甚至还能够支持子查询。
支持面向对象的高级特性: JPA 中能够支持面向对象的高级特性,如类之间的继承、多态和类之间的复杂关系,最大限度的使用面向对象的模型。
4.JPA包含的技术
ORM 映射元数据:JPA 支持 XML 和 JDK 5.0 注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中。
JPA 的 API:用来操作实体对象,执行CRUD操作,框架在后台完成所有的事情,开发者从繁琐的 JDBC 和 SQL 代码中解脱出来。
查询语言(JPQL):这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序和具体的 SQL 紧密耦合。
通过一个例子来说明一下:
1.创建Springboot项目
选择web,MySQL Driver和Spring Data JPA
2.修改pom.xml文件
给mysql数据库添加版本号(我的是5.1.27)
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
<version>5.1.27</version>
</dependency>
然后添加连接依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
3.在application.properties中配置数据库连接信息
spring.jpa.show-sql=true的作用是:jpa中不用sql语句操控数据库,我们通过各种方法去操作,在用方法操作时我们希望将操作的具体sql代码打印出来。
spring.jpa.database=mysql和spring.jpa.database-platform=mysql的作用是:申明平台是mysql
spring.jpa.hibernate.ddl-auto=update的作用:根据实体类来创建表(如果是第一次),以后就会将实体类和之前创建的相比较查看是否有不同的地方,不同的地方在原先的基础上修改一下就可以了,不用再次创建。
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect作用:指定方言(设定引擎为Innodb)。
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/javaboy?characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
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
4.实体类:Book
@Entity(name = “book”)作用:声明这是哥实体类,这个实体类对应数据库中的book表
@Id作用:代表这个属性是为主键
@GeneratedValue(strategy = GenerationType.IDENTITY)该字段是自增长
每个属性上还可以提供注解: @Column() 这个可以用来申明建立表中字段的名称,字段是否不为空等等一系列要求。
package org.javaboy.jpa.bean;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
//告诉其是个实体类,name代表对应的表是book
@Entity(name = "book")
public class Book {
@Id //表示id为该表主键
@GeneratedValue(strategy = GenerationType.IDENTITY) //id为自增长
private Integer id;
private String name;
private String 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;
}
@Override
public String toString() {
return "Book{" +
"id=" + id +
", name='" + name + '\'' +
", author='" + author + '\'' +
'}';
}
}
5.Bookdao
接下来要创建接口来操作实体类
接口中一个方法也不用写,只需要继承JpaRepository<>,这个接口提供了操作表的各种方法,<>中需要填写两个泛型,第一个泛型是操作的实体类,第二个是id属性。
package org.javaboy.jpa.dao;
import org.javaboy.jpa.bean.Book;
import org.springframework.data.jpa.repository.JpaRepository;
//操作实体类Book
//继承接口,第一个泛型是你要操控的实体类,第二个反应是id的属性
public interface BookDao extends JpaRepository<Book,Integer> {
}
现在先不去做CRUD操作,看看启动之后是否能在数据库中创建出book表。
点击启动类启动,控制台打印出sql语句:
Hibernate: create table book (id integer not null auto_increment,
author varchar(255), name varchar(255), primary key (id))
engine=InnoDB
打开mysql可以看到book表已经创建成功:
这里证明了spring.jpa.hibernate.ddl-auto=update实现了。
现在再回到BookDao,可以看到继承的接口是由jpa提供的:
可以看到JpaRepository(也就是我们继承的接口),它的父类是Repository
Repository下有个子类:CrudRepository,点击查看CrudRepository:
可以看到里面定义了各种crud的方法。
CrudRepository下有个实现类:PagingAndSortingRepository
PagingAndSortingRepository里提供了分页的功能:
PagingAndSortingRepository下的实现类才是我们继承的JpaRepository,下面这张图可以清除的看出JpaRespository由于继承了PagingAndSortingRepository,PagingAndSortingRepository又继承了CrudRepository,所以我们的BookDao接口继承了JpaRepository就拥有了各种crud的方法和分页功能。
下面通过测试来证明CRUD操作是否可行:
这里BookDao不用写任何方法,系统会默认识别到
测试类中注入BookDao,通过接口调用save(保持)方法,看看是否成功。
package org.javaboy.jpa;
import org.javaboy.jpa.bean.Book;
import org.javaboy.jpa.dao.BookDao;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class JpaApplicationTests {
@Autowired
private BookDao bookDao;
@Test
void contextLoads() {
Book book = new Book();
book.setName("三国演义");
book.setAuthor("罗贯中");
bookDao.save(new Book());
}
}
控制台打印:Hibernate: insert into book (author, name) values (?, ?)
可以看到数据添加成功
上面只是添加方法,接下来把删除,修改,查询都来测试一遍
修改测试:
saveAndFlush会根据id来更新,如果不存在这条数据,则会自动往数据库中添加这条数据,有的话则更新。
@Test
public void update() {
Book book = new Book();
book.setAuthor("罗贯中");
book.setName("三国志");
book.setId(2);
bookDao.saveAndFlush(book);
}
更新成功:
控制台打印:
Hibernate: select book0_.id as id1_0_0_, book0_.author as author2_0_0_, book0_.name as name3_0_0_ from book book0_ where book0_.id=?
Hibernate: update book set author=?, name=? where id=?
接下来是删除操作:
我们删除id为2的数据:
删除可以全部删除,也可以根据各种条件来删除:
@Test
public void delete() {
bookDao.deleteById(1);
}
启动删除测试类可以看出数据库中的信息被删除了控制台打印:
Hibernate: select book0_.id as id1_0_0_, book0_.author as author2_0_0_, book0_.name as name3_0_0_ from book book0_ where book0_.id=?
Hibernate: delete from book where id=?
最后就是查询方法,查询既可以根据id查询还可以查询全部,这里都试一下:
Hibernate: select book0_.id as id1_0_0_, book0_.author as author2_0_0_, book0_.name as name3_0_0_ from book book0_ where book0_.id=?
Book{id=2, name=‘水浒传’, author=‘施耐庵’}
Hibernate: select book0_.id as id1_0_, book0_.author as author2_0_, book0_.name as name3_0_ from book book0_
[Book{id=1, name=‘三国演义’, author=‘罗贯中’}, Book{id=2, name=‘水浒传’, author=‘施耐庵’}, Book{id=3, name=‘西游记’, author=‘吴承恩’}, Book{id=4, name=‘红楼梦’, author=‘曹雪芹’}]
可以看到两种方法都成功了。
上面的查询都是简单查询下面来演示排序查询:
@Test
public void find2() {
List<Book> id = bookDao.findAll(new Sort(Sort.Direction.DESC, "id"));
System.out.println(id);
}
上一篇: LeetCode 面试题 01.06. 字符串压缩
下一篇: 19:字符串移位包含问题
推荐阅读
-
Springboot整合微信小程序实现登录与增删改查
-
Springboot整合JPA
-
Springboot整合Spring Data Jpa
-
SpringBoot整合JPA数据源方法及配置解析
-
详解SpringBoot是如何整合JPA的
-
SpringBoot整合JPA异常org.springframework.validation.BindException
-
SpringBoot2.x系列二:整合第三方组件Mybatis、JPA、Redis、Elasticsearch、ActiveMQ、Kafka、Logback
-
activemq整合springboot使用(个人微信小程序用)
-
第四篇:SpringBoot 整合JPA
-
Springboot整合微信小程序实现登录与增删改查