微人事第五天: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);
    }
发布了287 篇原创文章 · 获赞 24 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_41998938/article/details/104042043