MyBatis

说明

Zebra 微服务框架提供了一种简便通过 Mybatis 访问数据库的方法。

依赖引入

引入如下依赖

  1. <dependency>
  2. <groupId>com.guosen</groupId>
  3. <artifactId>zebra-database</artifactId>
  4. <version>${zebra.version}</version>
  5. </dependency>

代码编写

Mybatis Mapper XML

根据Mybatis规范编写对应的 mapper XML,mapper 文件需要遵循下面的规范:

  • 名称格式必须为 *Mapper.xml
  • 放到代码目录下 resources 下
  1. <!DOCTYPE mapper
  2. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  3. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  4. <mapper namespace="com.guosen.zebra.demo.database.hello.dao.StudentDao">
  5. <resultMap type="com.guosen.zebra.demo.database.hello.model.Student" id="StudentMap">
  6. <result column="name" property="name"/>
  7. <result column="clz" property="clz"/>
  8. <result column="description" property="description"/>
  9. </resultMap>
  10. <select id="getStudent" resultMap="StudentMap">
  11. select name, clz, description from t_student where name = #{name}
  12. </select>
  13. <update id="updateStudent">
  14. update t_student set clz = #{clz} where name = #{name}
  15. </update>
  16. </mapper>

Java 代码

  • 定义对应的 Mapper 接口
  1. package com.guosen.zebra.demo.database.hello.dao;
  2. import com.guosen.zebra.demo.database.hello.model.Student;
  3. import org.apache.ibatis.annotations.Param;
  4. public interface StudentDao {
  5. Student getStudent(@Param("name") String name);
  6. void updateStudent(@Param("name") String name, @Param("clz") String clz);
  7. }
  • 使用,其他地方使用 @Autowired 自动注入此 Dao 即可。

配置

配置样例

  1. zebra.database.url[0]=jdbc:jtds:sqlserver://172.24.140.84:1433/ngum
  2. zebra.database.username[0]=sa
  3. zebra.database.pwd[0]=password
  4. zebra.database.basePackage[0]=com.guosen.zebra.demo.database.hello
  5. zebra.database.dataSourceName[0]=gum
  6. logging.level.com.guosen.zebra.hello.mapper=debug

配置说明

支持最多 10 个数据源的配置, 0 <= k <= 9

配置项 类型 说明
zebra.database.url[k] String JDBC URL
zebra.database.username[k] String 数据库用户名
zebra.database.pwd[k] String 数据库密码
zebra.database.basePackage[k] String Mybatis 扫描的包
zebra.database.dataSourceName[k] String 数据源名称,确保唯一

高级功能

批量插入

说明

在插入大量数据的情况下,必须使用 Mybatis 的批量插入模式,否则插入速度会很慢。

通常开发者需要编写如下的代码:

  1. @Autowired
  2. private SqlSessionFactory sqlSessionFactory;
  3. public void batchCreate(List<Student> students) {
  4. try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false)) {
  5. StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
  6. for (Student student : students) {
  7. studentDao.create(student);
  8. }
  9. sqlSession.commit();
  10. sqlSession.clearCache();
  11. }
  12. }

存在如下问题:

  • 重复代码,每个批量插入的地方都要实现如上类似的逻辑
  • zebra 框架支持多数据源,当业务微服务使用多个数据源时,会在 Spring 中注入多个 SqlSessionFactory 的 bean,代码必须指定 bean 的名称(框架会使用“SqlSesssionFactory + 数据源名称”作为 bean 的名称),这样业务代码和配置、框架底层的实现紧紧耦合到了一起。

综上,Zebra微服务框架提供了一种简便的批量插入方法,开发者只需在对应的 mapper 接口方法上添加 @BatchInsert 注解,便可由框架代为批量插入。

代码实现

Mapper接口定义

  1. import com.guosen.model.Student;
  2. import org.mybatis.zebra.annotation.BatchInsert;
  3. import java.util.List;
  4. public interface StudentDao {
  5. Student get(String name);
  6. void create(Student student);
  7. @BatchInsert
  8. void batchCreate(List<Student> students);
  9. }

如上图,在 batchCreate 的方法上面添加 @BatchInsert 注解,同时必须确保batchCreate这个方法的只有一个且为 List 类型的参数

Mapper.xml

Mapper 文件中对应的 id 填上对应的 insert 语句,注意该 insert 的参数类型是 List 的元素的类型,而非 List 类型,一般不用配置。

在调用 Mapper batchCreate 接口时,传入多个待插入的对象,zebra 框架会多次调用 insert 语句,最后提交。

  1. <mapper namespace="com.guosen.dao.StudentDao">
  2. <resultMap type="com.guosen.model.Student" id="StudentMap">
  3. <result column="name" property="name"/>
  4. <result column="clz" property="clz"/>
  5. <result column="age" property="age"/>
  6. </resultMap>
  7. <insert id="batchCreate">
  8. insert into t_student (name, age, clz) values(#{name}, #{age}, #{clz})
  9. </insert>
  10. </mapper>