SpringBoot3SpringBoot使用Springdatajpa实现数据库访问

26次阅读

共计 4963 个字符,预计需要花费 13 分钟才能阅读完成。

做 Web 开发,首先要能将数据渲染到网页中展示,其次是要获取数据库数据展示到视图层,在前面的文章 SpringBoot 整合 Thymeleaf 模板引擎渲染 web 视图,我们实现了从后端数据展示到视图层,那么下面我们通过使用 Spring Data Jpa 来实现简单的数据库增删改查功能。

1.pom.xml 中引入依赖的 jar 包

        <!--Web 开发依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--junit 测试依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--jpa 依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>    
        <!-- 引入 MySQL 连接的依赖包 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.21</version>
        </dependency>                                        

因为项目是基于 Spring Boot 2.1.9.RELEASE 版本的,而我本地使用的 Mysql 是 5.X 版本,所以这里引入 mysql 依赖的时候添加了版本信息,这样可以引入相应的版本,如果不加版本信息将会引入 8.X 版本的 Mysql,可能在运行项目测试出现错误。

2. 配置 application.properties 数据库信息

# 数据库连接信息
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# 自动创建表结构的设置
spring.jpa.properties.hibernate.hbm2ddl.auto=create-drop

spring.jpa.properties.hibernate.hbm2ddl.auto是 hibernate 的配置属性,其主要作用是:自动创建、更新、验证数据库表结构。该参数的几种配置如下:

  • create:每次加载 hibernate 时都会删除上一次的生成的表,然后根据你的 model 类再重新来生成新表,哪怕两次没有任何改变也要这样执行,这就是导致数据库表数据丢失的一个重要原因。
  • create-drop:每次加载 hibernate 时根据 model 类生成表,但是 sessionFactory 一关闭, 表就自动删除
  • update:最常用的属性,第一次加载 hibernate 时根据 model 类会自动建立起表的结构(前提是先建立好数据库),以后加载 hibernate 时根据 model 类自动更新表结构,即使表结构改变了但表中的行仍然存在不会删除以前的行。要注意的是当部署到服务器后,表结构是不会被马上建立起来的,是要等应用第一次运行起来后才会。
  • validate:每次加载 hibernate 时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值。

3. 创建实体类

创建一个 User 实体,包含 id(主键)、name(姓名)、age(年龄)属性,通过 ORM 框架其会被映射到数据库表中,由于配置了hibernate.hbm2ddl.auto,并且配置的值为:create-drop,在应用启动的时候框架会自动去数据库中创建对应的表,应用停止时则会自动删除表信息。

package com.w3cjava.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class User {
    @Id
    @GeneratedValue
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private Integer age;

    public User() {}

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

    public Long getId() {return id;}

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

    public String getName() {return name;}

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

    public Integer getAge() {return age;}

    public void setAge(Integer age) {this.age = age;}   
}

4. 创建数据访问接口

下面针对 User 实体创建对应的 Repository 接口实现对该实体的数据访问,如下代码:

package com.w3cjava.dao;

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

import com.w3cjava.entity.User;
/**
 * 
 * @class  UserRepository
 * @version 1.0.0
 * @author cos
 * @desc   创建对应的 Repository 接口实现对该实体的数据访问
 *
 */
public interface UserRepository extends JpaRepository<User, Long> {User findByName(String name);

    User findByNameAndAge(String name, Integer age);

    @Query("from User u where u.name=:name")
    User findUser(@Param("name") String name);

}

通过继承 JpaRepository 接口,已经实现了基础的增 (save) 删(delete)改 (save) 查(findAll、findOne),具体可以查看 API 文档,因此开发过程中,基本的数据访问层不需要开发者再自己定义。

项目开发过程中,往往对数据的访问都比较复杂,这时候就需要程序员自己定义相对复杂的 Sql 语句。具体可以参考 API 文档。

Spring Data Jpa 还提供了通过解析方法名创建查询,比如上面的代码:

    User findByName(String name);

    User findByNameAndAge(String name, Integer age);

5. 单元测试

整合 Spring Data Jpa 所需要的基本类和配置已经准备好,下面进行简单的单元测试。

package com.w3cjava.service;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import com.w3cjava.SpringBootSpringDataJpaApplication;
import com.w3cjava.dao.UserRepository;
import com.w3cjava.entity.User;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {SpringBootSpringDataJpaApplication.class})
public class UserServiceTest {
    @Autowired
    private UserRepository userRepository;

    @Test
    public void test() throws Exception {

        // 创建 10 条记录
        userRepository.save(new User("A", 10));
        userRepository.save(new User("B", 20));
        userRepository.save(new User("C", 30));
        userRepository.save(new User("D", 40));
        userRepository.save(new User("E", 50));
        userRepository.save(new User("F", 60));
        userRepository.save(new User("G", 70));
        userRepository.save(new User("H", 80));
        userRepository.save(new User("I", 90));
        userRepository.save(new User("J", 100));

        // 测试 findAll, 查询所有记录
        Assert.assertEquals(10, userRepository.findAll().size());

        // 测试 findByName, 查询姓名为 FFF 的 User
        Assert.assertEquals(60, userRepository.findByName("F").getAge().longValue());

        // 测试 findUser, 查询姓名为 FFF 的 User
        Assert.assertEquals(60, userRepository.findUser("F").getAge().longValue());

        // 测试 findByNameAndAge, 查询姓名为 FFF 并且年龄为 60 的 User
        Assert.assertEquals("F", userRepository.findByNameAndAge("F", 60).getName());

        // 测试删除姓名为 AAA 的 User
        userRepository.delete(userRepository.findByName("A"));

        // 测试 findAll, 查询所有记录, 验证上面的删除是否成功
        Assert.assertEquals(9, userRepository.findAll().size());

    }
}

6. 参考文章

Cannot load driver class: com.mysql.jdbc.Driver: https://blog.csdn.net/linmeng…
spring Boot–junit 单元测试: https://blog.csdn.net/adminBf…
源码:03.Spring-Boot-SpringDataJpa

欢迎扫面下列二维码关注“余弦的自留地 ”公众微信号

万物之中,希望至美

正文完
 0