前言
入职3个月的时间,通过这3个月品管系统的开发,发现我50%的时间都浪费在复制粘贴代码上,以及在各个文件之间添接口和文件跳转上,我认为后端应该把主要的时间花在业务实现上,而且我认为公司应该在项目开发上结构保持统一。我对项目进行了简单总结,发现大部分的工作都是类似模板式的方法,这种代码不应该一行一行出来,所以我开发了一个针对公司项目的定制idea插件,通过插件生成项目的50%的代码,而且出错的概率能够减小一些,希望可以减少项目开发的周期。
公司有很多的中间件,比如发号器,wmonitor等组件,这些组件我希望可以通过idea插件一键式添加,直接把代码添加带项目中,包括很多工具类等。这部分功能暂时还没开发。
浪费了好n个周六周日,加了n天的班,踩过无数个坑,看了很多插件开发的api,看了mybatis generator的源码。完成了插件的初版,写一篇博客记录一下,主要是介绍一下插件的功能,插件主要分为3部分,mybatis文件的生成、文件创建、文件修改。
旨在一切需要复制粘贴的地方全部用插件生成
一、mybatis文件的生成
1.1 介绍
看了mybatis generator源码,对生成文件进行了深度定制,对产生文件不需要修改,可以直接使用。而且生成的文件符合公司开发的标准,包括继承baseBean,实现序列化等。
红框中的是对产生文件修改的代码,如果想按自己的意愿生成代码,重写上面的类即可。
1.2 使用说明
要使用插件首先要在项目中加一个名为“blibee.properties”配置文件,提前设置好里面的参数,文件可以放在项目中的任意位置,但尽量保证项目中只有一个配置文件。配置文件内容如下
# 数据库连接信息
jdbc.url=jdbc:mysql://localhost:3306/team5
jdbc.driver=com.mysql.jdbc.Driver
jdbc.username=root
jdbc.password=123456
# 主要字段,意思是根据code查询还是id,默认是id
BeeGenPlugin.mainColumn=code
# 是否是逻辑删除,true代表是
BeeGenPlugin.isLogicallyDeleted=true
# mapper.xml的后缀名
RenameSqlMapperPlugin.mapperXmlSuffix=Mapper
# 接口的的后缀名
RenameJavaMapperPlugin.interfaceMapperSuffix=Dao
# Query类后缀名
BeeGenPlugin.queryClassSuffix=Param
# Query类(查询类)的包名
BeeGenPlugin.queryPackage=com.bianlifeng.tempoon.aladdin.qcs.core.api.baseinfo.bean.param
# Query类java包的在磁盘中的绝对路径
BeeGenPlugin.queryProject=/Users/zk/Desktop/pin2/qcs-core-api/src/main/java
# 实体类的包名
javaModelGenerator.modelPackage=com.bianlifeng.tempoon.aladdin.qcs.core.model.baseinfo
# 实体类java包的在磁盘中的绝对路径
javaModelGenerator.modelProject=/Users/zk/Desktop/pin2/qcs-core/dao/src/main/java
# 接口类的包名
javaClientGenerator.interfaceMapperPackage=com.bianlifeng.tempoon.aladdin.qcs.core.dao.baseinfo
# 接口类java包的在磁盘中的绝对路径
javaClientGenerator.interfaceMapperProject=/Users/zk/Desktop/pin2/qcs-core/dao/src/main/java
# xml文件的包名
sqlMapGenerator.mapperXmlPackage=mappers
# 上面包的在磁盘上的绝对路径
sqlMapGenerator.mapperXmlProject=/Users/zk/Desktop/pin2/qcs-core/provider/src/main/resources/mybatis
1.2.1 Mybatis Generator
生成实体类,dao接口,映射文件,查询类。S
生成结果
package com.bianlifeng.tempoon.aladdin.qcs.core.model.baseinfo;
import com.wormpex.api.pojo.BaseBean;
import java.util.Date;
/**
* @table_name user
* @author ke.zhang02
* @date 2018-11-04
*/
public class User extends BaseBean {
private Integer userId;
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
/**
* 金额
*/
private Integer money;
private Date createTime;
private String code;
private String content;
private static final long serialVersionUID = -6623057708469335114L;
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getMoney() {
return money;
}
public void setMoney(Integer money) {
this.money = money;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
package com.bianlifeng.tempoon.aladdin.qcs.core.dao.baseinfo;
import com.bianlifeng.tempoon.aladdin.qcs.core.api.baseinfo.bean.param.UserParam;
import com.bianlifeng.tempoon.aladdin.qcs.core.model.baseinfo.User;
import java.util.List;
import org.apache.ibatis.annotations.Param;
public interface UserDao {
User selectByUserId(Integer record);
List<User> selectList(UserParam record);
List<User> selectPage(UserParam record);
int count(UserParam record);
int insert(User record);
int insertList(@Param("list") List<User> list);
int update(User record);
int deleteByUserId(Integer record);
int deleteList(@Param("list") List<User> list);
}
<?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.bianlifeng.tempoon.aladdin.qcs.core.dao.baseinfo.UserDao">
<resultMap id="BaseResultMap" type="com.bianlifeng.tempoon.aladdin.qcs.core.model.baseinfo.User">
<id column="user_id" jdbcType="INTEGER" property="userId" />
<result column="username" jdbcType="VARCHAR" property="username" />
<result column="password" jdbcType="VARCHAR" property="password" />
<result column="money" jdbcType="INTEGER" property="money" />
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
<result column="code" jdbcType="VARCHAR" property="code" />
<result column="content" jdbcType="LONGVARCHAR" property="content" />
</resultMap>
<sql id="Base_Column_List">
user_id,username,password,money,create_time,code,content
</sql>
<sql id="sql_where">
<where>
<if test="userId != null and userId != ''"> user_id = #{userId,jdbcType=INTEGER} </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="money != null and money != ''"> and money = #{money,jdbcType=INTEGER} </if>
<if test="createTime != null and createTime != ''"> and create_time = #{createTime,jdbcType=TIMESTAMP} </if>
<if test="code != null and code != ''"> and code = #{code,jdbcType=VARCHAR} </if>
<if test="content != null and content != ''"> and content = #{content,jdbcType=LONGVARCHAR} </if>
</where>
</sql>
<sql id="limit">
<if test='offset != 0 and limit != 0'>
limit #{offset}, #{limit}
</if>
<if test='offset == 0 and limit != 0'>
limit #{limit}
</if>
</sql>
<select id="selectByUserId" resultMap="BaseResultMap">
select <include refid="Base_Column_List" /> from user where user_id = #{userId,jdbcType=INTEGER}
</select>
<select id="selectList" resultMap="BaseResultMap">
select <include refid="Base_Column_List" /> from user
<include refid="sql_where"/>
ORDER BY create_time DESC
</select>
<select id="selectPage" resultMap="BaseResultMap">
select <include refid="Base_Column_List" /> from user
<include refid="sql_where"/>
ORDER BY create_time DESC
<include refid="limit"/>
</select>
<select id="count" resultType="java.lang.Integer">
SELECT COUNT(0) FROM user
<include refid="sql_where"/>
</select>
<insert id="insert" keyProperty="userId" parameterType="com.bianlifeng.tempoon.aladdin.qcs.core.model.baseinfo.User" useGeneratedKeys="true">
insert into user
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="username != null">username, </if>
<if test="password != null">password, </if>
<if test="money != null">money, </if>
<if test="createTime != null">create_time, </if>
<if test="code != null">code, </if>
<if test="content != null">content, </if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="username != null"> #{username,jdbcType=VARCHAR}, </if>
<if test="password != null"> #{password,jdbcType=VARCHAR}, </if>
<if test="money != null"> #{money,jdbcType=INTEGER}, </if>
<if test="createTime != null"> #{createTime,jdbcType=TIMESTAMP}, </if>
<if test="code != null"> #{code,jdbcType=VARCHAR}, </if>
<if test="content != null"> #{content,jdbcType=LONGVARCHAR}, </if>
</trim>
</insert>
<insert id="insertList" parameterType="java.util.List">
insert into user
(username,password,money,create_time,code,content)
values
<foreach collection ="list" item="item" index= "index" separator =",">
(#{item.username},#{item.password},#{item.money},#{item.createTime},#{item.code},#{item.content})
</foreach>
</insert>
<update id="update" parameterType="com.bianlifeng.tempoon.aladdin.qcs.core.model.baseinfo.User">
update user
<set>
<if test="username != null">username = #{username,jdbcType=VARCHAR},</if>
<if test="password != null">password = #{password,jdbcType=VARCHAR},</if>
<if test="money != null">money = #{money,jdbcType=INTEGER},</if>
<if test="createTime != null">create_time = #{createTime,jdbcType=TIMESTAMP},</if>
<if test="code != null">code = #{code,jdbcType=VARCHAR},</if>
<if test="content != null">content = #{content,jdbcType=LONGVARCHAR},</if>
</set>
where user_id = #{userId,jdbcType=INTEGER}
</update>
<delete id="deleteByUserId">
update user set del_status = 1 where user_id = #{userId}
</delete>
<delete id="deleteList">
update user set del_status = 1 where user_id in
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">#{item}</foreach>
</delete>
</mapper>
package com.bianlifeng.tempoon.aladdin.qcs.core.api.baseinfo.bean.param;
import com.wormpex.api.pojo.page.PageRequest;
import java.util.Date;
public class UserParam extends PageRequest {
private static final long serialVersionUID = -6706500633706438330L;
private Integer userId;
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
/**
* 金额
*/
private Integer money;
private Date createTime;
private String code;
private String content;
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getMoney() {
return money;
}
public void setMoney(Integer money) {
this.money = money;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
1.2.2 Add Sql Field
在.xml中添加数据库字段,右键xml文件,选择在数据库中新添加的字段,点击ok,会在xml中,补充字段,在实体类中补充字段,在Ao类中补充字段,在Vo中补充字段。
生产结果
?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.bianlifeng.tempoon.aladdin.qcs.core.dao.baseinfo.UserDao">
<resultMap id="BaseResultMap" type="com.bianlifeng.tempoon.aladdin.qcs.core.model.baseinfo.User">
<id column="user_id" jdbcType="INTEGER" property="userId" />
<result column="username" jdbcType="VARCHAR" property="username" />
<result column="password" jdbcType="VARCHAR" property="password" />
<result column="money" jdbcType="INTEGER" property="money" />
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
<result column="code" jdbcType="VARCHAR" property="code" />
<result column="content" jdbcType="LONGVARCHAR" property="content" />
<result column="new_column" jdbcType="INTEGER" property="newColumn"/>
</resultMap>
<sql id="Base_Column_List">
user_id,username,password,money,create_time,code,content,new_column
</sql>
<sql id="sql_where">
<where>
<if test="userId != null and userId != ''"> user_id = #{userId,jdbcType=INTEGER} </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="money != null and money != ''"> and money = #{money,jdbcType=INTEGER} </if>
<if test="createTime != null and createTime != ''"> and create_time = #{createTime,jdbcType=TIMESTAMP} </if>
<if test="code != null and code != ''"> and code = #{code,jdbcType=VARCHAR} </if>
<if test="content != null and content != ''"> and content = #{content,jdbcType=LONGVARCHAR} </if>
<if test="newColumn != null and newColumn != ''">and new_column = #{newColumn,jdbcType=INTEGER}</if>
</where>
</sql>
<sql id="limit">
<if test='offset != 0 and limit != 0'>
limit #{offset}, #{limit}
</if>
<if test='offset == 0 and limit != 0'>
limit #{limit}
</if>
</sql>
<select id="selectByUserId" resultMap="BaseResultMap">
select <include refid="Base_Column_List" /> from user where user_id = #{userId,jdbcType=INTEGER}
</select>
<select id="selectList" resultMap="BaseResultMap">
select <include refid="Base_Column_List" /> from user
<include refid="sql_where"/>
ORDER BY create_time DESC
</select>
<select id="selectPage" resultMap="BaseResultMap">
select <include refid="Base_Column_List" /> from user
<include refid="sql_where"/>
ORDER BY create_time DESC
<include refid="limit"/>
</select>
<select id="count" resultType="java.lang.Integer">
SELECT COUNT(0) FROM user
<include refid="sql_where"/>
</select>
<insert id="insert" keyProperty="userId" parameterType="com.bianlifeng.tempoon.aladdin.qcs.core.model.baseinfo.User" useGeneratedKeys="true">
insert into user
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="username != null">username, </if>
<if test="password != null">password, </if>
<if test="money != null">money, </if>
<if test="createTime != null">create_time, </if>
<if test="code != null">code, </if>
<if test="content != null">content, </if>
<if test="newColumn != null">new_column,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="username != null"> #{username,jdbcType=VARCHAR}, </if>
<if test="password != null"> #{password,jdbcType=VARCHAR}, </if>
<if test="money != null"> #{money,jdbcType=INTEGER}, </if>
<if test="createTime != null"> #{createTime,jdbcType=TIMESTAMP}, </if>
<if test="code != null"> #{code,jdbcType=VARCHAR}, </if>
<if test="content != null"> #{content,jdbcType=LONGVARCHAR}, </if>
<if test="newColumn != null">#{newColumn,jdbcType=INTEGER},</if>
</trim>
</insert>
<insert id="insertList" parameterType="java.util.List">
insert into user
(username,password,money,create_time,code,content,new_column)
values
<foreach collection="list" item="item" index="index" separator=",">
(#{item.username},#{item.password},#{item.money},#{item.createTime},#{item.code},#{item.content},#{item.newColumn})
</foreach>
</insert>
<update id="update" parameterType="com.bianlifeng.tempoon.aladdin.qcs.core.model.baseinfo.User">
update user
<set>
<if test="username != null">username = #{username,jdbcType=VARCHAR},</if>
<if test="password != null">password = #{password,jdbcType=VARCHAR},</if>
<if test="money != null">money = #{money,jdbcType=INTEGER},</if>
<if test="createTime != null">create_time = #{createTime,jdbcType=TIMESTAMP},</if>
<if test="code != null">code = #{code,jdbcType=VARCHAR},</if>
<if test="content != null">content = #{content,jdbcType=LONGVARCHAR},</if>
<if test="newColumn != null">new_column = #{newColumn,jdbcType=INTEGER},</if>
</set>
where user_id = #{userId,jdbcType=INTEGER}
</update>
<delete id="deleteByUserId">
update user set del_status = 1 where user_id = #{userId}
</delete>
<delete id="deleteList">
update user set del_status = 1 where user_id in
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">#{item}</foreach>
</delete>
</mapper>
/**
* null
*/
private Integer newColumn;
二、项目文件的生成
2.1 介绍
这部分插件主要是生成一些项目文件,包括Service文件及其实现,biz文件及其实现,remote文件及其实现,controller文件及其实现,单元测试文件,adaptor文件等,Aobean文件,VoBean文件 及其实现等。
2.2 使用说明
2.2.1 New Service File
右键项目包路径,文件会生成到这个包里面。选择Dao层的接口文件。
生成结果:
2.2.2 New ServiceImpl File
右键项目包路径,文件会生成到这个包里面。选择service接口文件。
生成结果:
2.2.3 New AoBean File
右键项目包路径,文件会生成到这个包里面。选择Bean文件。
生成结果:
2.2.4 New VoBean File
右键项目包路径,文件会生成到这个包里面。选择Bean文件。
生成结果
2.2.5 New Adaptor File
右键项目包路径,文件会生成到这个包里面。填写类名,选择类型,这里要注意,类名一定要以Adaptor结尾,前面的内容是实体类的名称,一定要写对,否到找不到类,导不进去报名。
生成结果:
2.2.6 New Biz Interface File
右键项目包路径,文件会生成到这个包里面。填写类名,一定要以Biz结尾。改生成里面并没有什么方法。需要手动写,但只要把,把结果方法定义好就行,通过New Biz Impl File,插件可以给你生成实现类,不需要自己创建。
生成结果:
2.2.7 New Biz Impl File
右键项目包路径,文件会生成到这个包里面。选择Biz接口文件。先在接口中创建两个方法。
生成结果:
2.2.8 New Remote File
右键项目包路径,文件会生成到这个包里面。选择Dao层的Biz接口文件:
生成结果:
2.2.9 New RemoteImpl File
右键项目包路径,文件会生成到这个包里面。选择Romote接口文件:
生成结果:
2.2.10 New Test File
生成单元测试文件,右键项目包路径,文件会生成到这个包里面。改该功能是根据接口文件生成单测,既可以生成service单测,也可以生成biz单测。
生成结果:
2.2.11 New Controller File
右键项目包路径,文件会生成到这个包里面。选择man层biz接口文件件:
生成结果:
三、编辑页面代码生成
3.1 介绍
这部分插件主要是选择编辑页文本,在文件中添加代码。
3.2 使用说明
3.2.1 Add Method Impl
添加方法实现,这要是指文件都已经创建完毕,想在接口文件中新加一个方法。选中接口文件中新加的方法,右键方法名。方法名一定要是选中状态。
结果:
在Biz层使用,会在Biz层往上生成
3.2.2 Add Method Test
根据接口方法,在测试文件中添加单元测试。
结果:
3.2.3 Add Resource Bean
添加@Resource的参数。比如在service中添加Dao类,在biz中添加service和remote等。编辑页中右键
结果:
3.2.4 Add Annotion
批量在方法上添加注解。例如添加如下两个注解:
//如果添加全类名,会自动导包,否则需要手动导包
@com.bianlifeng.tempoon.aladdin.qcs.core.service.common.wmonitor.RecordTime(parent = STATISTICS_QUERY_EFFICIENCY)
@Transactional(rollbackFor = StatusCodeException.class)
结果:
3.2.5 Bean Assignment
快捷对new的实体类赋值,选中实体类名称
结果:
3.2.6 Add CheckParams
快速添加bizTemplate参数校验,选中bizImpl文件中的方法名:
结果:
3.2.7 Add Pager Impl
快速完成pager方法,选中类名称,选则需要的service接口
结果: