首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

「拥抱开源」从零开始 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 容器与虚拟技术,成为一件新的技术“神器”。

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


03 Docker 安装 MySQL

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

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

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

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

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

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

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

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

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

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


04 JPA 配置

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

  1. 历史原因,大量的老开发人员习惯于 iBatis 操作数据库的风格。
  2. MyBatis 的出现,继承了 iBatis 的基础上,又进行了大量的优化。
  3. 在商业运用中,大量的 SQL 查询需要手动干预进行优化。

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

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

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

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

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

代码语言:javascript
复制
<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 中增加数据库链接的配置。

代码语言:javascript
复制
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 事务配置类。

代码语言:javascript
复制
**
 * Application config.
 * 
 * @author chenxinjie
 * @date 2020-08-01
 */
@Configuration
@EnableJpaRepositories
@EnableTransactionManagement
public 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.* 注解进行修饰,这样的目的是在应用启动的过程中,程序会主动的像数据库中创建指定的表。

代码语言:javascript
复制
/**
 * 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. 指定表名、唯一约束:

代码语言:javascript
复制
@Table(name = "usc_guide", uniqueConstraints = { @UniqueConstraint(columnNames = "no") })

2. 程序自动生成主键:

代码语言:javascript
复制
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
@Column(name = "id", length = 32)
private String id;

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

代码语言:javascript
复制
@Column(name = "gender", columnDefinition = "int default 0", nullable = false)

4. 时间戳配置:

代码语言:javascript
复制
@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. 懒加载的一对多、多对多、一对一等配置:

代码语言:javascript
复制
@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 小结

今天先写到这里。

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

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

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

下一篇
举报
领券