SpringBoot+Dubbo微服务用户中心实践-环境准备-Mysql集成

1、Mysql集成

      本文主要描述了以下几个问题:

        Mysql 集成:包括使用 Docker 部署 Mysql 的关键运行命令,如拉取镜像、创建保存数据及日志的目录、运行并配置相关参数。还举例说明了创建相关库表,如创建数据库和 sys_user 表。

        SpringBoot + SpringData JPA 配置:在 application.yml 中进行数据源配置及 JPA 的配置,如配置驱动、URL、用户名、密码等。以及实体类注解、ID生成器等相关代码说明

        配置问题说明:包括 Mysql 链接的时区配置、ddl-auto 的配置习惯、懒加载问题。

1.1、Docker部署Mysql        

 docker部署mysql比较简单,网上一大堆,本文只描述一些关键的运行命令,建议使用版本8.0

## 拉取mysql镜像
docker pull mysql

## 在宿主机创建几个目录用以保存mysql数据及日志,方便查看
# data、log、config三个文件

## docker运行
# 命名、端口映射、后台运行、挂载目录、root密码
docker run --name mysql -p 3306:3306 -d \
-v /home/docker_data/mysql/data:/var/lib/mysql \
-v /home/docker_data/mysql/log:/var/log/mysql \
-v /home/docker_data/mysql/config:/etc/mysql  \
-e MYSQL_ROOT_PASSWORD=root

1.2、创建相关库表

        本文只举例说明,主键统一使用SnowFlake(单机版)生成的32位ID,由SpringDataJPA主键策略配置并由业务服务生成。

-- 创建数据库
CREATE DATABASE IF NOT EXISTS account_center ;

-- 创建表
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user`  (
  `TENANT_ID` bigint NOT NULL COMMENT '租户号',
  `ORG_ID` bigint NOT NULL COMMENT '机构ID',
  `CREATED_BY` bigint NULL DEFAULT NULL COMMENT '创建人',
  `CREATED_TIME` datetime NULL DEFAULT NULL COMMENT '创建时间',
  `UPDATED_BY` bigint NULL DEFAULT NULL COMMENT '更新人',
  `UPDATED_TIME` datetime NULL DEFAULT NULL COMMENT '更新时间',
  `DELETED` bit(1) NULL DEFAULT b'0' COMMENT '删除标识',
  `USER_ID` bigint NOT NULL COMMENT '用户id',
  `USER_NAME` varchar(90) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户名',
  `STATUS` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '状态',
  `PASSWORD` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '密码,加密后',
  `NICK_NAME` varchar(125) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '昵称',
  `HEADER` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '头像',
  `PHONE_NO` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '手机号',
  `ADDRESS` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '地址',
  `EMAIL` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '邮箱地址',
  `EXPIRED_TIME` datetime NULL DEFAULT NULL COMMENT '失效时间',
  `TYPE` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '类型',
  PRIMARY KEY (`USER_ID`) USING BTREE,
  INDEX `idx_tenant_id`(`TENANT_ID` ASC) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '系统用户' ROW_FORMAT = Dynamic;

2、SpringBoot+SpringData JPA配置

        springdata jpa比较不符合咱们国服开发者的使用习惯,不管是从库表结构维护、表关系维护(国服大多数系统的物理层模型,已经不太建议做外键关联了)、懒加载策略等等,不过此处是为了折腾,也算是增长下见识。

2.1、SpringBoot配置

springboot的数据源配置及jpa的配置均在application.yml中进行配置,具体如下

spring:
  application:
    name: AcStarter
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/account_center?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false
    username: root
    password: root
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: none
    database: mysql
    open-in-view: true
    properties:
      hibernate:
        enable_lazy_load_no_trans: true        

2.2、实体类注解及ID生成器

        因为本文使用的项目不涉及表结构自动生成,所以一些注解的实际作用并没有用到,大家可百度具体的参数说明

2.2.1、基类及ID生成器

        将一些通用字段放到一个父类中,其他实体集成该父类可大大减少代码量,并提高代码的可读性。

       @MappedSuperclass:是标识该类为父类,不使用该注解,jpa获取不到父类中的字段映射关系

        @Id:主键标识

        @GenericGenerator及GeneratedValue:可指定具体的主键生成策略,本文使用的是自定义的主键生成策略(SnowFlake算法,见下方代码)

        @CreatedDate及@LastModifiedDate:数据创建时间及最后修改时间赋值标识

        @Column:字段映射配置(该处的nullable等其他配置在关闭auto-dll后不生效)

/**
 * 实体基类
 *
 * @Author: changjiang
 * @date: 2024/7/6 11:01 in beijing
 */
@MappedSuperclass
@Data
public abstract class BaseEntity {

    @Id
    @Comment("id")
    @Column(name = "ID", nullable = false)
    @GenericGenerator(name = "snowFlakeGenerator", strategy ="com.cj.ac.module.SnowFlakeGenerator")
    @GeneratedValue(generator = "snowFlakeGenerator")
    private Long id;

    @Comment("租户号")
    @Column(name = "TENANT_ID", nullable = false)
    private Long tenantId;

    @Comment("创建人")
    @Column(name = "CREATED_BY")
    private Long createdBy;

    @Comment("创建时间")
    @Column(name = "CREATED_TIME")
    @CreatedDate
    private Instant createdTime;

    @Comment("更新人")
    @Column(name = "UPDATED_BY")
    private Long updatedBy;

    @Comment("更新时间")
    @Column(name = "UPDATED_TIME")
    @LastModifiedDate
    private Instant updatedTime;

    @Comment("删除标识")
    @ColumnDefault("b'0'")
    @Column(name = "DELETED")
    private Boolean deleted = false;
}

/**
 * 雪花算法Id生成
 *
 * @Author: changjiang
 * SnowFakeGenerator
 * @date: 2024/7/6 11:05 in beijing
 */
public class SnowFlakeGenerator implements IdentifierGenerator, Configurable {

    @Override
    public Serializable generate(SharedSessionContractImplementor session, Object o) throws HibernateException {
        SnowflakeGenerator generator = new SnowflakeGenerator();
        return generator.next();
    }

    @Override
    public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
    }
}

2.2.2、业务类配置

        业务类配置主要包含表映射、字段映射、查询及逻辑删除等配置,具体如下:

        @Entity以及@Table:实体与表映射

        @SQLRestriction:查询时增加的条件

        @SQLDelete:物理删除转逻辑删除配置(是不如mybatis-plus注解好使)

        @EntityListeners:开启监听,开启后@CreatedDate及@LastModifiedDate生效

@Getter
@Setter
@Comment("系统用户")
@Entity
@Table(name = "sys_user")
@SQLRestriction("deleted = 0")
@SQLDelete(sql = "UPDATE `sys_user` set DELETED = 1 where ID = ?")
@EntityListeners(AuditingEntityListener.class)
public class User extends BaseEntity implements BeanConvertor<User, UserDTO> {

    @Comment("用户名")
    @Column(name = "USER_NAME", nullable = false, length = 90)
    private String userName;

    @Comment("账号")
    @Column(name = "ACCOUNT", nullable = false, length = 90)
    private String account;

    @Comment("状态")
    @Column(name = "STATUS", nullable = false, length = 50)
    private String status;

    @Comment("密码,加密后")
    @Column(name = "PASSWORD")
    private String password;

    @Comment("昵称")
    @Column(name = "NICK_NAME", length = 125)
    private String nickName;

    @Comment("头像")
    @Column(name = "HEADER")
    private String header;

    @Comment("手机号")
    @Column(name = "PHONE_NO", nullable = false)
    private String phoneNo;

    @Comment("地址")
    @Column(name = "ADDRESS")
    private String address;

    @Comment("邮箱地址")
    @Column(name = "EMAIL")
    private String email;

    @Comment("失效时间")
    @Column(name = "EXPIRED_TIME")
    private Instant expiredTime;

    @Comment("类型")
    @Column(name = "TYPE", length = 32)
    private String type;

    @Override
    public User convertT(UserDTO userDTO) {
        return null;
    }

    @Override
    public UserDTO convertS() {
        return BeanUtil.copyProperties(this, UserDTO.class);
    }
}

2.2.3、启动入口配置

        启动入口增加@EnableJpaAuditing注解,否则@CreatedDate及@LastModifiedDate不生效

3、配置问题说明

datasource-url

        注意mysql的链接,其中时区配置容易忽略,这个在较高版本的mysql驱动中,是需要额外配置的,配置GMT+8或者Asia/Shanghai,具体配置参考配置文件

ddl-auto

        我们国服一般的研发习惯是先进行数据库设计,再进行开发,进行编码的时候,其实库表结构已经存在了,不需要springdata jpa替我们创建,所以尽量关闭这个配置

懒加载问题

        jpa使用了hibernate的懒加载策略,这个策略可以减少系统运行过程的内存消耗,但是以此带来的session问题严重影响了开发节奏,开发者需要额外关心各实体之间的关系,比如说要查询用户的菜单,不使用主外键关系的情况下(此项目物理层模型不设计主外键关系),查询流程为:用户->角色->权限->菜单,在开启懒加载的策略下,同一个service线程中,查完用户,session就回收了,后续查询角色时就会报错。

        此时如果只是web访问模式,可以开启open-in-view: true这个策略,该配置是spring为了解决该问题提出的方案,即第一次查询用户后,session只是关闭,并不回收,第二次查询角色时,session开启,request结束,session回收。

        若项目内还有rpc调用,定时任务调用等服务调用该功能,open-in-view: true就不够用了,需要使用enable_lazy_load_no_trans: true来关闭懒加载策略。

        本系列文章一般不考虑资源消耗的问题,只是单纯的进行技术梳理,所以直接关闭了懒加载策略,当然也会导致其他的问题出现,比如查询用户到菜单的流程,springdata jpa调用的查询的次数为1(用户)+n(角色)+ n*m(权限)+n*m*t(菜单),具体原因及解决方案,本文不再描述,后续具体到用户角色设计时会详细说明。

        

  • 18
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值