Mybatis官方提供了逆向生成的工程的工厂类,这个可以针对mybatis执行所需要的对应数据库中单表的pojo类,以及pojo类和SQL以及其对应的Mapper文件,都可以逆向生成,同时,这个有较多的生成方式:maven插件,基于xml配置的和基于java Configuration类 的java program。
一般情况下我们使用第4种生成方式,通过一个xml配置文件和java program类生成所需要的上述文件。首先我们可以先建立一个空的Java工程,在java工程里面添加引用对应的jar包,构建好工程之后需要配置generatorConfig.xml文件。这些步骤在前面的文章中提到过了,具体参考此链接。
这次需要分析一下生成的文件和运行的简要原理:
我们了解到,这个工程应对与单表查询逆向生成比较方便,但是对于多表查询和复杂的sql语句等支持不好,复杂的sql语句还需要开发者自己编写配置,一般的对于单表查询起会生成以下这几种文件:
1.POJO类行的java文件:
这个是对应于数据库中指定表中的字段生成的,一般情况下会根据表名字来命名文件名如下面的文件是查询newstyles数据库中的Tb_Item表格,则包含的字段都会被写入到TbItempojo类中,生成文件(文件路径在相关连接的文档中已经给出)如下:
package com.newstyles.pojo;
import java.util.Date;
public class TbItem {
private Long id;
private String title;
private String sellPoint;
private Long price;
private Integer num;
private String barcode;
private String image;
private Long cid;
private Byte status;
private Date created;
private Date updated;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title == null ? null : title.trim();
}
public String getSellPoint() {
return sellPoint;
}
public void setSellPoint(String sellPoint) {
this.sellPoint = sellPoint == null ? null : sellPoint.trim();
}
public Long getPrice() {
return price;
}
public void setPrice(Long price) {
this.price = price;
}
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
}
public String getBarcode() {
return barcode;
}
public void setBarcode(String barcode) {
this.barcode = barcode == null ? null : barcode.trim();
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image == null ? null : image.trim();
}
public Long getCid() {
return cid;
}
public void setCid(Long cid) {
this.cid = cid;
}
public Byte getStatus() {
return status;
}
public void setStatus(Byte status) {
this.status = status;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public Date getUpdated() {
return updated;
}
public void setUpdated(Date updated) {
this.updated = updated;
}
}
你会发现,看这个类很容易和方便,因为其是一个简单的类对象,里面仅有对应的属性和修改属性的getter和setter方法,同时以了解到,如果需要mybatis工程运行,仅有这个是不行的,还需要有关于数据库操作的定义的Mapper接口和一个对应的能够编写sql的Mapper的xml配置文件。接下来展示第二类文件,*****Mapper.java:
2. TbItemMapper.java
package com.newstyles.mapper;
import com.newstyles.pojo.TbItem;
import com.newstyles.pojo.TbItemExample;
import java.util.List;
import org.apache.ibatis.annotations.Param;
public interface TbItemMapper {
int countByExample(TbItemExample example);
int deleteByExample(TbItemExample example);
int deleteByPrimaryKey(Long id);
int insert(TbItem record);
int insertSelective(TbItem record);
List<TbItem> selectByExample(TbItemExample example);
TbItem selectByPrimaryKey(Long id);
int updateByExampleSelective(@Param("record") TbItem record, @Param("example") TbItemExample example);
int updateByExample(@Param("record") TbItem record, @Param("example") TbItemExample example);
int updateByPrimaryKeySelective(TbItem record);
int updateByPrimaryKey(TbItem record);
}
你会发现其声明的类型为接口,这正符合的mybatis工程运行的规则,首先,mybatis除了Config.xml文件外,还需要对应数据库的pojo类和相对应的关于数据库操作的Mapper接口类,我们知道,这个接口不需要我们其实现,但是,需要我们给予一个相对应的****mapper.xml文件进行相关的配置,主要包括确定对应接口中方法的配置,数据类型和返回数据类型的配置,以及返回结果的操作,sql查询语句的编写。对此我们需要了解一下,这个接口中,定义的接口中的各个方法的含义:
方法 | 功能概要 |
---|---|
int countByExample(UserExample example) thorws SQLException | 按条件计数 |
int deleteByPrimaryKey(Integer id) thorws SQLException | 按主键删除 |
int deleteByExample(UserExample example) thorws SQLException | 按条件查询 |
String/Integer insert(User record) thorws SQLException | 插入数据(返回值为ID) |
User selectByPrimaryKey(Integer id) thorws SQLException | 按主键查询 |
ListselectByExample(UserExample example) thorws SQLException | 按条件查询 |
ListselectByExampleWithBLOGs(UserExample example) thorws SQLException | 按条件查询(包括BLOB字段)。只有当数据表中的字段类型有为二进制的才会产生。 |
int updateByPrimaryKey(User record) thorws SQLException | 按主键更新 |
int updateByPrimaryKeySelective(User record) thorws SQLException | 按主键更新值不为null的字段 |
int updateByExample(User record, UserExample example) thorws SQLException | 按条件更新 |
int updateByExampleSelective(User record, UserExample example) thorws SQLException | 按条件更新值不为null的字段 |
同时观察到,我们里面有很多的***Example类型的实例化对象,mybatis的逆向工程中会生成实例及实例对应的example,example用于添加条件,相当where后面的部分 例如,select id,note from tb_xxx where id = 2
xxxExample example = new xxxExample();
Criteria criteria = new Example().createCriteria();//这个为具体的条件规则的类
方法 | 说明 |
---|---|
example.setOrderByClause(“字段名 ASC”); | 添加升序排列条件,DESC为降序 |
example.setDistinct(false) | 去除重复,boolean型,true为选择不重复的记录。 |
criteria.andXxxIsNull | 添加字段xxx为null的条件 |
criteria.andXxxIsNotNull | 添加字段xxx不为null的条件 |
criteria.andXxxEqualTo(value) | 添加xxx字段等于value条件 |
criteria.andXxxNotEqualTo(value) | 添加xxx字段不等于value条件 |
criteria.andXxxGreaterThan(value) | 添加xxx字段大于value条件 |
criteria.andXxxGreaterThanOrEqualTo(value) | 添加xxx字段大于等于value条件 |
criteria.andXxxLessThan(value) | 添加xxx字段小于value条件 |
criteria.andXxxLessThanOrEqualTo(value) | 添加xxx字段小于等于value条件 |
criteria.andXxxIn(List<?>) | 添加xxx字段值在List<?>条件 |
criteria.andXxxNotIn(List<?>) | 添加xxx字段值不在List<?>条件 |
criteria.andXxxLike(“%”+value+”%”) | 添加xxx字段值为value的模糊查询条件 |
criteria.andXxxNotLike(“%”+value+”%”) | 添加xxx字段值不为value的模糊查询条件 |
criteria.andXxxBetween(value1,value2) | 添加xxx字段值在value1和value2之间条件 |
criteria.andXxxNotBetween(value1,value2) | 添加xxx字段值不在value1和value2之间条件 |
3. ****Mapper.xml
这个是一个跟随***Mapper.java一起生成的文件,具体的生成代码如下:
<?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.newstyles.mapper.TbItemMapper" >
<resultMap id="BaseResultMap" type="com.newstyles.pojo.TbItem" >
<!-- 设置列和属性之间的转换,转换为jdbc的数据类型 -->
<id column="id" property="id" jdbcType="BIGINT" />
<result column="title" property="title" jdbcType="VARCHAR" />
<result column="sell_point" property="sellPoint" jdbcType="VARCHAR" />
<result column="price" property="price" jdbcType="BIGINT" />
<result column="num" property="num" jdbcType="INTEGER" />
<result column="barcode" property="barcode" jdbcType="VARCHAR" />
<result column="image" property="image" jdbcType="VARCHAR" />
<result column="cid" property="cid" jdbcType="BIGINT" />
<result column="status" property="status" jdbcType="TINYINT" />
<result column="created" property="created" jdbcType="TIMESTAMP" />
<result column="updated" property="updated" jdbcType="TIMESTAMP" />
</resultMap>
<sql id="Example_Where_Clause" >
<where >
<foreach collection="oredCriteria" item="criteria" separator="or" >
<if test="criteria.valid" >
<trim prefix="(" suffix=")" prefixOverrides="and" >
<foreach collection="criteria.criteria" item="criterion" >
<choose >
<when test="criterion.noValue" >
and ${criterion.condition}
</when>
<when test="criterion.singleValue" >
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue" >
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue" >
and ${criterion.condition}
<foreach collection="criterion.value" item="listItem" open="(" close=")" separator="," >
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Update_By_Example_Where_Clause" >
<where >
<foreach collection="example.oredCriteria" item="criteria" separator="or" >
<if test="criteria.valid" >
<trim prefix="(" suffix=")" prefixOverrides="and" >
<foreach collection="criteria.criteria" item="criterion" >
<choose >
<when test="criterion.noValue" >
and ${criterion.condition}
</when>
<when test="criterion.singleValue" >
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue" >
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue" >
and ${criterion.condition}
<foreach collection="criterion.value" item="listItem" open="(" close=")" separator="," >
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Base_Column_List" >
id, title, sell_point, price, num, barcode, image, cid, status, created, updated
</sql>
<select id="selectByExample" resultMap="BaseResultMap" parameterType="com.newstyles.pojo.TbItemExample" >
select
<if test="distinct" >
distinct
</if>
<include refid="Base_Column_List" />
from tb_item
<if test="_parameter != null" >
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null" >
order by ${orderByClause}
</if>
</select>
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long" >
select
<include refid="Base_Column_List" />
from tb_item
where id = #{id,jdbcType=BIGINT}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Long" >
delete from tb_item
where id = #{id,jdbcType=BIGINT}
</delete>
<delete id="deleteByExample" parameterType="com.newstyles.pojo.TbItemExample" >
delete from tb_item
<if test="_parameter != null" >
<include refid="Example_Where_Clause" />
</if>
</delete>
<insert id="insert" parameterType="com.newstyles.pojo.TbItem" >
insert into tb_item (id, title, sell_point,
price, num, barcode,
image, cid, status,
created, updated)
values (#{id,jdbcType=BIGINT}, #{title,jdbcType=VARCHAR}, #{sellPoint,jdbcType=VARCHAR},
#{price,jdbcType=BIGINT}, #{num,jdbcType=INTEGER}, #{barcode,jdbcType=VARCHAR},
#{image,jdbcType=VARCHAR}, #{cid,jdbcType=BIGINT}, #{status,jdbcType=TINYINT},
#{created,jdbcType=TIMESTAMP}, #{updated,jdbcType=TIMESTAMP})
</insert>
<insert id="insertSelective" parameterType="com.newstyles.pojo.TbItem" >
insert into tb_item
<trim prefix="(" suffix=")" suffixOverrides="," >
<if test="id != null" >
id,
</if>
<if test="title != null" >
title,
</if>
<if test="sellPoint != null" >
sell_point,
</if>
<if test="price != null" >
price,
</if>
<if test="num != null" >
num,
</if>
<if test="barcode != null" >
barcode,
</if>
<if test="image != null" >
image,
</if>
<if test="cid != null" >
cid,
</if>
<if test="status != null" >
status,
</if>
<if test="created != null" >
created,
</if>
<if test="updated != null" >
updated,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides="," >
<if test="id != null" >
#{id,jdbcType=BIGINT},
</if>
<if test="title != null" >
#{title,jdbcType=VARCHAR},
</if>
<if test="sellPoint != null" >
#{sellPoint,jdbcType=VARCHAR},
</if>
<if test="price != null" >
#{price,jdbcType=BIGINT},
</if>
<if test="num != null" >
#{num,jdbcType=INTEGER},
</if>
<if test="barcode != null" >
#{barcode,jdbcType=VARCHAR},
</if>
<if test="image != null" >
#{image,jdbcType=VARCHAR},
</if>
<if test="cid != null" >
#{cid,jdbcType=BIGINT},
</if>
<if test="status != null" >
#{status,jdbcType=TINYINT},
</if>
<if test="created != null" >
#{created,jdbcType=TIMESTAMP},
</if>
<if test="updated != null" >
#{updated,jdbcType=TIMESTAMP},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="com.newstyles.pojo.TbItemExample" resultType="java.lang.Integer" >
select count(*) from tb_item
<if test="_parameter != null" >
<include refid="Example_Where_Clause" />
</if>
</select>
<update id="updateByExampleSelective" parameterType="map" >
update tb_item
<set >
<if test="record.id != null" >
id = #{record.id,jdbcType=BIGINT},
</if>
<if test="record.title != null" >
title = #{record.title,jdbcType=VARCHAR},
</if>
<if test="record.sellPoint != null" >
sell_point = #{record.sellPoint,jdbcType=VARCHAR},
</if>
<if test="record.price != null" >
price = #{record.price,jdbcType=BIGINT},
</if>
<if test="record.num != null" >
num = #{record.num,jdbcType=INTEGER},
</if>
<if test="record.barcode != null" >
barcode = #{record.barcode,jdbcType=VARCHAR},
</if>
<if test="record.image != null" >
image = #{record.image,jdbcType=VARCHAR},
</if>
<if test="record.cid != null" >
cid = #{record.cid,jdbcType=BIGINT},
</if>
<if test="record.status != null" >
status = #{record.status,jdbcType=TINYINT},
</if>
<if test="record.created != null" >
created = #{record.created,jdbcType=TIMESTAMP},
</if>
<if test="record.updated != null" >
updated = #{record.updated,jdbcType=TIMESTAMP},
</if>
</set>
<if test="_parameter != null" >
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByExample" parameterType="map" >
update tb_item
set id = #{record.id,jdbcType=BIGINT},
title = #{record.title,jdbcType=VARCHAR},
sell_point = #{record.sellPoint,jdbcType=VARCHAR},
price = #{record.price,jdbcType=BIGINT},
num = #{record.num,jdbcType=INTEGER},
barcode = #{record.barcode,jdbcType=VARCHAR},
image = #{record.image,jdbcType=VARCHAR},
cid = #{record.cid,jdbcType=BIGINT},
status = #{record.status,jdbcType=TINYINT},
created = #{record.created,jdbcType=TIMESTAMP},
updated = #{record.updated,jdbcType=TIMESTAMP}
<if test="_parameter != null" >
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByPrimaryKeySelective" parameterType="com.newstyles.pojo.TbItem" >
update tb_item
<set >
<if test="title != null" >
title = #{title,jdbcType=VARCHAR},
</if>
<if test="sellPoint != null" >
sell_point = #{sellPoint,jdbcType=VARCHAR},
</if>
<if test="price != null" >
price = #{price,jdbcType=BIGINT},
</if>
<if test="num != null" >
num = #{num,jdbcType=INTEGER},
</if>
<if test="barcode != null" >
barcode = #{barcode,jdbcType=VARCHAR},
</if>
<if test="image != null" >
image = #{image,jdbcType=VARCHAR},
</if>
<if test="cid != null" >
cid = #{cid,jdbcType=BIGINT},
</if>
<if test="status != null" >
status = #{status,jdbcType=TINYINT},
</if>
<if test="created != null" >
created = #{created,jdbcType=TIMESTAMP},
</if>
<if test="updated != null" >
updated = #{updated,jdbcType=TIMESTAMP},
</if>
</set>
where id = #{id,jdbcType=BIGINT}
</update>
<update id="updateByPrimaryKey" parameterType="com.newstyles.pojo.TbItem" >
update tb_item
set title = #{title,jdbcType=VARCHAR},
sell_point = #{sellPoint,jdbcType=VARCHAR},
price = #{price,jdbcType=BIGINT},
num = #{num,jdbcType=INTEGER},
barcode = #{barcode,jdbcType=VARCHAR},
image = #{image,jdbcType=VARCHAR},
cid = #{cid,jdbcType=BIGINT},
status = #{status,jdbcType=TINYINT},
created = #{created,jdbcType=TIMESTAMP},
updated = #{updated,jdbcType=TIMESTAMP}
where id = #{id,jdbcType=BIGINT}
</update>
</mapper>
最后,生成的代码拷贝到建立的工程的对应位置进行测试。关于自己测试的内容可以参考下面的地址: 实例应用, 相关参考
对应的mybatis逆向工程的源码请参考github分享内容generatorSqlmapCustom