【SpringBoot】数据持久化——JPA(1)搭建环境

如果饿了就吃,困了就睡,渴了就喝,人生就太无趣了
源码地址:https://github.com/keer123456789/springbootstudy/tree/master/jpa_demo
本人刚刚接触jpa,如有错误,欢迎大家指正!!


1.JPA介绍

JPA(Java Persistence API)Java持久化API,是 Java 持久化的标准规范,Hibernate是持久化规范的技术实现,而Spring Data JPA是在 Hibernate 基础上封装的一款框架。JPA作为标准,实际上并没有说局限于某个固定的数据源,事实上mysql,mongo, solr都是ok的。接下来我们将介绍下springboot结合jpa 来实现mysql的curd以及更加复杂一点的sql支持

2.环境配置

2.1 数据库配置

数据库选择mysql数据库。并新建一个数据库jpademo1。如图

在这里插入图片描述

2.2 SpringBoot pom 配置

mysql依赖中的版本根据自己的mysql版本配置。

	<dependencies>
        <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>
            <version>8.0.11</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

2.3 MySQL数据源配置

mysql的基本配置,不再过多解释。

spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/jpademo?useSSL=false&serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

2.4 jpa配置

每个属性的解释都在注释中,

  • spring.jpa.show-sql建议开启,这个会在日志中打印sql语句,对之后的调试很有帮助。
  • ddl-auto:update 每次运行程序,没有表格会新建表格,表内有数据不会清空,只会更新
# 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

3.Entity介绍

JPA提供了实体与库表的映射关系。只需要使用@Entity注解即可。

  • @Entity
    • 声明这个POJO是一个与数据库中叫做 user 的表关联的对象.
    • 参数name,用于指定表名,如果不主动指定时,默认用类名,即上面如果不指定那么,那么默认与表 user 绑定
  • @Column
    • 这个注解就是用来解决我们pojo成员名和数据库列名不一致的问题的
    • name参数填写表名
    • nullable参数是表示该列是否可以为空
  • 主键注解
    • @Id 注解 表示这个列是主键,关系型数据中很重的。
    • @GeneratedValue设置初始值,谈到主键,我们一般会和”自增“这个一起说,所以你经常会看到的取值为 strategy = GenerationType.IDENTITY(由数据库自动生成)
      这个注解提供了四种形式,关于这几种使用姿势,这里不详细展开了,有兴趣的可以可以看一下这博文: @GeneratedValue
取值 说明
GenerationType.TABLE 使用一个特定的数据库表格来保存主键
GenerationType.SEQUENCE 根据底层数据库的序列来生成主键,条件是数据库支持序列
GenerationType.IDENTITY 主键由数据库自动生成(主要是自动增长型)
GenerationType.AUTO 主键由程序控制
@Entity(name = "user")
public class User {
    @Column(name = "name", nullable = false)
    private String name;
    @Column(name = "password", nullable = false)
    private String password;
    @Column(name = "address", nullable = false)
    private String address;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    public User() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getAddress() {
        return address;
    }

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

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

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

4.增删改查

jpa只需要继承一个接口即可完成DB的操作。这次继承的CrudRepository类。这样就可以实现很多操作。

@Component
public interface UserDao extends CrudRepository<User, Integer> {
}

4.1 Select

由于继承了CrudRepository接口,这个接口提供了三个查询方法,如图

  • 查询表中所有User信息
  • 根据主键查询相应的User
  • 根据一组主键查询相应的信息。

在这里插入图片描述

这单单是此接口实现的根据主键查询的方法,jpa具有强大的查询功能,实现了GroupBy,having等等高级的sql查询功能,这些功能会在之后的博客中介绍……

这次简单的介绍findAll()的功能。在Service层进行查询。查寻完成之后返回给controller,即可,webResult返回请求的自定义的值。具体的就不在介绍,可以自行去项目中查看。

public WebResult selectAllUsers(){
    List<User> users= (List<User>) userDao.findAll();
    WebResult webResult=new WebResult();
    webResult.setStatus(WebResult.SUCCESS);
    webResult.setMessage("查询成功");
    webResult.setData(users);
    logger.info("查询成功,数据:"+users.toString());
    return webResult;
}

如图,可以看到查询语句

在这里插入图片描述

数据库中的数据和日志打印出来的数据:
在这里插入图片描述

4.2 Insert

1.插入单个数据

public WebResult addUser(User user) {
        User res = userDao.save(user);
        WebResult result = new WebResult();
        if (res != null) {
            result.setData(user);
            result.setMessage("增加成功");
            result.setStatus(WebResult.SUCCESS);
            return result;
        }
        return null;
    }
  • 调用接口的save()方法。入参是需要增加的User信息

进行测试:
测试数据:

#增加用户信息
POST http://127.0.0.1:8080/jpa/addUser
Content-Type: application/json

{
  "id": 4,
  "name": "keer",
  "password": "133333",
  "address": "北京市平谷区"
}

测试结果:
在这里插入图片描述

  • 先根据id进行查询(防止主键重复,这是一种可能,原因在update的时候在深入解释)。
  • 然后在进行插入操作

2.批量插入
同样是调用接口已经有的方法,saveAll()方法,入参是User的list数组

public WebResult addUsers(List list) {
    WebResult webResult = new WebResult();
    userDao.saveAll(list);
    List<User> failUsers = new ArrayList<>();
    for (Object o : list) {
        User user = (User) o;
        if (!userDao.existsById(user.getId())) {
            failUsers.add(user);
        }
    }
    if (failUsers.size() == 0) {
        webResult.setStatus(WebResult.SUCCESS);
        webResult.setMessage("插入成功");
    } else {
        webResult.setMessage("部分插入失败");
        webResult.setData(failUsers);
        webResult.setStatus(WebResult.ERROR);
    }
    return webResult;
}

进行测试:
测试数据:

#批量增加用户
POST http://127.0.0.1:8080/jpa/addUsers
Content-Type: application/json

[
  {
    "name": "可耳",
    "password": "love",
    "address": "北京市"
  },
  {
    "name": "java",
    "password": "hello world",
    "address": "main()"
  }

]

测试结果:
在这里插入图片描述

  • 这次没有指明主键id,因为是自增主键,所以就自动生成了
  • 日志中的select语句,是因为调用了existsById()方法进行查询是否存在。

4.3 Delete

删除操作直接调用接口中的delete()方法,入参是user实例

public WebResult removeUser(User user) {
    userDao.delete(user);
    WebResult webResult = new WebResult();
    if (!userDao.existsById(user.getId())) {
        webResult.setStatus(WebResult.SUCCESS);
        webResult.setMessage("删除用户信息成功!");
    } else {
        webResult.setStatus(WebResult.ERROR);
        webResult.setMessage("删除用户信息失败!");
    }
    return webResult;
}

进行测试:
测试数据:

#删除用户
POST http://127.0.0.1:8080/jpa/deleteUser
Content-Type: application/json

{
  "name": "java",
  "password": "hello world",
  "address": "main()",
  "id": 6
}

测试结果:
在这里插入图片描述

  • 日志中首先使用主键进行了查询
  • 之后再进行删除
  • 日志中的select语句,是因为调用了existsById()方法进行查询是否存在。

4.4 Updata

1.使用save()方法,数据必须带有主键,而且需要user中带有全部数据,这样才能进行update。

public WebResult updateUser(User user) {
    WebResult webResult = new WebResult();
    User newUser = userDao.save(user);
    logger.info("更新信息:" + newUser.toString());
    webResult.setMessage("更新操作成功");
    webResult.setData(newUser);
    webResult.setStatus(WebResult.SUCCESS);
    return webResult;
}

进行测试:
测试数据:

POST http://127.0.0.1:8080/jpa/updateUser
Content-Type: application/json

{
  "id": 1,
  "name": "keer",
  "password": "133333",
  "address": "北京市平谷区"
}

测试结果:

在这里插入图片描述

  • 日志中首先使用主键进行了查询(回答上面的问题,查询这个id对应的记录是否存在,存在就是update,不存在就是insert)

参考博客:http://spring.hhui.top/spring-blog/2019/06/14/190614-SpringBoot%E7%B3%BB%E5%88%97%E6%95%99%E7%A8%8BJPA%E4%B9%8B%E6%96%B0%E5%A2%9E%E8%AE%B0%E5%BD%95%E4%BD%BF%E7%94%A8%E5%A7%BF%E5%8A%BF/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章