在用mybatis进行javaweb项目开发中,少不了的就是写sql.xml文件,对于每个数据库表的操作,都要通过这些sql文件进行调用访问。后端开发中,每开发一个项目,都会有很多的表,也将会写对应的sql.xml文件,而且每个sql的基本操作都是那么一模一样的增删查改,所以为了方便开发,最近就写了一个代码程序来自动生成xml和dao层文件。
这里有一个前提,就是要用mybatis-generator生成对应entity和基本的mapping文件。mybatis-generator还能生成dao层文件,这里没用它是因为考虑到接口文件都大致一样,所以我对dao层接口做了一个泛型封装,每个接口集成这个就好。
写这个代码程序是有4个目的:生成自定义mapper文件,改写entity,生成dao文件,生成daoImpl文件。
1.生成自定义mapper文件
原理:根据mybatis-generator生成的文件中解析出数据库表和对应实体类的所有字段,及其表的名字,然后利用这些字段信息生成自定义的mapping文件。
mybatis-generator生成的源文件:代码程序主要是从BaseResultMap里获取字段信息的。
<?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="cn.wzy.sport.dao.Complain_InfoMapper" >
<resultMap id="BaseResultMap" type="cn.wzy.sport.entity.Complain_Info" >
<id column="id" property="id" jdbcType="INTEGER" />
<result column="co_userid" property="coUserid" jdbcType="INTEGER" />
<result column="co_content" property="coContent" jdbcType="VARCHAR" />
<result column="co_creatdate" property="coCreatdate" jdbcType="TIMESTAMP" />
</resultMap>
<sql id="Base_Column_List" >
id, co_userid, co_content, co_creatdate
</sql>
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
select
<include refid="Base_Column_List" />
from complain_info
where id = #{id,jdbcType=INTEGER}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
delete from complain_info
where id = #{id,jdbcType=INTEGER}
</delete>
<insert id="insert" parameterType="cn.wzy.sport.entity.Complain_Info" >
insert into complain_info (id, co_userid, co_content,
co_creatdate)
values (#{id,jdbcType=INTEGER}, #{coUserid,jdbcType=INTEGER}, #{coContent,jdbcType=VARCHAR},
#{coCreatdate,jdbcType=TIMESTAMP})
</insert>
<insert id="insertSelective" parameterType="cn.wzy.sport.entity.Complain_Info" >
insert into complain_info
<trim prefix="(" suffix=")" suffixOverrides="," >
<if test="id != null" >
id,
</if>
<if test="coUserid != null" >
co_userid,
</if>
<if test="coContent != null" >
co_content,
</if>
<if test="coCreatdate != null" >
co_creatdate,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides="," >
<if test="id != null" >
#{id,jdbcType=INTEGER},
</if>
<if test="coUserid != null" >
#{coUserid,jdbcType=INTEGER},
</if>
<if test="coContent != null" >
#{coContent,jdbcType=VARCHAR},
</if>
<if test="coCreatdate != null" >
#{coCreatdate,jdbcType=TIMESTAMP},
</if>
</trim>
</insert>
<update id="updateByPrimaryKeySelective" parameterType="cn.wzy.sport.entity.Complain_Info" >
update complain_info
<set >
<if test="coUserid != null" >
co_userid = #{coUserid,jdbcType=INTEGER},
</if>
<if test="coContent != null" >
co_content = #{coContent,jdbcType=VARCHAR},
</if>
<if test="coCreatdate != null" >
co_creatdate = #{coCreatdate,jdbcType=TIMESTAMP},
</if>
</set>
where id = #{id,jdbcType=INTEGER}
</update>
<update id="updateByPrimaryKey" parameterType="cn.wzy.sport.entity.Complain_Info" >
update complain_info
set co_userid = #{coUserid,jdbcType=INTEGER},
co_content = #{coContent,jdbcType=VARCHAR},
co_creatdate = #{coCreatdate,jdbcType=TIMESTAMP}
where id = #{id,jdbcType=INTEGER}
</update>
</mapper>
impl目录就是用来生成主要的语句文件:
<?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="cn.wzy.sport.dao.Complain_InfoMapper" >
<select id="selectByCondition" parameterType="org.cn.wzy.query.BaseQuery" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List"/>
FROM complain_info
<include refid="condition"/>
<include refid="order" />
<include refid="limit" />
</select>
<select id="selectCountByCondition" parameterType="org.cn.wzy.query.BaseQuery" resultType="java.lang.Integer">
SELECT
COUNT(*)
FROM complain_info
<include refid="condition"/>
</select>
<insert id="insertList" parameterType="java.util.List" useGeneratedKeys="false">
<foreach collection="list" item="item" index="index" separator=";" >
INSERT into complain_info
(co_userid,co_content,co_creatdate)
VALUES
(#{item.coUserid,jdbcType=INTEGER},#{item.coContent,jdbcType=VARCHAR},#{item.coCreatdate,jdbcType=TIMESTAMP})
</foreach>
</insert>
<delete id="deleteByIdsList" parameterType="java.util.List">
DELETE FROM complain_info
WHERE id IN
<foreach collection="list" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</delete>
<select id="selectByIds" parameterType="java.util.List" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List"/>
FROM complain_info
WHERE id In
<foreach collection="list" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</select>
</mapper>
然后sql目录就是用来存这些包括引用字段的,所以我叫做是impl文件的辅助文件,impl文件用到的一些判断啊,排序啊,就可以在这里面改,复用性也比较高。
<?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="cn.wzy.sport.dao.Complain_InfoMapper" >
<sql id="condition" >
WHERE 1 = 1
<if test="query.coUserid != null" >
AND co_userid = #{query.coUserid,jdbcType=INTEGER}
</if>
<if test="query.coContent != null" >
AND co_content = #{query.coContent,jdbcType=VARCHAR}
</if>
<if test="query.coCreatdate != null" >
AND co_creatdate = #{query.coCreatdate,jdbcType=TIMESTAMP}
</if>
<if test="query.id != null" >
AND id = #{query.id,jdbcType=INTEGER}
</if>
</sql>
<sql id="order" >
</sql>
<sql id="limit" >
<if test="start != null and rows != null" >
LIMIT #{start}, #{rows}
</if>
</sql>
</mapper>
2改写entity文件
改写是因为生成的文件都是含有很多的getter&setter方法,文件显得乱,开发中是用到了lombok,很方便的整理了这些看似繁多的代码。
mybatis-generator生成的源文件:
package cn.wzy.sport.entity;
import java.util.Date;
public class Complain_Info {
private Integer id;
private Integer coUserid;
private String coContent;
private Date coCreatdate;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getCoUserid() {
return coUserid;
}
public void setCoUserid(Integer coUserid) {
this.coUserid = coUserid;
}
public String getCoContent() {
return coContent;
}
public void setCoContent(String coContent) {
this.coContent = coContent == null ? null : coContent.trim();
}
public Date getCoCreatdate() {
return coCreatdate;
}
public void setCoCreatdate(Date coCreatdate) {
this.coCreatdate = coCreatdate;
}
}
改写后输出文件:
package cn.wzy.sport.entity;
import java.util.Date;
import lombok.*;
import lombok.experimental.Accessors;
/**
* Create by WzyGenerator
* on Mon Jul 16 18:27:09 CST 2018
* 不短不长八字刚好
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class Complain_Info {
private Integer id;
private Integer coUserid;
private String coContent;
private Date coCreatdate;
}
3.生成dao文件
我是通过泛型封装了一个basedao文件,生成dao层文件就直接继承ok:这里面的方法都是对应自定义生成的文件的方法。
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package org.cn.wzy.dao;
import java.util.List;
import org.cn.wzy.query.BaseQuery;
public interface BaseDao<Q> {
String getNameSpace();
int deleteByPrimaryKey(Integer var1);
int insert(Q var1);
int insertSelective(Q var1);
Q selectByPrimaryKey(Integer var1);
int updateByPrimaryKeySelective(Q var1);
int updateByPrimaryKeyWithBLOBs(Q var1);
int updateByPrimaryKey(Q var1);
List<Q> selectByCondition(BaseQuery<Q> var1);
Integer selectCountByCondition(BaseQuery<Q> var1);
int insertList(List<Q> var1);
int deleteByIdsList(List<Integer> var1);
List<Q> selectByIds(List<Integer> var1);
}
生成的文件:
package cn.wzy.sport.dao;
import cn.wzy.sport.entity.Complain_Info;
import org.cn.wzy.dao.BaseDao;
/**
* Create by WzyGenerator
* on Mon Jul 16 19:07:30 CST 2018
* 不短不长八字刚好
*/
public interface Complain_InfoDao extends BaseDao<Complain_Info> {
}
4.生成daoImpl文件
这里也是封装了一个basedaoimpl文件,所有的实现类继承就可以用,每个方法是basedao的实现,而且将容易出错的方法错误日志搜集。
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package org.cn.wzy.dao.impl;
import java.util.Date;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
import org.cn.wzy.dao.BaseDao;
import org.cn.wzy.query.BaseQuery;
import org.mybatis.spring.support.SqlSessionDaoSupport;
public abstract class BaseDaoImpl<Q> extends SqlSessionDaoSupport implements BaseDao<Q> {
private static final Logger log = Logger.getLogger(BaseDaoImpl.class);
public BaseDaoImpl() {
}
public int deleteByPrimaryKey(Integer id) {
return id == null ? -1 : this.getSqlSession().delete(this.getNameSpace() + ".deleteByPrimaryKey", id);
}
public int insert(Q record) {
return record == null ? -1 : this.getSqlSession().insert(this.getNameSpace() + ".insert", record);
}
public int insertSelective(Q record) {
if (record == null) {
return -1;
} else {
try {
return this.getSqlSession().insert(this.getNameSpace() + ".insertSelective", record);
} catch (Exception var3) {
log.error(new Date() + "--insertSelective--param:" + record + " failed");
return -1;
}
}
}
public Q selectByPrimaryKey(Integer id) {
return id == null ? null : this.getSqlSession().selectOne(this.getNameSpace() + ".selectByPrimaryKey", id);
}
public int updateByPrimaryKeySelective(Q record) {
if (record == null) {
return -1;
} else {
try {
return this.getSqlSession().update(this.getNameSpace() + ".updateByPrimaryKeySelective", record);
} catch (Exception var3) {
log.error(new Date() + "--updateByPrimaryKeySelective--param:" + record + " failed");
return -1;
}
}
}
public int updateByPrimaryKeyWithBLOBs(Q record) {
return record == null ? -1 : this.getSqlSession().update(this.getNameSpace() + ".updateByPrimaryKeyWithBLOBs", record);
}
public int updateByPrimaryKey(Q record) {
return record == null ? -1 : this.getSqlSession().update(this.getNameSpace() + ".updateByPrimaryKey", record);
}
public List<Q> selectByCondition(BaseQuery<Q> record) {
if (record == null) {
return null;
} else {
try {
return this.getSqlSession().selectList(this.getNameSpace() + ".selectByCondition", record);
} catch (Exception var3) {
log.error(new Date() + "--selectByCondition--param:" + record + " failed");
return null;
}
}
}
public Integer selectCountByCondition(BaseQuery<Q> record) {
if (record == null) {
return -1;
} else {
try {
return (Integer)this.getSqlSession().selectOne(this.getNameSpace() + ".selectCountByCondition", record);
} catch (Exception var3) {
log.error(new Date() + "--selectCountByCondition--param:" + record + " failed");
return -1;
}
}
}
public int insertList(List<Q> list) {
if (list == null) {
return -1;
} else {
SqlSession nowSession = this.getSqlSession();
try {
return nowSession.insert(this.getNameSpace() + ".insertList", list);
} catch (Exception var4) {
log.error(new Date() + "--insertList--param:" + list + " failed");
nowSession.rollback();
return -1;
}
}
}
public int deleteByIdsList(List<Integer> ids) {
if (ids == null) {
return -1;
} else {
SqlSession nowSession = this.getSqlSession();
try {
return this.getSqlSession().delete(this.getNameSpace() + ".deleteByIdsList", ids);
} catch (Exception var4) {
log.error(new Date() + "--insertList--param:" + ids + " failed");
nowSession.rollback();
return -1;
}
}
}
public List<Q> selectByIds(List<Integer> ids) {
if (ids == null) {
return null;
} else {
try {
return this.getSqlSession().selectList(this.getNameSpace() + ".selectByIds", ids);
} catch (Exception var3) {
log.error(new Date() + "--selectByIds--param:" + ids + " failed");
return null;
}
}
}
}
生成的文件:
package cn.wzy.sport.dao.impl;
import cn.wzy.sport.entity.Complain_Info;
import cn.wzy.sport.dao.Complain_InfoDao;
import org.cn.wzy.dao.impl.BaseDaoImpl;
import org.springframework.stereotype.Repository;
/**
* Create by WzyGenerator
* on Mon Jul 16 19:07:30 CST 2018
* 不短不长八字刚好
*/
@Repository
public class Complain_InfoDaoImpl extends BaseDaoImpl<Complain_Info> implements Complain_InfoDao {
@Override
public String getNameSpace() {
return "cn.wzy.sport.dao.Complain_InfoMapper";
}
}
所以只需要基本的三个文件,指定输出目录,调用执行函数,就可以直接完成dao层的开发:
运行效果:生成11个entity文件,11个dao接口,11个impl实现类,11个自定义mapper文件,11个自定义辅助sql文件。
自定义生成项目源码地址:https://github.com/1510460325/wzy.jar/tree/master/src/main/java/org/cn/wzy/util
如果是mvn项目,我也把这些程序打包放mvn中央仓库,引用请加下面的依赖项:
<dependency>
<groupId>com.github.1510460325</groupId>
<artifactId>core</artifactId>
<version>1.0.3</version>
</dependency>