前言
介绍三个好用的Mybatis插件(包),帮助我们快速设计分页,快速生成dao层等
mybatis-generator
配置文件
这个插件可以根据数据库自动生成pojo、dao、对应的xml文件。
pojo中放的是和db字段一一对应的对象(就是model层啦)
dao层是供service调用的接口
xml是dao层接口的实现,即SQL语句全部写在xml中
mybatis-generator插件在maven的pom文件中已经配置了
它自己的配置文件放在src/main/resources下面,这里叫generatorConfig.xml
(还是自己敲进去,不然脑子中没有印象)
generator的配置文件还依赖一些数据库参数,放在另外一个文件datasource.properties中,也放在src/main/resources下面
# 这里mysql驱动jar包位置,让我有些搞不明白,我在本地开发那么应该填本地的位置,到时
# 候上线还需要修改成为线上的位置吧。。感觉不能这么麻烦
db.driverLocation=C:/Users/winxb/.m2/repository/mysql/mysql-connector-java/5.1.6/mysql-connector-java-5.1.6.jar
db.driverClassName=com.mysql.jdbc.Driver
# 这里本地就不搞数据库了,直接使用云服务器上的,不过到时候上线还需要把ip地址修改
# 为127.0.0.1,毕竟服务器上tomcat和mysql在一台机子上,ip填自己的,我就用0代替了
db.url=jdbc:mysql://000.000.000.000:3306/happymall?characterEncoding=utf-8
db.username=happymall
db.password=123456
以下为generatorConfig.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>
<!--导入属性配置,就是把一些配置${}放到这个文件中datasource.properties-->
<properties resource="datasource.properties"/>
<!--指定特定数据库的jdbc驱动jar包的位置-->
<classPathEntry location="${db.driverLocation}"/>
<context id="default" targetRuntime="MyBatis3">
<!--optional,旨在创建class时,对注释进行控制-->
<commentGenerator>
<property name="supressDate" value="true"/>
<property name="supressAllComments" value="true"/>
</commentGenerator>
<!--jdbc的数据库连接-->
<jdbcConnection
driverClass="${db.driverClassName}"
connectionURL="${db.url}"
userId="${db.username}"
password="${db.password}">
</jdbcConnection>
<!--非必须,类型处理器,在数据库类型和java类型之间的转换控制-->
<javaTypeResolver>
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!--Model模型生成器,用来生成含有主键key的类,记录类以及查询Example类
targetPackage 指定生成的model生成所在的包名
targetProject 指定在该项目下所在的路径
-->
<javaModelGenerator targetPackage="top.winxblast.happymall.pojo"
targetProject="./src/main/java">
<!--是否允许子包,即targetPackage.schemaName.tableName-->
<property name="enableSubPackages" value="false"/>
<!--是否对model添加构造函数-->
<property name="constructorBased" value="true"/>
<!--是否对类CHAR类型的列的数据进行trim操作-->
<property name="trimString" value="true"/>
<!--建立的Model对象是否不可改变,true即生成的
Model对象不会有setter方法,只有构造方法-->
<property name="immutable" value="false"/>
</javaModelGenerator>
<!--mapper映射文件生成所在的目录
为每一个数据库的表生成对应的SqlMap文件-->
<!--生成目标xml文件,即接口实现文件-->
<sqlMapGenerator targetPackage="mappers"
targetProject="./src/main/resources">
<property name="enableSubPackages" value="false"/>
</sqlMapGenerator>
<!--客户端代码,生成易于使用的针对Model对象和xml配置文件的代码
type="ANNOTATEDMAPPER",生成Java Model
和基于注解的Mapper对象
type="MIXEDMAPPER",生成基于注解的Java Model
和相应的Mapper对象
type="XMLMAPPER",生成SQLMap XML文件和独立的Mapper接口
-->
<!--targetPackage: mapper接口dao生成的位置-->
<javaClientGenerator type="XMLMAPPER"
targetPackage="top.winxblast.happymall.dao"
targetProject="./src/main/java">
<!--enableSubPackages:是否让schema作为包的后缀-->
<property name="enableSubPackages" value="false"/>
</javaClientGenerator>
<!-- tableName和数据库中表的名字保持一致,domainObjectName表示
生成Java类的类名;enableCountByExample表示是否可以通过这个对象查它
的数量;enableUpdateByExample表示是否可以通过这个对象update;
这里这些都采用默认-->
<table tableName="happymall_shipping" domainObjectName="Shipping"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false"/>
<table tableName="happymall_cart" domainObjectName="Cart"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false"/>
<!--这个表比较奇怪,之前没有在数据库中添加,后来靠插件也没有生成,可能老师有什么遗漏-->
<table tableName="happymall_cart_item" domainObjectName="CartItem"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false"/>
<table tableName="happymall_category" domainObjectName="Category"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false"/>
<table tableName="happymall_order" domainObjectName="Order"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false"/>
<table tableName="happymall_order_item" domainObjectName="OrderItem"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false"/>
<table tableName="happymall_pay_info" domainObjectName="PayInfo"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false"/>
<table tableName="happymall_product" domainObjectName="Product"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
<!--这两个字段在数据库中都是用text的,mybatis不同版本生成的会不一样
所以就都转化成VARCHAR-->
<columnOverride column="detail" jdbcType="VARCHAR"/>
<columnOverride column="sub_images" jdbcType="VARCHAR"/>
</table>
<table tableName="happymall_user" domainObjectName="User"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false"/>
</context>
</generatorConfiguration>
生成数据对象
如图一次点击,然后双击③,最后看到build success就成功了,且说明前面没有配置错误
这时候可以在三个包(文件夹)下面看到生成的内容,可以对照自己学mybatis时的手写程序看看(其实感觉要技能进阶,就要有熟练手撸这些代码的能力,虽然说自动工具太爽了)
dao层的接口供service层调用,实际的SQL语句放在xml文件中了。
时间戳优化
我们每个表里面都有create_time
和update_time
两个字段,这两个字段对于业务来说还是很重要的,不过这里将这两个代码交给数据库的内置函数now()
来更新,而不通过我们的代码来实现。
将insert语句中的两个时间都改成now(),将update语句中的update_time
字段的值改成now()
这里举一个xml文件为例,其他所有表都一样改
第一个insert,注意最后两个now
<insert id="insert" parameterType="top.winxblast.happymall.pojo.Cart" >
insert into happymall_cart (id, user_id, product_id,
quantity, checked, create_time,
update_time)
values (#{id,jdbcType=INTEGER}, #{userId,jdbcType=INTEGER}, #{productId,jdbcType=INTEGER},
#{quantity,jdbcType=INTEGER}, #{checked,jdbcType=INTEGER}, now(),
now())
</insert>
第二个insert,不过这里既然是selective,那么我还有点疑问就是,两个时间要是没初始化还是null,那不就插入其他值时不会建立这两个时间了么?不过可能这就是自动化生成的问题,可能这个问题不会出现,因为Cart这个类构造方法就是全部值要传进去的,也没有单独的setter方法,所以这个选择插入的语句以后要用可能还有会有一些改造。
<insert id="insertSelective" parameterType="top.winxblast.happymall.pojo.Cart" >
insert into happymall_cart
<trim prefix="(" suffix=")" suffixOverrides="," >
<if test="id != null" >
id,
</if>
<if test="userId != null" >
user_id,
</if>
<if test="productId != null" >
product_id,
</if>
<if test="quantity != null" >
quantity,
</if>
<if test="checked != null" >
checked,
</if>
<if test="createTime != null" >
create_time,
</if>
<if test="updateTime != null" >
update_time,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides="," >
<if test="id != null" >
#{id,jdbcType=INTEGER},
</if>
<if test="userId != null" >
#{userId,jdbcType=INTEGER},
</if>
<if test="productId != null" >
#{productId,jdbcType=INTEGER},
</if>
<if test="quantity != null" >
#{quantity,jdbcType=INTEGER},
</if>
<if test="checked != null" >
#{checked,jdbcType=INTEGER},
</if>
<if test="createTime != null" >
now(),
</if>
<if test="updateTime != null" >
now(),
</if>
</trim>
</insert>
两个update,注意找里面的now
<update id="updateByPrimaryKeySelective" parameterType="top.winxblast.happymall.pojo.Cart" >
update happymall_cart
<set >
<if test="userId != null" >
user_id = #{userId,jdbcType=INTEGER},
</if>
<if test="productId != null" >
product_id = #{productId,jdbcType=INTEGER},
</if>
<if test="quantity != null" >
quantity = #{quantity,jdbcType=INTEGER},
</if>
<if test="checked != null" >
checked = #{checked,jdbcType=INTEGER},
</if>
<if test="createTime != null" >
create_time = #{createTime,jdbcType=TIMESTAMP},
</if>
<if test="updateTime != null" >
now(),
</if>
</set>
where id = #{id,jdbcType=INTEGER}
</update>
<update id="updateByPrimaryKey" parameterType="top.winxblast.happymall.pojo.Cart" >
<!--
WARNING - @mbggenerated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Sun Oct 08 14:03:47 CST 2017.
-->
update happymall_cart
set user_id = #{userId,jdbcType=INTEGER},
product_id = #{productId,jdbcType=INTEGER},
quantity = #{quantity,jdbcType=INTEGER},
checked = #{checked,jdbcType=INTEGER},
create_time = #{createTime,jdbcType=TIMESTAMP},
update_time = now()
where id = #{id,jdbcType=INTEGER}
</update>