引言
在软件开发中,数据库操作是不可或缺的一部分。通常我们会使用mybatis,的MBG插件,自动生成表对应的基本操作语句xml。
当我们的表字段发生变化的时候,我们需要修改实体类和Mapper文件定义的字段和方法。如果是增量维护,那么一个个文件去修改。如果是全量替换,我们还要去对比用MBG生成的文件。字段变动一次就要修改一次,维护起来非常麻烦。
MBG
mybatis 代码生成工具 (https://github.com/mybatis/generator)
MBG(MyBatis Generator)是一个针对MyBatis和iBATIS的代码生成工具。以下是关于MBG的详细简单介绍:
1. 功能概述
- 代码生成:MBG能够自动生成与数据库表结构相匹配的Java POJO(Plain Old Java Object,简单的Java对象)、Mapper文件(DAO接口)以及XML映射文件。
- 支持版本:它支持所有版本的MyBatis以及iBATIS 2.2.0及以后的版本。
- CRUD操作:MBG可以内省数据库表,并生成用于访问这些表的基础对象,从而简化了与数据库表进行交互时的对象和配置文件创建过程。它主要解决了简单的CRUD(创建、检索、更新、删除)操作。
2. 生成的代码类型
- Java POJO :
- 匹配表主键的类(如果存在主键)
- 匹配表非主键字段的类(BLOB字段除外)
- 包含BLOB字段的类(如果表具有BLOB字段)
- 允许动态查询、更新和删除的类(如Example查询)
- Mapper文件(DAO接口):与MyBatis 3.x或iBATIS 2.x兼容的Mapper接口。
- XML映射文件:MyBatis/iBATIS兼容的SQL映射XML文件,包含用于简单CRUD操作的SQL语句。
3. 优点
- 提高开发效率:自动生成代码可以减少重复的编码工作,节省开发时间。
- 提高代码质量:自动生成的代码基本上是经过测试的,可以减少一些错误,提高代码的质量。
- 易于维护:自动生成的代码结构清晰,易于阅读和理解,方便维护。
- 可自定义:可以根据自己的需求定制生成规则,满足项目的特定需求。
4. 缺点
- 生成的代码可能不符合项目需求:生成的代码可能不完全符合项目的需求,需要手动修改。
- 学习成本:需要花时间学习生成工具的使用方法,可能需要一定的技术水平。
- 可能会覆盖已有代码:生成的代码可能会覆盖已有的代码,导致一些问题。
- 可能会导致代码冗余:生成的代码可能会存在冗余,需要手动清理。
5. 使用方法
- 配置MBG:在项目的构建配置文件中(如pom.xml)添加MBG的依赖,并创建MBG的配置文件(如generatorConfig.xml),配置数据库连接信息、Java模型生成器等相关设置。
- 运行MBG:通过构建工具(如Maven)运行MBG,根据配置文件生成代码。
6. 注意事项
- 在使用MBG时,应确保数据库表结构的准确性和完整性,以避免生成的代码出现问题。
- 根据项目的实际需求,合理配置MBG的生成规则,以满足项目的特定需求。
- 在使用生成的代码时,应仔细检查和测试,确保代码的正确性和稳定性。
通用Mapper的实现方案
mapper继承
第一个,因为MyBatis的Mapper是支持继承的(见:Can mybatis support mapper xml extend feature? · Issue #35 · mybatis/mybatis-3 · GitHub)。所以我们可以把我们的Mapper.xml和Mapper接口都分成两个文件。一个是MBG生成的,这部分是固定不变的。然后创建DAO类继承生成的接口,变化的部分就在DAO里面维护。
public interface UserMapperExt extends UserMapper {
public List<User> selectUserByName(String userName);
}
对应的映射文件
sql
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.boge.vip.mapper.UserMapperExt" >
<resultMap id="BaseResultMapExt" type="com.boge.vip.domain.User" >
<id column="id" property="id" jdbcType="INTEGER" />
<result column="user_name" property="userName" jdbcType="VARCHAR" />
<result column="real_name" property="realName" jdbcType="VARCHAR" />
<result column="password" property="password" jdbcType="VARCHAR" />
<result column="age" property="age" jdbcType="INTEGER" />
<result column="d_id" property="dId" jdbcType="INTEGER" />
<result column="i_id" property="iId" jdbcType="INTEGER" />
</resultMap>
<select id="selectUserByName" resultMap="BaseResultMapExt" >
select * from t_user where user_name = #{userName}
</select>
</mapper>
当然在全局配置文件里面我们需要增加这个mapper的扫描
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
<mapper resource="mapper/UserMapperExt.xml"/>
</mappers>
所以以后只要修改Ext的文件就可以了。这么做有一个缺点,就是文件会增多。
mybatis-plus
推荐使用。官网如下:快速开始 | MyBatis-Plus
这里贴一个例子,非常好用。
添加依赖,引入 MyBatis-Plus Starter 依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.6</version>
</dependency>
配置
在 application.yml
配置文件中添加 H2 数据库的相关配置:
application.yml
# DataSource Config
spring:
datasource:
driver-class-name: org.h2.Driver
username: root
password: test
sql:
init:
schema-locations: classpath:db/schema-h2.sql
data-locations: classpath:db/data-h2.sql
上面的配置是任何一个 Spring Boot 工程都会配置的数据库链接信息,如果您使用的是其他数据库,如 MySQL,则需要修改相应的配置信息。
在 Spring Boot 启动类中添加 @MapperScan
注解,扫描 Mapper 文件夹:
Application.java
@SpringBootApplication
@MapperScan("com.baomidou.mybatisplus.samples.quickstart.mapper")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
编码
编写实体类 User.java
:
User.java
@Data
public class User {
private Long id;
private String name;
private Integer age;
private String email;
}
编写 Mapper 接口类 UserMapper.java
:
public interface UserMapper extends BaseMapper<User> {
}
开始使用
添加测试类,进行功能测试:
@SpringBootTest
public class SampleTest {
@Autowired
private UserMapper userMapper;
@Test
public void testSelect() {
System.out.println(("----- selectAll method test ------"));
List<User> userList = userMapper.selectList(null);
Assert.isTrue(5 == userList.size(), "");
userList.forEach(System.out::println);
}
}
控制台输出:
User(id=1, name=Jone, age=18, email=test1@baomidou.com)
User(id=2, name=Jack, age=20, email=test2@baomidou.com)
User(id=3, name=Tom, age=28, email=test3@baomidou.com)
User(id=4, name=Sandy, age=21, email=test4@baomidou.com)
User(id=5, name=Billie, age=24, email=test5@baomidou.com)