本文介绍 Spring Boot 2 集成 MariaDB Connector/J 驱动连接 MySQL 数据库的方法。

目录

MariaDB Connector/J 简介

版本说明

代码示例

MariaDB Connector/J 简介

MariaDB 是一个开源关系型数据库,由 MySQL 的一些原始开发者领导,与 MySQL 保持高度兼容。

尽管 MySQL 官方提供了 MySQL Connector/J 驱动,但是因为使用了 GPL V2.0 协议,导致所有引用此驱动的软件都不得不开源,MariaDB Connector/J 驱动使用的是 LGPL V2.1 开源协议,对商业应用更加友好,因此可以使用 MariaDB Connector/J 替代 MySQL Connector/J 用于连接 MySQL 数据库。

版本说明

JDK 8

MySQL 8.x

MariaDB Connector/J 2.6.0

代码示例

创建存储用户信息的数据表。

CREATE TABLE `user` (

`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,

`name` VARCHAR(16) NOT NULL COMMENT '姓名',

`age` INT UNSIGNED NOT NULL COMMENT '年龄',

`email` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '电子邮箱',

PRIMARY KEY (`id`),

UNIQUE INDEX `uk_name` (`name` ASC)

) COMMENT='用户信息';

在生成的 pom 文件中添加 spring-boot-starter-jdbc 和 mariadb-java-client 依赖。

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

org.springframework.boot

spring-boot-starter-parent

2.2.7.RELEASE

tutorial.spring.boot

spring-boot-mysql-mariadb-driver

0.0.1-SNAPSHOT

spring-boot-mysql-mariadb-driver

1.8

org.springframework.boot

spring-boot-starter-jdbc

org.mariadb.jdbc

mariadb-java-client

2.6.0

org.springframework.boot

spring-boot-starter-test

test

org.junit.vintage

junit-vintage-engine

org.springframework.boot

spring-boot-maven-plugin

在 application.yml 中添加数据源配置。

spring:

datasource:

driver-class-name: org.mariadb.jdbc.Driver

username: root

password: 123456

url: jdbc:mysql://127.0.0.1:3306/test?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8&useSSL=false

编写映射数据表的领域模型类。

package tutorial.spring.boot.mysql.domain;

import java.util.Objects;

public class User {

/**

* 数据库表 user 列名

*/

public static class ColumnConstant {

public static final String ID = "id";

public static final String NAME = "name";

public static final String AGE = "age";

public static final String EMAIL = "email";

}

private Long id;

private String name;

private Integer age;

private String email;

public User(String name, Integer age, String email) {

this.name = name;

this.age = age;

this.email = email;

}

// Getter and Setter 略

@Override

public boolean equals(Object o) {

if (this == o) {

return true;

}

if (o == null || getClass() != o.getClass()) {

return false;

}

User user = (User) o;

if (!Objects.equals(name, user.name)) {

return false;

}

if (!Objects.equals(age, user.age)) {

return false;

}

return Objects.equals(email, user.email);

}

@Override

public int hashCode() {

int result = name != null ? name.hashCode() : 0;

result = 31 * result + (age != null ? age.hashCode() : 0);

result = 31 * result + (email != null ? email.hashCode() : 0);

return result;

}

// toString 略

}

编写 DAO(Data Access Object)层接口。

package tutorial.spring.boot.mysql.dao;

import tutorial.spring.boot.mysql.domain.User;

import java.sql.SQLException;

import java.util.List;

public interface UserDao {

/**

* 查询用户总数

*

* @return 记录总数

*/

int count() throws SQLException;

/**

* 根据 ID 删除用户

*

* @param id 用户ID,对应主键

* @return 删除记录数目

*/

int delete(long id);

/**

* 新增用户

*

* @param user 封装用户信息的User对象

* @return 插入记录主键

*/

long insert(User user) throws SQLException;

/**

* 批量新增用户

*

* @return 新增记录总数

*/

int insertBatch(List users);

/**

* 根据 ID 查询用户

*

* @param id 用户ID,对应主键

* @return 查询到的用户记录,如无对应记录则返回 null

*/

User select(long id);

/**

* 查询全部用户

*

* @return 封装用户信息的User对象列表

*/

List selectAll();

/**

* 更新用户

*

* @param user 封装用户信息的User对象

* @return 更新记录数

*/

int update(User user);

}

编写 DAO(Data Access Object)层实现。

package tutorial.spring.boot.mysql.dao.impl;

import org.springframework.jdbc.core.JdbcOperations;

import org.springframework.jdbc.support.GeneratedKeyHolder;

import org.springframework.jdbc.support.KeyHolder;

import org.springframework.stereotype.Repository;

import tutorial.spring.boot.mysql.dao.UserDao;

import tutorial.spring.boot.mysql.domain.User;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

import java.util.Arrays;

import java.util.List;

import java.util.Objects;

import java.util.stream.Collectors;

@Repository

public class UserDaoImpl implements UserDao {

private final JdbcOperations jdbcOperations;

public UserDaoImpl(JdbcOperations jdbcOperations) {

this.jdbcOperations = jdbcOperations;

}

@Override

public int count() throws SQLException {

String sql = "SELECT COUNT(*) FROM user";

Integer count = jdbcOperations.queryForObject(sql, Integer.class);

if (Objects.isNull(count)) {

throw new SQLException();

}

return count;

}

@Override

public int delete(long id) {

String sql = "DELETE FROM user WHERE id=?";

return jdbcOperations.update(sql, id);

}

@Override

public long insert(User user) throws SQLException {

if (Objects.isNull(user)) {

throw new IllegalArgumentException("Param[user] is null!");

}

final String sql = "INSERT INTO user ("

+ User.ColumnConstant.NAME + ", "

+ User.ColumnConstant.AGE + ", "

+ User.ColumnConstant.EMAIL + ") VALUES (?, ?, ?)";

KeyHolder keyHolder = new GeneratedKeyHolder();

jdbcOperations.update(connection -> {

PreparedStatement preparedStatement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);

preparedStatement.setString(1, Objects.isNull(user.getName()) ? "Anonymous User" : user.getName());

preparedStatement.setInt(2, Objects.isNull(user.getAge()) ? -1 : user.getAge());

preparedStatement.setString(3, Objects.isNull(user.getEmail()) ? "" : user.getEmail());

return preparedStatement;

}, keyHolder);

if (Objects.isNull(keyHolder.getKey())) {

throw new SQLException();

}

return keyHolder.getKey().longValue();

}

@Override

public int insertBatch(List users) {

List params = users.stream().map(user -> new Object[]{

user.getName(),

user.getAge(),

user.getEmail()

}).collect(Collectors.toList());

final String sql = "INSERT INTO user ("

+ User.ColumnConstant.NAME + ", "

+ User.ColumnConstant.AGE + ", "

+ User.ColumnConstant.EMAIL + ") VALUES (?, ?, ?)";

int[] result = jdbcOperations.batchUpdate(sql, params);

return Arrays.stream(result).sum();

}

@Override

public User select(long id) {

String sql = "SELECT "

+ User.ColumnConstant.ID + ", "

+ User.ColumnConstant.NAME + ", "

+ User.ColumnConstant.AGE + ", "

+ User.ColumnConstant.EMAIL

+ " FROM user WHERE id=?";

List users = jdbcOperations.query(sql, this::mapResultSetToUser, id);

return users.size() == 0 ? null : users.get(0);

}

private User mapResultSetToUser(ResultSet resultSet, int rowNum)

throws SQLException {

User user = new User(resultSet.getString(User.ColumnConstant.NAME),

resultSet.getInt(User.ColumnConstant.AGE),

resultSet.getString(User.ColumnConstant.EMAIL));

user.setId(resultSet.getLong(User.ColumnConstant.ID));

return user;

}

@Override

public List selectAll() {

String sql = "SELECT "

+ User.ColumnConstant.ID + ", "

+ User.ColumnConstant.NAME + ", "

+ User.ColumnConstant.AGE + ", "

+ User.ColumnConstant.EMAIL

+ " FROM user";

return jdbcOperations.query(sql, this::mapResultSetToUser);

}

@Override

public int update(User user) {

if (Objects.isNull(user)) {

throw new IllegalArgumentException("Param[user] is null!");

}

if (Objects.isNull(user.getId())) {

throw new IllegalArgumentException("The [id] attribute in param[user] is null!");

}

String sql = "UPDATE user SET name=?, age=?, email=? WHERE id=?";

return jdbcOperations.update(sql,

Objects.isNull(user.getName()) ? "Anonymous User" : user.getName(),

Objects.isNull(user.getAge()) ? -1 : user.getAge(),

Objects.isNull(user.getEmail()) ? "" : user.getEmail(),

user.getId()

);

}

}

基于 JUnit 5 和 Spring Boot 测试框架编写单元测试。

package tutorial.spring.boot.mysql.dao;

import org.assertj.core.api.Assertions;

import org.junit.jupiter.api.Order;

import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.test.context.SpringBootTest;

import org.springframework.transaction.annotation.Transactional;

import tutorial.spring.boot.mysql.domain.User;

import java.sql.SQLException;

import java.util.Arrays;

import java.util.List;

@SpringBootTest

@Transactional(rollbackFor = Exception.class)

public class UserDaoTest {

@Autowired

private UserDao userDao;

@Test

@Order(1)

public void testNotNull() {

Assertions.assertThat(userDao).isNotNull();

}

@Test

@Order(2)

public void testCount() throws SQLException {

Assertions.assertThat(userDao.count()).isEqualTo(0);

userDao.insert(new User("Tom", 32, "tom@zzz.org"));

userDao.insert(new User("Lily", 16, "lily@zzz.org"));

userDao.insert(new User("James", 28, "james@zzz.org"));

Assertions.assertThat(userDao.count()).isEqualTo(3);

}

@Test

@Order(3)

public void testDelete() throws SQLException {

long id = userDao.insert(new User("Harry", 12, "harry@magic.com"));

Assertions.assertThat(userDao.delete(id)).isEqualTo(1);

}

@Test

@Order(4)

public void testInsert() throws SQLException {

int count = userDao.count();

User user = new User("Jack", 18, "jack@xxx.com");

long id = userDao.insert(user);

Assertions.assertThat(id).isGreaterThan(0);

Assertions.assertThat(userDao.count()).isEqualTo(count + 1);

User result = userDao.select(id);

Assertions.assertThat(result).isEqualTo(user);

}

@Test

@Order(5)

public void testInsertBatch() {

List users = Arrays.asList(new User("Tom", 32, "tom@zzz.org"),

new User("Lily", 16, "lily@zzz.org"),

new User("James", 28, "james@zzz.org"),

new User("Jack", 18, "jack@xxx.com"));

Assertions.assertThat(userDao.insertBatch(users)).isEqualTo(4);

List allUsers = userDao.selectAll();

users.forEach(user -> Assertions.assertThat(allUsers.contains(user)).isTrue());

}

@Test

@Order(6)

public void testSelect() throws SQLException {

User user = new User("Lily", 16, "lily@zzz.org");

long id = userDao.insert(user);

User result = userDao.select(id);

Assertions.assertThat(result).isNotNull();

Assertions.assertThat(result).isEqualTo(user);

}

@Test

@Order(7)

public void testSelectAll() throws SQLException {

int count = userDao.count();

List users = Arrays.asList(new User("Tom", 32, "tom@zzz.org"),

new User("Lily", 16, "lily@zzz.org"),

new User("James", 28, "james@zzz.org"),

new User("Jack", 18, "jack@xxx.com"),

new User("Harry", 12, "harry@magic.com"));

Assertions.assertThat(userDao.insertBatch(users)).isEqualTo(5);

List allUsers = userDao.selectAll();

Assertions.assertThat(allUsers.size()).isGreaterThan(0);

Assertions.assertThat(userDao.count()).isEqualTo(count + 5);

users.forEach(user -> Assertions.assertThat(allUsers.contains(user)).isTrue());

}

@Test

@Order(8)

public void testUpdate() throws SQLException {

User user = new User("Jack", 18, "jack@xxx.com");

long id = userDao.insert(user);

user.setId(id);

User result1 = userDao.select(id);

Assertions.assertThat(result1).isEqualTo(user);

user.setName("Changed");

user.setAge(19);

user.setEmail("unknown@yyy.com");

Assertions.assertThat(userDao.update(user)).isEqualTo(1);

User result2 = userDao.select(id);

Assertions.assertThat(result2).isNotEqualTo(result1);

Assertions.assertThat(result2).isEqualTo(user);

}

}

执行过程略。

mysql connector开源协议_Spring Boot 集成 MariaDB Connector/J 连接 MySQL相关推荐

  1. flyway版本号_Spring Boot 集成 Flyway 实现数据库版本控制

    在项目迭代开发中,难免会有更新数据库 Schema 的情况,比如添加新表.在表中增加字段或者删除字段等,那么当我对数据库进行一系列操作后,如何快速地在其他同事的电脑上同步?如何在测试/生产服务器上快速 ...

  2. spring boot 缓存_Spring Boot 集成 Redis 实现数据缓存

    Spring Boot 集成 Redis 实现数据缓存,只要添加一些注解方法,就可以动态的去操作缓存了,减少代码的操作. 在这个例子中我使用的是 Redis,其实缓存类型还有很多,例如 Ecache. ...

  3. springboot dubbo引入包_spring boot 集成 dubbo 企业完整版

    一.什么是Spring Boot ? 现阶段的 Spring Boot 可谓是太火了,为什么呢?因为使用方便.配置简洁.上手快速,那么它是什么?从官网上我们可以看到,它是 Spring 开源组织下的一 ...

  4. hazelcast 搭建_Spring Boot集成Hazelcast实现集群与分布式内存缓存

    Hazelcast是Hazelcast公司开源的一款分布式内存数据库产品,提供弹性可扩展.高性能的分布式内存计算.并通过提供诸如Map,Queue,ExecutorService,Lock和JCach ...

  5. idea swagger生成接口文档_spring boot集成Swagger-UI接口文档

    本文介绍如何用spring boot集成Swagger-UI,实现项目在线接口文档 一.Swagger-UI简介 Swagger是一个Restful风格接口的文档在线自动生成和测试的框架 官网对Swa ...

  6. springboot 单测加入参数_Spring Boot集成Elasticsearch实战分享

    作者|java梦想口服液|简书 最近有读者问我能不能写下如何使用 Spring Boot 开发 Elasticsearch(以下简称 ES) 相关应用,今天就讲解下如何使用 Spring Boot 结 ...

  7. java beetl模板引擎_Spring Boot集成beetl模板引擎 个人总结

    1. Spring boot快速集成beetl模板引擎 查看官方文档:http://ibeetl.com/guide/#beetl 可参看官方文档 4.6. Spring Boot集成 增加beetl ...

  8. python mysql ssh隧道_在python中使用ssh隧道连接mysql

    通常为了保证数据库安全,不会允许直接连接数据库,而是需要通过SSH隧道去连接服务器背后的数据库: 今天我在用Python连接远程的MySQL时,直连遇到了无法连接的情况,使用了SSH隧道之后解决了问题 ...

  9. c ibatis mysql实例_[Java教程]java程序中的ibatis连接mySql的基本实例

    [Java教程]java程序中的ibatis连接mySql的基本实例 0 2015-03-16 00:01:32 属性文件:SqlMap.properties1 driver=com.mysql.jd ...

最新文章

  1. Atitit.java jna  调用c  c++ dll的原理与实践  总结  v2  q27
  2. R语言ggplot2可视化时间序列散点图、X轴和Y轴都是时间信息、使用as.POSIXct函数自定义指定Y轴的时间范围(setting time limits in y axis)
  3. C语言中的nan和inf使用
  4. 这个AI狠!能互译C++、Java和Python,以后只学一种编程就行吗
  5. 凭什么,Netty能成为最流行的NIO框架?
  6. 重启中的武汉:烟火气息回来了,消费疯狂增长
  7. 外媒:伊朗政府封锁加密通讯应用Signal
  8. 修改Eclipse的WorkSpace保持数[转载]
  9. VS2010+OpenCV2.4.6永久性配置方法
  10. 重写(Overriding)
  11. 基于matlab的车牌识别
  12. SQL Server上月同期 日期的计算
  13. Evenly Separated Strings
  14. 数理统计 -次序统计量、充分统计量
  15. 算法---逻辑智力题
  16. dasheddotted IE6爷爷居然认不出来的说……
  17. XTP控件ReportCtrl使用
  18. 【JVM · 字节码】指令集 解析说明
  19. 养生防癌:八大神效食物能杀死癌细胞
  20. 用于计算圆柱体体积和面积的Python程序

热门文章

  1. rbac模型的特点和优势_权限体系设计:融合了组织和岗位的权限模型长啥样?...
  2. java冒泡法排序实例_Java冒泡法排序实例
  3. @aspect注解_Spring自定义注解玩法大全,从入门到放弃
  4. html5 心,HTML5你必须知道的28个新特性
  5. python如何实现小车行走_[详细推导]基于EKF的小车运动模型的python编程实现
  6. 1小时搞懂设计模式之工厂模式(简单工厂)
  7. Maven中引入本地jar包
  8. jenkins安装部署全过程(linux)
  9. dos查看java环境变量_dos命令的识别及环境变量的设置实例
  10. flask框架(四):通过局域网访问网站