桌面生活

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数获取结果集的过程。MyBatis 可以使用简单的 XML注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。

关于 Mybatis 的基础知识可以查询官方文档,十分的详细。mybatis 官方文档.

本系列 Springboot 文章主要是 Springboot 的学习与分析,也因此只会试验 Mybatis 在 Springboot 中的一些用法,关于 Mybatis 的基础知识,还是需要自行学习的。
创建 Springboot 项目不提,引入 maven 依赖,主要是 mybastis 核心依赖以及一个 mybatis xml 自动生成插件。依赖中的 druid 数据源部分,可以参考系列文章第九篇。

  1. <dependencies>
  2. <!-- Spring Boot web 开发整合 -->
  3. <dependency>
  4. <groupId>org.springframework.boot</groupId>
  5. <artifactId>spring-boot-starter-web</artifactId>
  6. <exclusions>
  7. <exclusion>
  8. <artifactId>spring-boot-starter-json</artifactId>
  9. <groupId>org.springframework.boot</groupId>
  10. </exclusion>
  11. </exclusions>
  12. </dependency>
  13. <dependency>
  14. <groupId>org.springframework.boot</groupId>
  15. <artifactId>spring-boot-starter-test</artifactId>
  16. <scope>test</scope>
  17. </dependency>
  18. <!-- 阿里 fastjson -->
  19. <dependency>
  20. <groupId>com.alibaba</groupId>
  21. <artifactId>fastjson</artifactId>
  22. <version>1.2.47</version>
  23. </dependency>
  24. <!-- Lombok 工具 -->
  25. <dependency>
  26. <groupId>org.projectlombok</groupId>
  27. <artifactId>lombok</artifactId>
  28. <optional>true</optional>
  29. </dependency>
  30. <!-- 导入配置文件处理器,在配置springboot相关文件时候会有提示 -->
  31. <dependency>
  32. <groupId>org.springframework.boot</groupId>
  33. <artifactId>spring-boot-configuration-processor</artifactId>
  34. <optional>true</optional>
  35. </dependency>
  36. <!-- 单元测试 -->
  37. <dependency>
  38. <groupId>org.junit.jupiter</groupId>
  39. <artifactId>junit-jupiter-api</artifactId>
  40. <version>RELEASE</version>
  41. <scope>compile</scope>
  42. </dependency>
  43. <!-- Druid 数据源 -->
  44. <dependency>
  45. <groupId>com.alibaba</groupId>
  46. <artifactId>druid-spring-boot-starter</artifactId>
  47. <version>1.1.10</version>
  48. </dependency>
  49. <!-- mybatis -->
  50. <dependency>
  51. <groupId>org.mybatis.spring.boot</groupId>
  52. <artifactId>mybatis-spring-boot-starter</artifactId>
  53. <version>1.3.2</version>
  54. </dependency>
  55. <!-- mybatis mapper自动生成插件 -->
  56. <dependency>
  57. <groupId>org.mybatis.generator</groupId>
  58. <artifactId>mybatis-generator-core</artifactId>
  59. <version>1.3.7</version>
  60. <scope>compile</scope>
  61. <optional>true</optional>
  62. </dependency>
  63. <!--添加数据库链接 -->
  64. <dependency>
  65. <groupId>mysql</groupId>
  66. <artifactId>mysql-connector-java</artifactId>
  67. </dependency>
  68. </dependencies>

关于 Druid 数据源的配置不再说明,可以参考系列文章第九篇。配置中主要配置了项目编码、数据源信息、durid 数据源和 mybatis 的 mapper 位置以及 mybatis 映射别名的包路径。

  1. ############################################################
  2. # 服务启动端口号
  3. server.port=8080
  4. spring.profiles.active=dev
  5. # 编码
  6. server.tomcat.uri-encoding=utf-8
  7. spring.http.encoding.force=true
  8. spring.http.encoding.charset=UTF-8
  9. spring.http.encoding.enabled=true
  10. ############################################################
  11. spring.datasource.url=jdbc:mysql://127.0.0.1:3306/springboot?characterEncoding=utf-8&serverTimezone=GMT%2B8
  12. spring.datasource.driver-class-name= com.mysql.jdbc.Driver
  13. spring.datasource.username=root
  14. spring.datasource.password=123
  15. # 使用 druid 数据源
  16. spring.datasource.type: com.alibaba.druid.pool.DruidDataSource
  17. spring.datasource.initialSize: 5
  18. spring.datasource.minIdle: 5
  19. spring.datasource.maxActive: 20
  20. spring.datasource.maxWait: 60000
  21. spring.datasource.timeBetweenEvictionRunsMillis: 60000
  22. spring.datasource.minEvictableIdleTimeMillis: 300000
  23. spring.datasource.validationQuery: SELECT 1 FROM DUAL
  24. spring.datasource.testWhileIdle: true
  25. spring.datasource.testOnBorrow: false
  26. spring.datasource.testOnReturn: false
  27. spring.datasource.poolPreparedStatements: true
  28. spring.datasource.filters: stat
  29. spring.datasource.maxPoolPreparedStatementPerConnectionSize: 20
  30. spring.datasource.useGlobalDataSourceStat: true
  31. spring.datasource.connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
  32. # mybatis
  33. mybatis.mapper-locations=classpath:mapper/*.xml
  34. mybatis.type-aliases-package=net.codingme.boot.domain

mybatis 是半 ORM 框架,它通过 XML 描述符或者注解把 POJO 对象与 SQL 信息关联起来,也因为是和 SQL 关联起来,使用 mybatis 可以充分的利用数据的各种功能以及强大的 SQL 语句。也可以发发现使用 mybatis 至少应该建立 POJO 对象和 SQL 关联信息以及编写相关操作代码。

既然是持久层框架,先准备一个用户实验操作的数据表。上一个步骤中有配置数据库信息为 springboot。

  1. spring.datasource.url=jdbc:mysql://127.0.0.1:3306/springboot

因此在 mysql 数据库的 springboot 库中创建表 book 用于演示。
sql n CREATE TABLE `book` ( `id` int(11) NOT NULL AUTO_INCREMENT, `author` varchar(255) DEFAULT NULL COMMENT '书籍作者', `name` varchar(255) DEFAULT NULL COMMENT '书籍名称', `price` float NOT NULL COMMENT '书籍价格', `create_time` datetime NOT NULL COMMENT '创建时间', `description` varchar(255) DEFAULT NULL COMMENT '书籍描述', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8;
增加测试数据。

  1. INSERT INTO `springboot`.`book`(`id`, `author`, `name`, `price`, `create_time`, `description`) VALUES (2, '金庸', '笑傲江湖', 12, '2018-09-01 10:10:12', '是作家金庸创作的一部长篇武侠小说');
  2. INSERT INTO `springboot`.`book`(`id`, `author`, `name`, `price`, `create_time`, `description`) VALUES (3, '罗贯中', '三国演义', 22, '2018-09-01 10:10:16', '是作家罗贯中创作的一部长篇历史小说');
  3. INSERT INTO `springboot`.`book`(`id`, `author`, `name`, `price`, `create_time`, `description`) VALUES (4, '吴承恩', '西游记', 17, '2018-09-01 10:10:19', '是作家吴承恩创作的一部长篇小说');
  4. INSERT INTO `springboot`.`book`(`id`, `author`, `name`, `price`, `create_time`, `description`) VALUES (5, '金庸1535767819284', '笑傲江湖1535767819284', 43, '2018-09-01 10:10:19', '是作家金庸创作的一部长篇武侠小说1535767819284');
  5. INSERT INTO `springboot`.`book`(`id`, `author`, `name`, `price`, `create_time`, `description`) VALUES (6, '金庸1535767819679', '笑傲江湖1535767819679', 24, '2018-09-01 10:10:20', '是作家金庸创作的一部长篇武侠小说1535767819679');
  6. INSERT INTO `springboot`.`book`(`id`, `author`, `name`, `price`, `create_time`, `description`) VALUES (7, '罗贯中1535769035138', '三国演义1535769035138', 20, '2018-09-01 10:30:35', '是罗贯中创作的一部小说1535769035138');
  7. INSERT INTO `springboot`.`book`(`id`, `author`, `name`, `price`, `create_time`, `description`) VALUES (8, '金庸1535783611785', '笑傲江湖1535783611785', 30, '2018-09-01 14:33:32', '是作家金庸创作的一部长篇武侠小说1535783611785');

传统的 mybatis 开发过程需要依照数据表新建大量的 POJO 类,然后在编写响应的增删改查接口,继而编写增删改查对应的 XML 文件。过程无趣且有重复劳动,因此产生了一个自动生成工具,可以通过 JDBC 连接到数据库,自动的创建 POJO、操作接口、XML 文件。

在引入依赖的时候已经引入了自动生成插件,也就是 mybatis-generator-core

接着在项目根目录下创建自动生成配置文件,主要配置数据库信息和要生成的表已经生成的代码存放位置。
项目结构

在之前作者也介绍过,可以参考博客文章使用MyBatis Generator自动生成Model、Dao、Mapper相关代码

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE generatorConfiguration
  3. PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
  4. "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
  5. <generatorConfiguration>
  6. <context id="MysqlContext" targetRuntime="MyBatis3Simple" defaultModelType="flat">
  7. <property name="beginningDelimiter" value="`"/>
  8. <property name="endingDelimiter" value="`"/>
  9. <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
  10. connectionURL="jdbc:mysql://127.0.0.1:3306/springboot?characterEncoding=utf-8&amp;serverTimezone=GMT%2B8&amp;nullCatalogMeansCurrent=true"
  11. userId="root"
  12. password="123">
  13. </jdbcConnection>
  14. <!-- 对于生成的pojo所在包 -->
  15. <javaModelGenerator targetPackage="net.codingme.boot.domain" targetProject="src/main/java"/>
  16. <!-- 对于生成的mapper所在目录 -->
  17. <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources"/>
  18. <!-- 配置mapper对应的java映射 -->
  19. <javaClientGenerator targetPackage="net.codingme.boot.domain.mapper" targetProject="src/main/java"
  20. type="XMLMAPPER"/>
  21. <!-- 要生成那些表(更改tableName和domainObjectName就可以) -->
  22. <table tableName="book" domainObjectName="Book" enableCountByExample="true"
  23. enableUpdateByExample="true" enableUpdateByPrimaryKey="true"
  24. selectByExampleQueryId="true" enableDeleteByPrimaryKey="true"
  25. enableSelectByPrimaryKey="true" enableSelectByExample="true"
  26. ></table>
  27. </context>
  28. </generatorConfiguration>

写好配置文件之后,还需要写一个启动程序,用于加载配置文件,运行就可以生成相关配置。

  1. import org.mybatis.generator.api.MyBatisGenerator;
  2. import org.mybatis.generator.config.Configuration;
  3. import org.mybatis.generator.config.xml.ConfigurationParser;
  4. import org.mybatis.generator.internal.DefaultShellCallback;
  5. import java.io.File;
  6. import java.util.ArrayList;
  7. /**
  8. * <p>
  9. * Mybatis generator的逆向生成工具类
  10. *
  11. * @Author niujinpeng
  12. * @Date 2018/8/30 22:57
  13. */
  14. public class MybatisGenerator {
  15. public void generator() throws Exception {
  16. ArrayList<String> warnings = new ArrayList<>();
  17. boolean overwrite = true;
  18. // 指定你想工程配置文件
  19. File configFile = new File("generatorConfig.xml");
  20. System.out.println(configFile.getAbsolutePath());
  21. ConfigurationParser cp = new ConfigurationParser(warnings);
  22. Configuration config = cp.parseConfiguration(configFile);
  23. DefaultShellCallback callback = new DefaultShellCallback(overwrite);
  24. MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
  25. myBatisGenerator.generate(null);
  26. }
  27. public static void main(String[] args) throws Exception {
  28. MybatisGenerator mybatisGenerator = new MybatisGenerator();
  29. mybatisGenerator.generator();
  30. }
  31. }

生成的文件如下图。

项目结构

查看生成的接口以及 XML 映射文件可以发现已经自动生成了常用的几个方法。

  1. deleteByPrimaryKey
  2. insert
  3. updateByPrimaryKey
  4. selectByPrimaryKey
  5. selectAll

Mybatis 同样支持注解的方式配置映射关系,使用注解可以替代 XML 的配置,写一个简单的注解例子。在刚才生成的 BookMapper.java 中增加一个根据作者名称查询的方法,并映射字段对应的属性。

  1. // 添加 @Repository 注解,这样在使用 @Autowired 引入的时候不会报横线
  2. @Repository
  3. public interface BookMapper {
  4. /**
  5. * 注解方式配置映射
  6. *
  7. * @param author
  8. * @return
  9. * @Results 字段和属性映射关系
  10. * @Select 查询语句
  11. */
  12. @Results({
  13. @Result(property = "id", column = "ids"),
  14. @Result(property = "name", column = "name"),
  15. @Result(property = "author", column = "authors"),
  16. @Result(property = "createTime", column = "create_time")
  17. })
  18. @Select("select id as ids, author as authors, name, price, create_time, description from book where author = #{author}")
  19. List<Book> selectByAuthor(@Param("author") String author);
  20. // 省略下面自动生成代码

正常情况下会在项目中的业务层 service 包下创建接口和类然后通过注解引入使用。

  1. @Autowired
  2. private BookMapper bookMapper;

我们只是实验,没有这样写一套的必要,只要能确保 BookMapper 可以正常注入使用就好了。因此创建测试类进行测试。
创建测试类

在生成的(也可以完全手写测试方法)测试类中添加测试方法进行测试。

  1. @RunWith(SpringRunner.class)
  2. @SpringBootTest
  3. public class BookMapperTest {
  4. @Autowired
  5. private BookMapper bookMapper;
  6. @Test
  7. public void testSelectAll() {
  8. List<Book> bookList = bookMapper.selectAll();
  9. Assert.assertNotNull(bookList);
  10. bookList.forEach((book) -> System.out.println(book));
  11. }
  12. @Test
  13. public void testSelectByAuthro() {
  14. List<Book> bookList = bookMapper.selectByAuthor("金庸");
  15. Assert.assertNotNull(bookList);
  16. bookList.forEach((book) -> System.out.println(book));
  17. }
  18. @Test
  19. public void testSelectByPrimaryKey() {
  20. Book book = bookMapper.selectByPrimaryKey(2);
  21. Assert.assertNotNull(book);
  22. System.out.println(book);
  23. }
  24. public void testDeleteByPrimaryKey() {
  25. int primaryKey = bookMapper.deleteByPrimaryKey(8);
  26. Assert.assertNotEquals(0, primaryKey);
  27. System.out.println(primaryKey);
  28. }
  29. }

为了观察查询接口 book 的信息输出,重写 Book 类的 toString 方法,然后运行单元测试。

单元测试结果

可以发现测试全部通过。结果正常。
文章代码已经上传到 Github Spring Boot 连接数据库 – Mybatis

版权声明:本文为niumoo原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/niumoo/p/10488414.html