1.新建表
CREATE TABLE `key_value` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`biz_type` varchar(1000) NOT NULL DEFAULT 'DEFAULT' COMMENT '业务类型,用于需要区分业务的场景,一般情况为DEFAULT即可',
`key` varchar(1000) NOT NULL,
`value` text NOT NULL,
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`db_update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '数据记录更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_biztype_key` (`key`(128),`biz_type`(128)) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT='key-value配置表';
2.逆向工程配置文件
generatorConfig.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!-- JDBC Driver 这里需要改成各自本地的路径、不要删除别人的-->
<classPathEntry location="D:/.../mysql/mysql-connector-java/5.1.40/mysql-connector-java-5.1.40.jar" />
<context id="key_value_gen" targetRuntime="MyBatis3">
<!-- 处理数据库字段为sql关键字的情况 -->
<property name="autoDelimitKeywords" value="true"/>
<property name="beginningDelimiter" value="`"/>
<property name="endingDelimiter" value="`"/>
<!-- 这里引入扩展插件 -->
<plugin type="org.mybatis.generator.plugins.SerializablePlugin"/>
<commentGenerator>
<property name="suppressDate" value="true"/>
<!-- 是否去除自动生成的注释 true:是 : false:否 -->
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<!--数据库链接URL,用户名、密码 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
userId="root" password="************"
connectionURL="jdbc:mysql://127.0.0.1:3306/databaseX?autoReconnect=true&failOverReadOnly=false&zeroDateTimeBehavior=convertToNull">
</jdbcConnection>
<!--默认false
Java type resolver will always use java.math.BigDecimal if the database column is of type DECIMAL or NUMERIC.
-->
<javaTypeResolver>
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!--生成实体类 指定包名 以及生成的地址 (可以自定义地址,但是路径不存在不会自动创建 使用Maven生成在target目录下,会自动创建) -->
<javaModelGenerator targetPackage="dao.gen.po" targetProject="src/main/java">
<property name="enableSubPackages" value="false"/>
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!--生成Mapper.xml文件 -->
<sqlMapGenerator targetPackage="mybatis.mapper" targetProject="src/main/resources">
<property name="enableSubPackages" value="false"/>
</sqlMapGenerator>
<!--生成Dao文件 -->
<javaClientGenerator type="XMLMAPPER" targetPackage="dao.gen.mapper"
targetProject="src/main/java">
<property name="enableSubPackages" value="false"/>
</javaClientGenerator>
<table tableName="key_value" domainObjectName="KeyValuePO" enableDeleteByExample="false">
<generatedKey column="id" sqlStatement="MySql" identity="true"/>
<columnOverride column="biz_type" property="bizType" jdbcType="VARCHAR"
javaType="common.enums.KeyValueBizTypeEnum"
typeHandler="handler.KeyValueBizTypeEnumTypeHandler"/>
<columnOverride column="value" property="value" jdbcType="VARCHAR" javaType="java.lang.String"/>
</table>
</context>
</generatorConfiguration>
注意替换掉<classPathEntry ..." />,把jar包路径替换成自己的;数据库连接<jdbcConnection...>改成自己的。
3.mybatis与Spring整合
在database.xml配置文件中新增:
<!--mybatis与Spring整合 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="configLocation" value="classpath:SqlMapConfig.xml"/>
<property name="dataSource" ref="multipleDataSource"/>
<property name="mapperLocations">
<list>
<value>classpath:mybatis/mapper/**/*.xml</value>
</list>
</property>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="dao" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
4.新增Maven运行配置
在“Command line:”框输入:
mybatis-generator:generate -Dmybatis.generator.overwrite=true -Dmybatis.generator.contexts=key_value_gen -Dmybatis.generator.tableNames=key_value
配置完运行就好了。最终生成的文件:
5 类型转换——TypeHandler
如果表字段类型和java属性类型不一致,就需要用到类型转换。例如存储“开关”字段,数据库会存储0/1,java为了便于理解会通常是定义一个枚举类。
这里举个例子,我们在表里存储一个json类型的字段,然后在Java里把实际类型取出来。
CREATE TABLE `test_json` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键id',
`json_string` json DEFAULT NULL COMMENT 'json字符串',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='测试json';
然后写一个通用的JSON解析器:
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* JSON类型解析
* @param <T>
*/
public class JsonTypeHandler<T> extends BaseTypeHandler<T> {
private Class<T> clazz;
public JsonTypeHandler(Class<T> clazz) {
if (clazz == null) {
throw new IllegalArgumentException("Type argument cannot be null");
}
this.clazz = clazz;
}
@Override
public void setNonNullParameter(PreparedStatement preparedStatement, int i, T parameter,
JdbcType jdbcType) throws SQLException {
preparedStatement.setString(i, this.toJsonString(parameter));
}
@Override
public T getNullableResult(ResultSet resultSet, String s) throws SQLException {
String stringValue = resultSet.getString(s);
return resultSet.wasNull() ? null : this.parseJson(stringValue);
}
@Override
public T getNullableResult(ResultSet resultSet, int i) throws SQLException {
String stringValue = resultSet.getString(i);
return resultSet.wasNull() ? null : this.parseJson(stringValue);
}
@Override
public T getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
String stringValue = callableStatement.getString(i);
return callableStatement.wasNull() ? null : this.parseJson(stringValue);
}
private String toJsonString(Object obj) {
try {
return JSON.toJSONString(obj);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private T parseJson(String content) {
if (StringUtils.isBlank(content)) {
return null;
}
try {
return JSON.parseObject(content, clazz);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
把JSON对应的实际类型定义好:
/**
* @Description Json存储的对象
* @Author lilong
*/
public class TestJsonDetail {
private Integer switch1;
private String desc1;
public Integer getSwitch1() {
return switch1;
}
public void setSwitch1(Integer switch1) {
this.switch1 = switch1;
}
public String getDesc1() {
return desc1;
}
public void setDesc1(String desc1) {
this.desc1 = desc1;
}
}
然后在逆向工程配置文件里加上:
<table tableName="test_json" domainObjectName="TestJsonPO" enableDeleteByExample="false">
<generatedKey column="id" sqlStatement="MySql" identity="true"/>
<columnOverride column="json_string" property="jsonDetail" jdbcType="JSON"
javaType="entity.TestJsonDetail"
typeHandler="handler.JsonTypeHandler"/>
</table>
执行逆向工程的生成命令,生成:
其中,TestJsonPO的内容为:
import entity.TestJsonDetail;
public class TestJsonPO {
private Long id;
private TestJsonDetail jsonDetail;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public TestJsonDetail getJsonDetail() {
return jsonDetail;
}
public void setJsonDetail(TestJsonDetail jsonDetail) {
this.jsonDetail = jsonDetail;
}
}
可以看到,json已经转成了POJO