SpringBoot中数据库的配置和使用

2022-10-25 12:49:50

此文省略Springboot项目的创建以及初始化
学习书籍《深入实践SpringBoot》

1、MySQL


对于传统关系型数据库(如MySQL)来说,SpringBoot使用JPA(Java Persistence API)资源库实现对数据库的操作。JPA是为POJO(Plain Ordinary Java Object)提供持久化的标准规范。

1.1、配置依赖

通过项目模块配置文件pom.xml进行引入JPA和MySQL的依赖

<!-- ... --><dependencies><!-- mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.21</version></dependency><!-- jpa--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency></dependencies><!-- ... -->

1.2、实体配置

在这里插入图片描述

实体-关系模型示例

下面对以上三个实体进行建模:
部门Deparment:

packagedbdemo.mysql.entity;importjavax.persistence.*;@Entity@Table(name="department")publicclassDepartment{@Id@GeneratedValue(strategy=GenerationType.IDENTITY)privateLong id;privateString name;publicDepartment(){}/**
     *省略 setter 以及getter方法。
     */}

用户User:

packagedbdemo.mysql.entity;importcom.fasterxml.jackson.annotation.JsonBackReference;importcom.fasterxml.jackson.annotation.JsonIgnore;importorg.springframework.format.annotation.DateTimeFormat;importjavax.persistence.*;importjava.util.Date;importjava.util.List;@Entity@Table(name="user")publicclassUserimplementsjava.io.Serializable{@Id@GeneratedValue(strategy=GenerationType.IDENTITY)privateLong id;privateString name;@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")privateDate createdate;@ManyToOne@JoinColumn(name="did")@JsonBackReferenceprivateDepartment deparment;@ManyToMany(cascade={}, fetch=FetchType.EAGER)@JoinTable(name="user_role",
            joinColumns={@JoinColumn(name="user_id")},
            inverseJoinColumns={@JoinColumn(name="roles_id")})privateList<Role> roles;publicUser(){}/**
     *省略 setter 以及getter方法。
     */}

角色Role:

packagedbdemo.mysql.entity;importjavax.persistence.*;@Entity@Table(name="role")publicclassRoleimplementsjava.io.Serializable{@Id@GeneratedValue(strategy=GenerationType.IDENTITY)privateLong id;privateString name;publicRole(){}/**
     *省略 setter 以及getter方法。
     */}

通过以上三个实体定义,实现了使用Java普通对象(POJO)与数据库表建立映射关系(ORM)。

1.3、JPA实现持久化

JPA是一个接口,继承JPA资源库JpaRepository接口,使用注解@Repository将该接口定义为一个资源库,为其他程序提供存取数据库的功能。

分别对三个实体使用JPA存取数据库实现持久化

packagedbdemo.mysql.repository;importdbdemo.mysql.entity.Department;importorg.springframework.data.jpa.repository.JpaRepository;importorg.springframework.stereotype.Repository;@RepositorypublicinterfaceDepartmentRepositoryextendsJpaRepository<Department,Long>{}
packagedbdemo.mysql.repository;importdbdemo.mysql.entity.Role;importorg.springframework.data.jpa.repository.JpaRepository;importorg.springframework.stereotype.Repository;@RepositorypublicinterfaceRoleRepositoryextendsJpaRepository<Role,Long>{}
packagedbdemo.mysql.repository;importdbdemo.mysql.entity.User;importorg.springframework.data.jpa.repository.JpaRepository;importorg.springframework.stereotype.Repository;importjava.util.Date;importjava.util.List;@RepositorypublicinterfaceUserRepositoryextendsJpaRepository<User,Long>{UserfindByNameLike(String name);UserreadByName(String name);List<User>getByCreatedateLessThan(Date star);}

1.4、测试

测试之前,需要保证Mysql中存在你想要访问的数据库,这里假设访问的数据库为test,而用户名设为 root ,密码为 admin。test数据库中是否存在对应的表table并不重要,因为Springboot运行后会帮你创建对应的表结构。

接下来进行实例测试来证明以上设计的正确性:

  1. 首先配置JPA配置类:JpaConfiguration.class
packagedbdemo.mysql.config;importorg.springframework.boot.orm.jpa.EntityScan;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.core.Ordered;importorg.springframework.core.annotation.Order;importorg.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;importorg.springframework.data.jpa.repository.config.EnableJpaRepositories;importorg.springframework.transaction.annotation.EnableTransactionManagement;@Order(Ordered.HIGHEST_PRECEDENCE)@Configuration@EnableTransactionManagement(proxyTargetClass=true)@EnableJpaRepositories(basePackages="dbdemo.**.repository")@EntityScan(basePackages="dbdemo.**.entity")publicclassJpaConfiguration{@BeanPersistenceExceptionTranslationPostProcessorpersistenceExceptionTranslationPostProcessor(){returnnewPersistenceExceptionTranslationPostProcessor();}}

各注解含义:

  • EnableTransactionManagement :启动JPA的事务管理
  • EnableJpaRepositories:启用JPA资源库并指定上面定义的接口资源库的位置;
  • EntityScan:指定了定义实体的所在位置,对我们所定义的实体进行导入

而在测试中使用的JPA配置类并不是像以上的配置这样简便,我们需要把一些配置参数都包含在用于测试的配置类类定义中,配置内容如下:

package dbdemo.mysql.test;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;

import javax.sql.DataSource;
import java.util.Properties;


@Configuration
@EnableJpaRepositories(basePackages = "dbdemo.**.repository")
public class JpaConfiguration {

    @Bean
    PersistenceExceptionTranslationPostProcessor persistenceExceptionTranslationPostProcessor(){
        return new PersistenceExceptionTranslationPostProcessor();
    }

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/test?characterEncoding=utf8");
        dataSource.setUsername("root");
        dataSource.setPassword("admin");

        return dataSource;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactoryBean.setDataSource(dataSource());
        entityManagerFactoryBean.setPackagesToScan("dbdemo.mysql.entity");
        entityManagerFactoryBean.setJpaProperties(buildHibernateProperties());
        entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter() {{
            setDatabase(Database.MYSQL);
        }});
        return entityManagerFactoryBean;
    }

    protected Properties buildHibernateProperties()
    {
        Properties hibernateProperties = new Properties();

        hibernateProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
        hibernateProperties.setProperty("hibernate.show_sql", "true");
        hibernateProperties.setProperty("hibernate.use_sql_comments", "false");
        hibernateProperties.setProperty("hibernate.format_sql", "true");
        hibernateProperties.setProperty("hibernate.hbm2ddl.auto", "update");
        hibernateProperties.setProperty("hibernate.generate_statistics", "false");
        hibernateProperties.setProperty("javax.persistence.validation.mode", "none");

        //Audit History flags
        hibernateProperties.setProperty("org.hibernate.envers.store_data_at_delete", "true");
        hibernateProperties.setProperty("org.hibernate.envers.global_with_modified_flag", "true");

        return hibernateProperties;
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        return new JpaTransactionManager();
    }

    @Bean
    public TransactionTemplate transactionTemplate() {
        return new TransactionTemplate(transactionManager());
    }
}
  1. 在Springboot的配置文件application.yml中天界配置来设置数据源和JPA的工作模式:
spring:datasource:url: jdbc:mysql://localhost:3306/test?characterEncoding=utf8username: rootpassword: adminjpa:database: MYSQLshow-sql:truehibernate:ddl-auto: updatenaming-strategy: org.hibernate.cfg.ImprovedNamingStrategyproperties:hibernate:dialect: org.hibernate.dialect.MySQL5Dialect

另外如果是利用application.properties文件进行配置的话,如下:

spring.datasource.url=jdbc:mysql://127.0.0.1:3306/how2java?characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=admin
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

jpa.database=MYSQL
jpa.show-sql=true

jpa.hibernate.ddl-auto=update
jpa.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy

jpa.properties.hibernate=
jpa.properties.dialect=org.hibernate.dialect.MySQL5Dialect
  1. 接下来编写MysqlTest测试类
  • 还有一件事 :
    测试用的程序都需要置于项目目录下的src/test/java目录下,否则不能正常进行测试
packagedbdemo.mysql.test;importdbdemo.mysql.entity.Department;importdbdemo.mysql.entity.Role;importdbdemo.mysql.entity.User;importdbdemo.mysql.repository.DepartmentRepository;importdbdemo.mysql.repository.RoleRepository;importdbdemo.mysql.repository.UserRepository;importorg.junit.Before;importorg.junit.Test;importorg.junit.runner.RunWith;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.data.domain.Page;importorg.springframework.data.domain.PageRequest;importorg.springframework.data.domain.Pageable;importorg.springframework.data.domain.Sort;importorg.springframework.test.context.ContextConfiguration;importorg.springframework.test.context.junit4.SpringJUnit4ClassRunner;importorg.springframework.util.Assert;importjava.util.*;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(classes={JpaConfiguration.class})publicclassMysqlTest{privatestaticLogger logger=LoggerFactory.getLogger(MysqlTest.class);@AutowiredUserRepository userRepository;@AutowiredDepartmentRepository departmentRepository;@AutowiredRoleRepository roleRepository;@BeforepublicvoidinitData(){
        userRepository.deleteAll();
        roleRepository.deleteAll();
        departmentRepository.deleteAll();Department department=newDepartment();
        department.setName("开发部");
        departmentRepository.save(department);Assert.notNull(department.getId());Role role=newRole();
        role.setName("admin");
        roleRepository.save(role);Assert.notNull(role.getId());User user=newUser();
        user.setName("user");
        user.setCreatedate(newDate());
        user.setDeparment(department);List<Role> roles= roleRepository.findAll();Assert.notNull(roles);
        user.setRoles(roles);

        userRepository.save(user);Assert.notNull(user.getId());}@TestpublicvoidfindPage(){Pageable pageable=newPageRequest(0,10,newSort(Sort.Direction.ASC,"id"));Page<User> page= userRepository.findAll(pageable);Assert.notNull(page);for(User user: page.getContent()){
            logger.info("====user==== user name:{}, department name:{}, role name:{}",
                    user.getName(), user.getDeparment().getName(), user.getRoles().get(0).getName());}}//@Testpublicvoidtest(){User user1= userRepository.findByNameLike("u%");Assert.notNull(user1);User user2= userRepository.readByName("user");Assert.notNull(user2);List<User> users= userRepository.getByCreatedateLessThan(newDate());Assert.notNull(users);}}

2、Redis


Redis是一种可以持久存储的缓存系统,是高性能的key-value数据库,Redis中的数据主要都存储在内存之中,只有部分存在硬盘之中,它通过json数据实现key-value数据的存储。
Redis官网下载

2.1、配置依赖

SpringBoot中使用Redis,也需要在工程中的Maven配置文件pom.xml中加入spring-boot-starter-redis依赖。
pom.xml中Redis模块的Maven依赖配置:

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-redis</artifactId></dependency><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.2.4</version></dependency><dependency><groupId>springboot.db</groupId><artifactId>mysql</artifactId><version>${project.version}</version></dependency></dependencies>

2.2、Redis服务类

Redis提供的数据类型如下:

  • string
  • hash
  • list
  • set 以及 zset

实例使用string字符串类型演示数据的存取操作。
Springboot并没有提供如JPA那样的资源库接口,需要根据Repository的定义写个User的服务类。

packagedbdemo.redis.repository;importcom.google.gson.Gson;importcom.google.gson.reflect.TypeToken;importdbdemo.mysql.entity.User;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.data.redis.core.RedisTemplate;importorg.springframework.stereotype.Repository;importorg.springframework.util.StringUtils;importjava.util.List;importjava.util.concurrent.TimeUnit;@RepositorypublicclassUserRedis{<
  • 作者:LP_bin
  • 原文链接:https://blog.csdn.net/weixin_40849588/article/details/99661146
    更新时间:2022-10-25 12:49:50