spring Boot中整合JPA

Spring Boot中的数据持久化方案前面介绍了两种,一个是JdbcTemplate,还有一个MyBatis,JdbcTemplate配置简单,使用也简单,但是功能也非常有限,MyBatis则比较灵活,功能也很强大,公司采用MyBatis做数据持久化的相当多,但是MyBatis并不是唯一的解决方案,除了MyBatis之外,还有另外一个东西,那就是Jpa,下面就来说说Jpa如何实现数据持久化。先简单介绍下jpa的概念

JPA介绍

JPA—java persistence api用于对象持久化的api,它是Java EE 5.0 平台标准的 ORM 规范,使得应用程序以统一的方式访问持久层

在这里插入图片描述

JPA与Hibernate的关系

1、JPA 是 Hibernate 的一个抽象(就像JDBC和JDBC驱动的关系);
2、JPA 是规范:JPA 本质上就是一种 ORM 规范,不是ORM 框架,这是因为 JPA 并未提供 ORM 实现,它只是制订了一些规范,提供了一些编程的 API 接口,但具体实现则由 ORM 厂商提供实现;
3、Hibernate 是实现:Hibernate 除了作为 ORM 框架之外,它也是一种 JPA 实现
4、从功能上来说, JPA 是 Hibernate 功能的一个子集

JPA的供应商

JPA 的目标之一是制定一个可以由很多供应商实现的 API,Hibernate 3.2+、TopLink 10.1+ 以及 OpenJPA 都提供了 JPA 的实现,Jpa 供应商有很多,常见的有如下四种:

1、Hibernate
2、JPA 的始作俑者就是 Hibernate 的作者,Hibernate 从 3.2 开始兼容 JPA。
3、OpenJPA
4、OpenJPA 是 Apache 组织提供的开源项目。
5、TopLink
6、TopLink 以前需要收费,如今开源了。
7、EclipseLink

JPA包含的技术

1、ORM 映射元数据:JPA 支持 XML 和 JDK 5.0 注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中。
2、JPA 的 API:用来操作实体对象,执行CRUD操作,框架在后台完成所有的事情,开发者从繁琐的 JDBC 和 SQL 代码中解脱出来。
3、查询语言(JPQL):这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序和具体的 SQL 紧密耦合。

创建项目

创建Spring Boot工程,添加Web、Jpa以及MySQL驱动依赖,如下:
在这里插入图片描述

工程创建好之后,添加Druid依赖,完整的依赖如下:

<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>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.10</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.27</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

以上项目算是创建成功了,下面我们进行基本数据源的配置

基本配置

我们需要在application.properties中配置数据源信息

#数据库的基本配置
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql:///tb_user?useSSL=true&useUnicode=true&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=123456

#JPA的配置
spring.jpa.database=mysql

#在控制台打印sql
spring.jpa.show-sql=true

#数据库平台
spring.jpa.database-platform=mysql
#每次启动项目时,数据库采用初始化策略,启动会检查这个表是否存在,不存在就创建,存在则会检测是否与实体类一样,一样则直接使用,不一样则会更新表
spring.jpa.hibernate.ddl-auto=update
#指定默认的存储引擎为InnoDB
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect

默认情况下,自动创建表的时候会使用MyISAM做表的引擎,如果配置了数据库方言为MySQL57Dialect,则使用InnoDB做表的引擎。

接下来我们就可以使用了

基本使用

ORM(Object Relational Mapping)框架表示对象关系映射,使用ORM框架我们不必再去创建表,框架会自动根据当前项目中的实体类创建相应的数据表。因此,我这里首先创建一个User对象

package com.zhouym.jpa;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

/**
 * 〈Users实体类〉
 *
 * @author zhouym
 * @create 2019/8/10
 * @since 1.0.0
 */
@Entity(name = "t_user")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String name;
    private String address;

    public User() {
    }

    public User(Integer id, String name, String address) {
        this.id = id;
        this.name = name;
        this.address = address;
    }

    public User(String name, String address) {
        this.name = name;
        this.address = address;
    }

    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 getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
}

首先@Entity注解表示这是一个实体类,那么在项目启动时会自动针对该类生成一张表,默认的表名为类名,@Entity注解的name属性表示自定义生成的表名。@Id注解表示这个字段是一个id,@GeneratedValue注解表示主键的自增长策略,对于类中的其他属性,默认都会根据属性名在表中生成相应的字段,字段名和属性名相同,如果开发者想要对字段进行定制,可以使用@Column注解,去配置字段的名称,长度,是否为空等等。

做完这一切之后,启动Spring Boot项目,就会发现数据库中多了一个名为t_user的表了。

针对该表的操作,则需要我们提供一个Repository,如下

package com.zhouym.jpa;

import org.springframework.data.jpa.repository.JpaRepository;
public interface UserDao extends JpaRepository<User,Integer> {

}

自定义UserDao接口继承自JpaRepository,JpaRepository提供了一些基本的数据操作方法,例如保存,更新,删除,分页查询等,我们在controller中可以直接调用方法使用

controller类

package com.zhouym.jpa;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 〈〉
 *
 * @author zhouym
 * @create 2019/8/10
 * @since 1.0.0
 */
@RestController
public class UserController {

    @Autowired
    UserDao userDao;

    @PostMapping("/add")
    public void addUser() {
        User user = new User();
        user.setName("张三");
        user.setAddress("深圳");
        userDao.save(user);
    }

    @GetMapping("/query")
    public List<User> queryUser() {
        return userDao.findAll();
    }

    @PutMapping("/update")
    public void updateUser() {
        User user = userDao.getOne(1);
        user.setName("王五");
        userDao.flush();
    }

    @DeleteMapping("/delete")
    public void deleteUser() {
        User user = new User();
        user.setId(1);
        userDao.delete(user);
    }

    @GetMapping("/query1")
    public void query1() {
        List<User> users = userDao.queryByUserAndNameAndAddress("王五", "上海");
        System.out.println(users);
    }

    @GetMapping("/query2")
    public void query2() {
        User user = userDao.MaxIdUser();
        System.out.println(user);
    }

    @GetMapping("/query3")
    public void query3() {
        Pageable pageable = PageRequest.of(1, 3);
        Page<User> page = userDao.findAll(pageable);
        System.out.println("总页数:" + page.getTotalPages());
        System.out.println("查询结果:" + page.getContent());
        System.out.println("当前页数:" + page.getNumber());
        System.out.println("每页显示的数据:" + page.getSize());
        System.out.println("是否是首页:" + page.isFirst());
        System.out.println("是否是最后一页:" + page.isLast());
    }
}

如果jpa默认提供的方法不能满足我们的需求,就需要我们在接口中自定义方法了,例如:

package com.zhouym.jpa;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import java.util.List;

public interface UserDao extends JpaRepository<User,Integer> {
	List<User> queryByUserAndNameOrAddress(String name,String address);

    @Query(value = "select * from t_user where id = (select max(id) from t_user)",nativeQuery = true)
    User MaxIdUser();


}

只需要方法名称符合规范即可,在Spring Data中,只要按照既定的规范命名方法,Spring Data Jpa就知道你想干嘛,这样就不用写SQL了,那么规范是什么呢?参考下图:
在这里插入图片描述

当然,这种方法命名主要是针对查询,但是一些特殊需求,可能并不能通过这种方式解决,例如想要查询id最大的用户,这时就需要开发者自定义查询SQL了,如上代码所示,自定义查询SQL,使用@Query注解,在注解中写自己的SQL,默认使用的查询语言不是SQL,而是JPQL,这是一种数据库平台无关的面向对象的查询语言,有点定位类似于Hibernate中的HQL,在@Query注解中设置nativeQuery属性为true则表示使用原生查询,即大伙所熟悉的SQL。上面代码中的只是一个很简单的例子,还有其他一些点,例如如果这个方法中的SQL涉及到数据操作,则需要使用@Modifying注解。

发布了207 篇原创文章 · 获赞 87 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/zhouym_/article/details/99181832