在mybatis generator自定义sql基本和自定义命名风格的流程一样,当然也需要我们去写代码,完成整个扩展
先修改org.mybatis.generator.api.IntrospectedTable.java类,在InternalAttribute增加自己需扩展的自定义方法枚举值,如想新增一个 selectList方法,定义一个ATTR_SELECT_LIST枚举值
protected enum InternalAttribute {
---省略部分代码---
ATTR_SELECT_LIST
}
在IntrospectedTable.java类中 新增一个setSelectListStatementId、getSelectListStatementId方法,在calculateXmlAttributes方法中调用setSelectListStatementId方法设置需要生成的方法名
protected void calculateXmlAttributes() {
---省略部分代码---
setSelectListStatementId("selectList");
}
public void setSelectListStatementId(String s){
internalAttributes.put(InternalAttribute.ATTR_SELECT_LIST,s);
}
public String getSelectListStatementId() {
return internalAttributes.get(InternalAttribute.ATTR_SELECT_LIST);
}
在org.mybatis.generator.codegen.mybatis3.xmlmapper新建一个extra包,新建一个SelectListElementGenerator.java类,这个类的作用就是在mapper.xml中实现自定义的sql语句
public class SelectListElementGenerator extends AbstractXmlElementGenerator {
public SelectListElementGenerator(){
super();
}
@Override
public void addElements(XmlElement parentElement) {
// 添加xml节点 - <select></select>
XmlElement answer = new XmlElement("select"); //$NON-NLS-1$
// select 标签中id属性
// 获取introspectedTable类中自己定义的方法名 --》setSelectListStatementId("selectList");
answer.addAttribute(new Attribute(
"id", introspectedTable.getSelectListStatementId())); //$NON-NLS-1$
// select 标签中resultMap属性
answer.addAttribute(new Attribute("resultMap", //$NON-NLS-1$
introspectedTable.getBaseResultMapId()));
// select 标签中parameterType属性
answer.addAttribute(new Attribute("parameterType", //$NON-NLS-1$
introspectedTable.getBaseRecordType()));
// 添加注释
context.getCommentGenerator().addComment(answer);
// 拼接sql语句
StringBuilder sb = new StringBuilder();
sb.append("select "); //$NON-NLS-1$
// 拼接 select
answer.addElement(new TextElement(sb.toString()));
// 拼接 需查询的字段
answer.addElement(getBaseColumnListElement());
// 是否有blob字段
if (introspectedTable.hasBLOBColumns()) {
answer.addElement(new TextElement(",")); //$NON-NLS-1$
answer.addElement(getBlobColumnListElement());
}
// 设置StringBuilder长度为0 -- 清空stringBuilder
sb.setLength(0);
// 拼接from
sb.append("from "); //$NON-NLS-1$
// 拼接表名
sb.append(introspectedTable
.getAliasedFullyQualifiedTableNameAtRuntime());
answer.addElement(new TextElement(sb.toString()));
//添加where条件
XmlElement whereXmlElement = new XmlElement("where");
answer.addElement(whereXmlElement);
//循环拼接所有的条件列
for (IntrospectedColumn introspectedColumn : introspectedTable.getAllColumns()) {
// 拼接 if判断
XmlElement selectNotNullElement = new XmlElement("if"); //$NON-NLS-1$
sb.setLength(0);
// java对象字段
sb.append(introspectedColumn.getJavaProperty());
sb.append(" != null ");
// 如果是字符型 增加 and column != ''
if (introspectedColumn.isJdbcCharacterColumn()){
sb.append("and ");
// java对象字段
sb.append(introspectedColumn.getJavaProperty());
sb.append(" != '' ");
}
selectNotNullElement.addAttribute(new Attribute("test", sb.toString()));
sb.setLength(0);
// 拼接实际的 赋值 “... where and 数据库字段 = java对象字段”
sb.append(" and "); //添加and
sb.append(MyBatis3FormattingUtilities
.getEscapedColumnName(introspectedColumn));
sb.append(" = "); //添加等号
sb.append(MyBatis3FormattingUtilities
.getParameterClause(introspectedColumn));
selectNotNullElement.addElement(new TextElement(sb.toString()));
whereXmlElement.addElement(selectNotNullElement);
}
parentElement.addElement(answer);
}
}
在org.mybatis.generator.codegen.mybatis3.xmlmapper.XMLMapperGenerator.java中新增addSelectListElement方法,方法中调用新建的SelectListElementGenerator类,同时在getSqlMapElement方法中调用addSelectListElement方法
protected XmlElement getSqlMapElement() {
---省略代码---
// mapper.xml中 -> 生成resultMap 标签内容
addResultMapWithoutBLOBsElement(answer);
// mapper.xml中 -> 生成sql 标签内容
addBaseColumnListElement(answer);
// mapper.xml中 -> 生成 select标签 id = selectOne
addSelectByPrimaryKeyElement(answer);
// mapper.xml中 -> 生成 insert标签 id = insert
addInsertSelectiveElement(answer);
// mapper.xml中 -> 生成 update标签 id = update
addUpdateByPrimaryKeySelectiveElement(answer);
// mapper.xml中 -> 生成 delete标签 id = delete
addDeleteByPrimaryKeyElement(answer);
// mapper.xml中 -> 生成 select标签 id = selectList
addSelectListElement(answer);
return answer;
}
protected void addSelectListElement(XmlElement parentElement) {
if (introspectedTable.getRules().generateSelectByPrimaryKey()) {
AbstractXmlElementGenerator elementGenerator = new SelectListElementGenerator();
initializeAndExecuteGenerator(elementGenerator, parentElement);
}
}
上面的步骤完成后,运行测试类,生成的mapper.xml文件中已经有了扩展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.cloud.dao.mapper.SysUserMapper">
<resultMap id="BaseResultMap" type="com.cloud.dao.po.SysUser">
<id column="id" jdbcType="VARCHAR" property="id" />
<result column="username" jdbcType="VARCHAR" property="username" />
<result column="password" jdbcType="VARCHAR" property="password" />
<result column="nickname" jdbcType="VARCHAR" property="nickname" />
<result column="dep_id" jdbcType="INTEGER" property="depId" />
<result column="pos_id" jdbcType="VARCHAR" property="posId" />
</resultMap>
<sql id="Base_Column_List">
id, username, password, nickname, dep_id, pos_id
</sql>
<select id="selectOne" parameterType="java.lang.String" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from t_sys_user
where id = #{id,jdbcType=VARCHAR}
</select>
<insert id="insert" parameterType="com.cloud.dao.po.SysUser">
insert into t_sys_user
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="username != null">
username,
</if>
<if test="password != null">
password,
</if>
<if test="nickname != null">
nickname,
</if>
<if test="depId != null">
dep_id,
</if>
<if test="posId != null">
pos_id,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=VARCHAR},
</if>
<if test="username != null">
#{username,jdbcType=VARCHAR},
</if>
<if test="password != null">
#{password,jdbcType=VARCHAR},
</if>
<if test="nickname != null">
#{nickname,jdbcType=VARCHAR},
</if>
<if test="depId != null">
#{depId,jdbcType=INTEGER},
</if>
<if test="posId != null">
#{posId,jdbcType=VARCHAR},
</if>
</trim>
</insert>
<update id="update" parameterType="com.cloud.dao.po.SysUser">
update t_sys_user
<set>
<if test="username != null">
username = #{username,jdbcType=VARCHAR},
</if>
<if test="password != null">
password = #{password,jdbcType=VARCHAR},
</if>
<if test="nickname != null">
nickname = #{nickname,jdbcType=VARCHAR},
</if>
<if test="depId != null">
dep_id = #{depId,jdbcType=INTEGER},
</if>
<if test="posId != null">
pos_id = #{posId,jdbcType=VARCHAR},
</if>
</set>
where id = #{id,jdbcType=VARCHAR}
</update>
<delete id="delete" parameterType="java.lang.String">
delete from t_sys_user
where id = #{id,jdbcType=VARCHAR}
</delete>
<select id="selectList" parameterType="com.cloud.dao.po.SysUser" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from t_sys_user
<where>
<if test="id != null and id != '' ">
and id = #{id,jdbcType=VARCHAR}
</if>
<if test="username != null and username != '' ">
and username = #{username,jdbcType=VARCHAR}
</if>
<if test="password != null and password != '' ">
and password = #{password,jdbcType=VARCHAR}
</if>
<if test="nickname != null and nickname != '' ">
and nickname = #{nickname,jdbcType=VARCHAR}
</if>
<if test="depId != null ">
and dep_id = #{depId,jdbcType=INTEGER}
</if>
<if test="posId != null and posId != '' ">
and pos_id = #{posId,jdbcType=VARCHAR}
</if>
</where>
</select>
</mapper>
在mapper.xml中已经成功生成了自定义sql,紧接着去完成方法的生成,在org.mybatis.generator.codegen.mybatis3.javamapper.elements包新建extra包,同时新增SelectListExtraMethodGenerator.java类。在这个类中我们完成对mapper方法的组装
public class SelectListExtraMethodGenerator extends AbstractJavaMapperMethodGenerator {
@Override
public void addInterfaceElements(Interface interfaze) {
// 组装方法[ 方法权限 返回类型 方法名 输入参数]
// selectList
Method method = new Method(introspectedTable.getSelectListStatementId());
method.setVisibility(JavaVisibility.PUBLIC);
method.setAbstract(true);
/* 导入相对应数据类型的包 */
Set<FullyQualifiedJavaType> importedTypes = new TreeSet<>();
/* 数据返回结果-List<Bean> */
FullyQualifiedJavaType returnType = FullyQualifiedJavaType.getNewListInstance();
FullyQualifiedJavaType listType =
new FullyQualifiedJavaType(introspectedTable.getBaseRecordType());
// importedType -> 导入对象的包
// import xxx.xxx
importedTypes.add(returnType);
importedTypes.add(listType);
// List<Object>
returnType.addTypeArgument(listType);
method.setReturnType(returnType);
/* 请求参数 */
FullyQualifiedJavaType parameterType = introspectedTable.getRules().calculateAllFieldsClass();
importedTypes.add(parameterType);
/* 设置请求参数 (Param param) */
method.addParameter(new Parameter(parameterType, "param")); //$NON-NLS-1$
/* 生成注释 */
context.getCommentGenerator().addGeneralMethodComment(method, introspectedTable);
if (context.getPlugins().clientSelectByPrimaryKeyMethodGenerated(method, interfaze, introspectedTable)) {
interfaze.addImportedTypes(importedTypes);
interfaze.addMethod(method);
}
}
}
在org.mybatis.generator.codegen.mybatis3.javamapper.JavaMapperGenerator.java中新增addSelectListeMethod方法,方法中new SelectListExtraMethodGenerator(),最后在getCompilationUnits中调用addSelectListeMethod方法
@Override
public List<CompilationUnit> getCompilationUnits() {
---省略部分代码---
// addCountByExampleMethod(interfaze);
// addDeleteByExampleMethod(interfaze);
// addDeleteByPrimaryKeyMethod(interfaze);
// addInsertMethod(interfaze);
// addInsertSelectiveMethod(interfaze);
// addSelectByExampleWithBLOBsMethod(interfaze);
// addSelectByExampleWithoutBLOBsMethod(interfaze);
// addSelectByPrimaryKeyMethod(interfaze);
// addUpdateByExampleSelectiveMethod(interfaze);
// addUpdateByExampleWithBLOBsMethod(interfaze);
// addUpdateByExampleWithoutBLOBsMethod(interfaze);
// addUpdateByPrimaryKeySelectiveMethod(interfaze);
// addUpdateByPrimaryKeyWithBLOBsMethod(interfaze);
// addUpdateByPrimaryKeyWithoutBLOBsMethod(interfaze);
addDeleteByPrimaryKeyMethod(interfaze);
addInsertSelectiveMethod(interfaze);
addUpdateByPrimaryKeySelectiveMethod(interfaze);
addSelectByPrimaryKeyMethod(interfaze);
addSelectListeMethod(interfaze);
---省略部分代码---
return answer;
}
protected void addSelectListeMethod(Interface interfaze) {
if (introspectedTable.getRules().generateSelectByPrimaryKey()) {
AbstractJavaMapperMethodGenerator methodGenerator = new SelectListExtraMethodGenerator();
initializeAndExecuteGenerator(methodGenerator, interfaze);
}
}
最后运行下测试类,selectList方法也已经有了
public interface SysUserMapper {
int delete(String id);
int insert(SysUser row);
int update(SysUser row);
SysUser selectOne(String id);
List<SysUser> selectList(SysUser param);
}
mapper.xml中的 xml节点间隔太紧凑了,在他们中间增加一个空行,修改org.mybatis.generator.codegen.mybatis3.xmlmapper.XMLMapperGenerator.java中的initializeAndExecuteGenerator即可
protected void initializeAndExecuteGenerator(AbstractXmlElementGenerator elementGenerator,
XmlElement parentElement) {
elementGenerator.setContext(context);
elementGenerator.setIntrospectedTable(introspectedTable);
elementGenerator.setProgressCallback(progressCallback);
elementGenerator.setWarnings(warnings);
// 标签与标签之间,增加空白隔行
parentElement.addElement(new TextElement(""));
elementGenerator.addElements(parentElement);
}
mybatis-generator生成的注释实在是不太友好,自己重新定义了mapper方法的注释以及po类注释
在org.mybatis.generator.internal包中新建一个extra包,在extra包下新建NotesCommentGenerator.java类,重新定义注释内容
public class NotesCommentGenerator extends DefaultCommentGenerator {
// 在mapper方法上添加注释
@Override
public void addGeneralMethodComment(Method method, IntrospectedTable introspectedTable) {
method.addJavaDocLine("/**"); //$NON-NLS-1$
// 方法名
method.addJavaDocLine(" * " + method.getName());
// 输入参数
if (method.getParameters() != null && method.getParameters().size() > 0){
for (Parameter parameter : method.getParameters()){
method.addJavaDocLine(" * @param " + parameter.getName());
}
}
// 返回结果
method.addJavaDocLine(" * @return " + method.getReturnType().get());
method.addJavaDocLine(" */"); //$NON-NLS-1$
}
// 在po类上添加注释
@Override
public void addModelClassComment(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
topLevelClass.addJavaDocLine("/**");
String remark = introspectedTable.getRemarks();
if (remark != null && !"".equals(remark)) {
topLevelClass.addJavaDocLine(" * " + remark);
}
topLevelClass.addJavaDocLine(" * ");
// 作者
topLevelClass.addJavaDocLine(" * " + "@author " + getAuthor());
// 日期
topLevelClass.addJavaDocLine(" * " + "@date " + getDateContent());
topLevelClass.addJavaDocLine(" */");
}
// 在po类属性上添加注释
@Override
public void addFieldComment(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
// 字段注释 - 数据库中对字段的说明
String remark = introspectedColumn.getRemarks();
if (remark != null && !"".equals(remark)) {
field.addJavaDocLine("/**");
field.addJavaDocLine(" * " + remark);
field.addJavaDocLine(" */");
}
}
}
在org.mybatis.generator.internal.DefaultCommentGenerator.java类中声明以下属性,同时在addConfigurationProperties方法中对新声明的属性赋值
/** 扩展属性 - 生成中文注释 */
private String author;
private String date;
private String dateContent;
private static final String DEFAULT_DATE_FORMAT = "yyyy/MM/dd";
@Override
public void addConfigurationProperties(Properties props) {
this.properties.putAll(props);
suppressDate = isTrue(properties.getProperty(PropertyRegistry.COMMENT_GENERATOR_SUPPRESS_DATE));
suppressAllComments = isTrue(properties.getProperty(PropertyRegistry.COMMENT_GENERATOR_SUPPRESS_ALL_COMMENTS));
addRemarkComments = isTrue(properties.getProperty(PropertyRegistry.COMMENT_GENERATOR_ADD_REMARK_COMMENTS));
String dateFormatString = properties.getProperty(PropertyRegistry.COMMENT_GENERATOR_DATE_FORMAT);
if (StringUtility.stringHasValue(dateFormatString)) {
dateFormat = new SimpleDateFormat(dateFormatString);
}
// 从配置文件中读取值
author = properties.getProperty("author");
author = author == null ? "" : author;
date = properties.getProperty("date");
date = date == null ? DEFAULT_DATE_FORMAT : date;
SimpleDateFormat sf = new SimpleDateFormat(date);
dateContent = sf.format(new Date());
}
public String getAuthor() {
return author;
}
public String getDateContent() {
return dateContent;
}
修改后的mybatis-generator-config.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>
<classPathEntry location="E:\development\repository\mysql\mysql-connector-java\8.0.28\mysql-connector-java-8.0.28.jar"/>
<context id="context" targetRuntime="MyBatis3">
<commentGenerator type="org.mybatis.generator.internal.extra.NotesCommentGenerator">
<!-- 文件编码 -->
<property name="javaFileEncoding" value="UTF-8" />
<!-- 忽略所有注解,使用自定义的注解生成 -->
<property name="suppressAllComments" value="true" />
<!-- 作者 -->
<property name="author" value="cloud" />
<!-- 时间 value值为时间格式-->
<property name="date" value="yyyy/MM/dd" />
</commentGenerator>
<!-- 数据库的相关配置 -->
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc-url"
userId="name"
password="password"/>
<javaTypeResolver>
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!-- 实体类生成的位置 -->
<javaModelGenerator targetPackage="com.cloud.dao.po"
targetProject="E:/local_project/idea/example/core/mybatis-example/src/main/java">
<property name="enableSubPackages" value="false"/>
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!-- *Mapper.xml 文件的位置 -->
<sqlMapGenerator targetPackage="mapper"
targetProject="E:/local_project/idea/example/core/mybatis-example/src/main/resources">
<property name="enableSubPackages" value="false"/>
</sqlMapGenerator>
<!-- Mapper 接口文件的位置 -->
<javaClientGenerator targetPackage="com.cloud.dao.mapper"
targetProject="E:/local_project/idea/example/core/mybatis-example/src/main/java"
type="XMLMAPPER">
<property name="enableSubPackages" value="false"/>
</javaClientGenerator>
<!-- 相关表的配置 -->
<table tableName="t_sys_user" domainObjectName="SysUser"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false"/>
</context>
</generatorConfiguration>
运行生成的结果如下
public interface SysUserMapper {
/**
* delete
* @param id
* @return int
*/
int delete(String id);
/**
* insert
* @param row
* @return int
*/
int insert(SysUser row);
/**
* update
* @param row
* @return int
*/
int update(SysUser row);
/**
* selectOne
* @param id
* @return com.cloud.dao.po.SysUser
*/
SysUser selectOne(String id);
/**
* selectList
* @param param
* @return java.util.List<com.cloud.dao.po.SysUser>
*/
List<SysUser> selectList(SysUser param);
}
/**
*
* @author cloud
* @date 2022/03/11
*/
public class SysUser {
/**
* 主键
*/
private String id;
/**
* 用户账号
*/
private String username;
/**
* 用户密码
*/
private String password;
/**
* 昵称
*/
private String nickname;
/**
* 部门id
*/
private Integer depId;
/**
* 岗位id
*/
private String posId;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id == null ? null : id.trim();
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username == null ? null : username.trim();
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password == null ? null : password.trim();
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname == null ? null : nickname.trim();
}
public Integer getDepId() {
return depId;
}
public void setDepId(Integer depId) {
this.depId = depId;
}
public String getPosId() {
return posId;
}
public void setPosId(String posId) {
this.posId = posId == null ? null : posId.trim();
}
}
没有下一篇了