在上一篇博客中说到,Mybatis是灵活的SQL语句应用,不想Hibernate一样有其封装好的方法,那么,当我们用Mybatis的时候(Hibernate),我们都需要编写其实体类,和配置文件。本篇博客,就介绍一下Mybatis的逆向生成工具。
一、思路
回想一下,在最早运用EF的时候,我们首先通过可视化界面,连接数据库,然后选择要使用的表单,然后,我们就可以自动生成实体类。在运用Hibernate的时候,我们可以先编写Hibernate的配置文件,连接数据库,然后编写实体类文件,然后通过读取HIbernate的配置文件,正向生成数据库表单。然后我们也可以运用工具,从数据库表,生成HIbernate的实体。那么,到了Mybatis这儿,可以怎么做呢?思路如下:
1,连接数据库,指定表单生成
2,指定代码生成后的存放路径,以及要生成哪些代码
2,读取配置文件,生成代码
二、实现
首先是建立了一个Java project,然后引入了5个jar包,分别是:
log4j-1.2.16.jar;Mybatis-3.2.3.jar;Mybatis-generator-core-1.3.2.jar;mysal-connector-java-5.1.28-bin.jar;ojdbc14.jar
版本可以自行确定!
然后,编写mybatis.xml配置文件,代码内容如下:
<span style="font-family:KaiTi_GB2312;font-size:18px;"><?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> <context id="testTables" targetRuntime="MyBatis3"> <commentGenerator> <!-- 是否去除自动生成的注释 true:是 : false:否 --> <property name="suppressAllComments" value="true" /> </commentGenerator> <!--数据库连接的信息:驱动类、连接地址、用户名、密码 --> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/Test" userId="root" password="Angel0626"> </jdbcConnection> <!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和 NUMERIC 类型解析为java.math.BigDecimal --> <javaTypeResolver> <property name="forceBigDecimals" value="false" /> </javaTypeResolver> <!-- targetProject:生成PO类的位置 --> <javaModelGenerator targetPackage="pojo" targetProject=".src"> <!-- enableSubPackages:是否让schema作为包的后缀 --> <property name="enableSubPackages" value="false" /> <!-- 从数据库返回的值被清理前后的空格 --> <property name="trimStrings" value="true" /> </javaModelGenerator> <!-- targetProject:mapper映射文件生成的位置 --> <sqlMapGenerator targetPackage="mapper" targetProject=".src"> <!-- enableSubPackages:是否让schema作为包的后缀 --> <property name="enableSubPackages" value="false" /> </sqlMapGenerator> <!-- targetPackage:mapper接口生成的位置 --> <javaClientGenerator type="XMLMAPPER" targetPackage="mapper" targetProject=".src"> <!-- enableSubPackages:是否让schema作为包的后缀 --> <property name="enableSubPackages" value="false" /> </javaClientGenerator> <!-- 指定数据库表 --> <table schema="" tableName="tb_content"></table> <table schema="" tableName="tb_content_category"></table> <table schema="" tableName="tb_item"></table> <table schema="" tableName="tb_item_cat"></table> <table schema="" tableName="tb_item_desc"></table> <table schema="" tableName="tb_item_param"></table> <table schema="" tableName="tb_item_param_item"></table> <table schema="" tableName="tb_order"></table> <table schema="" tableName="tb_order_item"></table> <table schema="" tableName="tb_order_shipping"></table> <table schema="" tableName="tb_user"></table> </context> </generatorConfiguration> </span>
其次,编写实现方法,代码如下:
<span style="font-family:KaiTi_GB2312;font-size:18px;">package test; import java.io.File; import java.util.ArrayList; import java.util.List; import org.mybatis.generator.api.MyBatisGenerator; import org.mybatis.generator.config.Configuration; import org.mybatis.generator.config.xml.ConfigurationParser; import org.mybatis.generator.internal.DefaultShellCallback; public class GeneratorSqlmap { public void generator() throws Exception{ List<String> warnings=new ArrayList<String>(); boolean overwrite=true; File configFile=new File("mybatis.xml"); ConfigurationParser cp=new ConfigurationParser(warnings); Configuration config=cp.parseConfiguration(configFile); DefaultShellCallback callback=new DefaultShellCallback(overwrite); MyBatisGenerator myBatisGenerator=new MyBatisGenerator(config,callback,warnings); myBatisGenerator.generate(null); } public static void main(String[] args) throws Exception{ try{ GeneratorSqlmap generatorSqlmap=new GeneratorSqlmap(); generatorSqlmap.generator(); }catch(Exception e){ e.printStackTrace(); } } } </span>
运行其main方法,即可生成相应代码。
代码示例:以TbUser表为例:
实体类:
<span style="font-family:KaiTi_GB2312;font-size:18px;">public class TbUser { private Long id; private String username; private String password; private String phone; private String email; private Date created; private Date updated; public Long getId() { return id; } public void setId(Long id) { this.id = id; }</span>
mapper接口:
<span style="font-family:KaiTi_GB2312;font-size:18px;">package mapper; import java.util.List; import org.apache.ibatis.annotations.Param; import pojo.TbUser; import pojo.TbUserExample; public interface TbUserMapper { int countByExample(TbUserExample example); int deleteByExample(TbUserExample example); int deleteByPrimaryKey(Long id); int insert(TbUser record); int insertSelective(TbUser record); List<TbUser> selectByExample(TbUserExample example); TbUser selectByPrimaryKey(Long id); int updateByExampleSelective(@Param("record") TbUser record, @Param("example") TbUserExample example); int updateByExample(@Param("record") TbUser record, @Param("example") TbUserExample example); int updateByPrimaryKeySelective(TbUser record); int updateByPrimaryKey(TbUser record); }</span>
mapper.xml实现:
<span style="font-family:KaiTi_GB2312;font-size:18px;"><?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="mapper.TbUserMapper" > <resultMap id="BaseResultMap" type="pojo.TbUser" > <id column="id" property="id" jdbcType="BIGINT" /> <result column="username" property="username" jdbcType="VARCHAR" /> <result column="password" property="password" jdbcType="VARCHAR" /> <result column="phone" property="phone" jdbcType="VARCHAR" /> <result column="email" property="email" jdbcType="VARCHAR" /> <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, username, password, phone, email, created, updated </sql> <select id="selectByExample" resultMap="BaseResultMap" parameterType="pojo.TbUserExample" > select <if test="distinct" > distinct </if> <include refid="Base_Column_List" /> from tb_user <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_user where id = #{id,jdbcType=BIGINT} </select> <delete id="deleteByPrimaryKey" parameterType="java.lang.Long" > delete from tb_user where id = #{id,jdbcType=BIGINT} </delete> <delete id="deleteByExample" parameterType="pojo.TbUserExample" > delete from tb_user <if test="_parameter != null" > <include refid="Example_Where_Clause" /> </if> </delete> <insert id="insert" parameterType="pojo.TbUser" > insert into tb_user (id, username, password, phone, email, created, updated) values (#{id,jdbcType=BIGINT}, #{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, #{phone,jdbcType=VARCHAR}, #{email,jdbcType=VARCHAR}, #{created,jdbcType=TIMESTAMP}, #{updated,jdbcType=TIMESTAMP}) </insert> <insert id="insertSelective" parameterType="pojo.TbUser" > insert into tb_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="phone != null" > phone, </if> <if test="email != null" > email, </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="username != null" > #{username,jdbcType=VARCHAR}, </if> <if test="password != null" > #{password,jdbcType=VARCHAR}, </if> <if test="phone != null" > #{phone,jdbcType=VARCHAR}, </if> <if test="email != null" > #{email,jdbcType=VARCHAR}, </if> <if test="created != null" > #{created,jdbcType=TIMESTAMP}, </if> <if test="updated != null" > #{updated,jdbcType=TIMESTAMP}, </if> </trim> </insert> <select id="countByExample" parameterType="pojo.TbUserExample" resultType="java.lang.Integer" > select count(*) from tb_user <if test="_parameter != null" > <include refid="Example_Where_Clause" /> </if> </select> <update id="updateByExampleSelective" parameterType="map" > update tb_user <set > <if test="record.id != null" > id = #{record.id,jdbcType=BIGINT}, </if> <if test="record.username != null" > username = #{record.username,jdbcType=VARCHAR}, </if> <if test="record.password != null" > password = #{record.password,jdbcType=VARCHAR}, </if> <if test="record.phone != null" > phone = #{record.phone,jdbcType=VARCHAR}, </if> <if test="record.email != null" > email = #{record.email,jdbcType=VARCHAR}, </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_user set id = #{record.id,jdbcType=BIGINT}, username = #{record.username,jdbcType=VARCHAR}, password = #{record.password,jdbcType=VARCHAR}, phone = #{record.phone,jdbcType=VARCHAR}, email = #{record.email,jdbcType=VARCHAR}, 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="pojo.TbUser" > update tb_user <set > <if test="username != null" > username = #{username,jdbcType=VARCHAR}, </if> <if test="password != null" > password = #{password,jdbcType=VARCHAR}, </if> <if test="phone != null" > phone = #{phone,jdbcType=VARCHAR}, </if> <if test="email != null" > email = #{email,jdbcType=VARCHAR}, </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="pojo.TbUser" > update tb_user set username = #{username,jdbcType=VARCHAR}, password = #{password,jdbcType=VARCHAR}, phone = #{phone,jdbcType=VARCHAR}, email = #{email,jdbcType=VARCHAR}, created = #{created,jdbcType=TIMESTAMP}, updated = #{updated,jdbcType=TIMESTAMP} where id = #{id,jdbcType=BIGINT} </update> </mapper></span>
三、总结
从生成的代码可以看出,生成的代码,基本上解决了对于一个实体操作的增删改查,但是,每个实体的代码都是这样的丰富,还能不能继续往上抽象一层呢?下一篇博客介绍Mybatis的底层封装思路!