vlambda博客
学习文章列表

「拥抱开源」从零开始 Docker、Mysql & JPA

MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一。

世界上最昂贵的东西是“免费”。

为了降低项目成本,我们有一套完整的 MySQL 开源社区版集群。希望能在低成本的基础上,带来期望的收益。

然而,经过不停的填坑操作告诉我们一个道理。

“免费” === 无人维护,商业运用还是 Oracle 关系型数据库来的香。



01 背景

这里是凭爱发电的开源项目 oPos。


考虑到将来还要自己全栈做 dev-ops,为了不给自己挖太深的坑。本项目的数据库存储采用以下技术选型:

  1. Docker ✔︎

  2. MySQL ✔︎

  3. Oracle 


本文的主要作用是记录 MySQL 安装与 JPA 的建表操作过程。为以后的技术复盘、运维做准备。


PS.欢迎大家 star: https://github.com/FoamValue/oPos.git



02 Docker 安装

Docker 是个好工具。

它是一个开源的虚拟应用容器引擎。随着云计算、AI、大数据等技术浪潮下,可以自动化部署、运维成千上万台服务器的 Docker 容器与虚拟技术,成为一件新的技术“神器”。


「拥抱开源」从零开始 Docker、Mysql & JPA


个人使用非常简单,直接下载安装程序即可。



03 Docker 安装 MySQL

首先,我们使用 search 命令来感受下 Docker 的强大。

罗列了所有 MySQL 的版本,再也没有寻找安装包该在哪里下载的痛苦了。

「拥抱开源」从零开始 Docker、Mysql & JPA


商业项目建议使用相对稳定的老版本,例如 5.6、5.7。

但,既然是开源项目。那就勇猛直前的最新 latest 版本就好。顺便还能感受下新的版本特性。

「拥抱开源」从零开始 Docker、Mysql & JPA


下载完成之后,可以使用 images 命令查看本地的镜像版本。例如:mysql latest,zookeeper 3.4.14。

「拥抱开源」从零开始 Docker、Mysql & JPA


目前,还没有部署测试环境的概念。

所以,现在选用“不建立映射目录”的方式运行。也就是,存储数据会丢失。

「拥抱开源」从零开始 Docker、Mysql & JPA


使用 Navicat 配置 MySQL 的访问方式。

「拥抱开源」从零开始 Docker、Mysql & JPA


创建一个 utf8 编码格式的数据库 oPos。


到这里,一个名叫 oPos 的关系型数据库就创建好了。



04 JPA 配置

在国内使用 JPA 来操作数据库,这样的运用场景是非常少的。

  1. 历史原因,大量的老开发人员习惯于 iBatis 操作数据库的风格。

  2. MyBatis 的出现,继承了 iBatis 的基础上,又进行了大量的优化。

  3. 在商业运用中,大量的 SQL 查询需要手动干预进行优化。


虽然,有更优秀的操作数据库的解决方案。但是,JPA 真的就没有优点了吗?

答案当然是:我也不知道。


JPA 特别适合中小型项目,它能帮助后端开发工程师更好的理解数据设计,让后端开发工程师把更多的时间、精力放在代码设计与优化之上。

至于 SQL 查询的销量,就让 JPA 自身优化去吧。


首先,在项目中引入 JPA、mysql 依赖包。

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


在 application-dev.yml 中增加数据库链接的配置。

spring: profiles: dev datasource: jdbcUrl: jdbc:mysql://127.0.0.1:3306/oPos?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true username: root password: 123456 driverClassName: com.mysql.cj.jdbc.Driver type: com.zaxxer.hikari.HikariDataSource hikari: poolName: hikari-local autoCommit: true connectionTestQuery: SELECT 1 connectionTimeout: 30000 idleTimeout: 30000 maxLifetime: 1800000 maximumPoolSize: 5 minimumIdle: 1 jpa: hibernate: ddl-auto: update show-sql: true


增加一个 MySQL 工厂与 Spring 事务配置类。

** * Application config. *  * @author chenxinjie * @date 2020-08-01 */@Configuration@EnableJpaRepositories@EnableTransactionManagementpublic class ApplicationConfig {
/** * data source. * * @return */ @Bean @ConfigurationProperties(prefix = "spring.datasource") public DataSource dataSource() { return DataSourceBuilder.create().build(); }
/** * entity manager factory. * * @return */ @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory() { HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); vendorAdapter.setGenerateDdl(true); LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); factory.setJpaVendorAdapter(vendorAdapter); factory.setPackagesToScan("cn.live.opos"); factory.setDataSource(dataSource()); return factory; }
/** * transaction manager. * * @param entityManagerFactory manager factory. * @return */ @Bean public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { JpaTransactionManager txManager = new JpaTransactionManager(); txManager.setEntityManagerFactory(entityManagerFactory); return txManager; }}


以上,JPA 操作数据库的配置就结束了。



05 JPA 创建表

上一节说到,JPA 可以帮助后段开发工程师更好的理解数据库设计,就体现这里。


以下是一张导购表的 JPA 实体 Java 类。

UscGuideEntity 使用了大量的 javax.persistence.* 注解进行修饰,这样的目的是在应用启动的过程中,程序会主动的像数据库中创建指定的表。

/** * usc_guide. *  * @author chenxinjie * @date 2020-08-01 */@Entity@Table(name = "usc_guide", uniqueConstraints = { @UniqueConstraint(columnNames = "no") })public class UscGuideEntity {
private static final long serialVersionUID = -5648617800765002770L;
@Id @GeneratedValue(strategy = GenerationType.AUTO, generator = "uuid") @GenericGenerator(name = "uuid", strategy = "uuid2") @Column(name = "id", length = 32) private String id;
@Column(name = "no", length = 20, nullable = false) private String no;
@Column(name = "name", length = 40, nullable = false) private String name;
@Column(name = "gender", columnDefinition = "int default 0", nullable = false) private int gender;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @Temporal(TemporalType.TIMESTAMP) @Column(name = "ts", columnDefinition = "timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP()", nullable = false) private Date ts;
public final String getId() { return id; }
public final void setId(String id) { this.id = id; }
public final String getNo() { return no; }
public final void setNo(String no) { this.no = no; }
public final String getName() { return name; }
public final void setName(String name) { this.name = name; }
public final int getGender() { return gender; }
public final void setGender(int gender) { this.gender = gender; }
public final Date getTs() { return ts; }
public final void setTs(Date ts) { this.ts = ts; }
public static final long getSerialversionuid() { return serialVersionUID; }
}


使用 Java 类来创建数据库表,这样的方式。将数据库表对象化,让后端开发人员非常的舒服。


当然,JPA 并不仅仅如此。它还有更加贴合手动建表的配置方式,例如:


1. 指定表名、唯一约束:

@Table(name = "usc_guide", uniqueConstraints = { @UniqueConstraint(columnNames = "no") })


2. 程序自动生成主键:

@Id@GeneratedValue(strategy = GenerationType.AUTO, generator = "uuid")@GenericGenerator(name = "uuid", strategy = "uuid2")@Column(name = "id", length = 32)private String id;


3. 字段长度、是否为空,等自定义配置:

@Column(name = "gender", columnDefinition = "int default 0", nullable = false)


4. 时间戳配置:

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")@Temporal(TemporalType.TIMESTAMP)@Column(name = "ts", columnDefinition = "timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP()", nullable = false)private Date ts;


5. 懒加载的一对多、多对多、一对一等配置:

@OneToMany(cascade = { CascadeType.REFRESH, CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE }, fetch = FetchType.LAZY, mappedBy = "orderEntity")private Set<OscOrderItemEntity> orderItems; @OneToOne@JoinColumn(name = "sku", referencedColumnName = "sku", insertable = false, updatable = false)private PscSkuEntity skuEntity;


6. 不挑数据库、换个数据库配置,就能自动建表。

7. 等等



06 小结

今天先写到这里。


夜深了,让我们下周再见。👋


这个周末,又一次成功“强迫”自己学习。


感谢各位小伙伴的阅读,这里是一个技术人的学习与分享。