MyBatis Generator 插件的拓展插件包

2019-09-08 09:05:54

应该说使用Mybatis就一定离不开MyBatis Generator这款代码生成插件,而这款插件自身还提供了插件拓展功能用于强化插件本身,官方已经提供了一些拓展插件,本项目的目的也是通过该插件机制来强化Mybatis Generator本身,方便和减少我们平时的代码开发量。

因为插件是本人兴之所至所临时发布的项目(本人已近三年未做JAVA开发,代码水平请大家见谅),但基本插件都是在实际项目中经过检验的请大家放心使用,但因为项目目前主要数据库为MySQL,Mybatis实现使用Mapper.xml方式,所以代码生成时对于其他数据库和注解方式的支持未予考虑,请大家见谅。


插件列表:

  • 查询单条数据插件(SelectOneByExamplePlugin)

  • MySQL分页插件(LimitPlugin)

  • 数据Model链式构建插件(ModelBuilderPlugin)

  • Example Criteria 增强插件(ExampleEnhancedPlugin(CriteriaBuilderPlugin这个是老版本叫法,已经弃用))

  • Example 目标包修改插件(ExampleTargetPlugin)

  • 批量插入插件(BatchInsertPlugin)

  • 逻辑删除插件(LogicalDeletePlugin)

  • 数据Model属性对应Column获取插件(ModelColumnPlugin)

  • 存在即更新插件(UpsertPlugin)


Maven引用:

<dependency>  <groupId>com.itfsw</groupId>  <artifactId>mybatis-generator-plugin</artifactId>  <version>1.0.6</version></dependency>

1. 查询单条数据插件

对应表Mapper接口增加了方法
插件:

<!-- 查询单条数据插件 --><plugin type="com.itfsw.mybatis.generator.plugins.SelectOneByExamplePlugin"/>

使用:

public interface TbMapper {        /**     * 这是Mybatis Generator拓展插件生成的方法(请勿删除).     * This method corresponds to the database table tb     *     * @mbg.generated     * @author hewei     */    Tb selectOneByExample(TbExample example);}

2. MySQL分页插件

对应表Example类增加了Mysql分页方法,limit(Integer rows)、limit(Integer offset, Integer rows)和page(Integer page, Integer pageSize)
插件:

<!-- MySQL分页插件 --><plugin type="com.itfsw.mybatis.generator.plugins.LimitPlugin"/>

使用:

public class TbExample {    /**     * 这是Mybatis Generator拓展插件生成的属性(请勿删除).     * This field corresponds to the database table tb     *     * @mbg.generated     * @author hewei     */    protected Integer offset;    /**     * 这是Mybatis Generator拓展插件生成的属性(请勿删除).     * This field corresponds to the database table tb     *     * @mbg.generated     * @author hewei     */    protected Integer rows;    /**     * 这是Mybatis Generator拓展插件生成的方法(请勿删除).     * This method corresponds to the database table rc_user_token     *     * @mbg.generated     * @author hewei     */    public TbExample limit(Integer rows) {        this.rows = rows;        return this;    }    /**     * 这是Mybatis Generator拓展插件生成的方法(请勿删除).     * This method corresponds to the database table rc_user_token     *     * @mbg.generated     * @author hewei     */    public TbExample limit(Integer offset, Integer rows) {        this.offset = offset;        this.rows = rows;        return this;    }    /**     * 这是Mybatis Generator拓展插件生成的方法(请勿删除).     * This method corresponds to the database table tb     *     * @mbg.generated     * @author hewei     */    public TbExample page(Integer page, Integer pageSize) {        this.offset = page * pageSize;        this.rows = pageSize;        return this;    }        // offset 和 rows 的getter&setter        // 修正了clear方法    /**     * This method was generated by MyBatis Generator.     * This method corresponds to the database table tb     *     * @mbg.generated     */    public void clear() {        oredCriteria.clear();        orderByClause = null;        distinct = false;        rows = null;        offset = null;    }}public class Test {    public static void main(String[] args) {        this.tbMapper.selectByExample(                new TbExample()                .createCriteria()                .andField1GreaterThan(1)                .example()                .limit(10)  // 查询前10条                .limit(10, 10)  // 查询10~20条                .page(1, 10)    // 查询第2页数据(每页10条)        );    }}

3. 数据Model链式构建插件

这个是仿jquery的链式调用强化了表的Model的赋值操作
插件:

<!-- 数据Model链式构建插件 --><plugin type="com.itfsw.mybatis.generator.plugins.ModelBuilderPlugin"/>

使用:

public class Test {    public static void main(String[] args) {        // 直接new表Model的内部Builder类,赋值后调用build()方法返回对象        Tb table = new Tb.Builder()               .field1("xx")               .field2("xx")               .field3("xx")               .field4("xx")               .build();    }}

4. Example 增强插件(example,andIf,orderBy)

  • Criteria的快速返回example()方法。

  • Criteria链式调用增强,以前如果有按条件增加的查询语句会打乱链式查询构建,现在有了andIf(boolean ifAdd, CriteriaAdd add)方法可一直使用链式调用下去。

  • Example增强了setOrderByClause方法,新增orderBy(String orderByClause)方法直接返回example,增强链式调用,可以一路.下去了。

  • 继续增强orderBy(String orderByClause)方法,增加orderBy(String ... orderByClauses)方法,配合数据Model属性对应Column获取插件(ModelColumnPlugin)使用效果更佳。
    插件:

<!-- Example Criteria 增强插件 --><plugin type="com.itfsw.mybatis.generator.plugins.ExampleEnhancedPlugin"/>

使用:

public class Test {    public static void main(String[] args) {        // -----------------------------------example-----------------------------------        // 表Example.Criteria增加了工厂方法example()支持,使用后可链式构建查询条件使用example()返回Example对象        this.tbMapper.selectByExample(                new TbExample()                .createCriteria()                .andField1EqualTo(1)                .andField2EqualTo("xxx")                .example()        );                // -----------------------------------andIf-----------------------------------        // Criteria增强了链式调用,现在一些按条件增加的查询条件不会打乱链式调用了        // old        TbExample oldEx = new TbExample();        TbExample.Criteria criteria = oldEx                .createCriteria()                .andField1EqualTo(1)                .andField2EqualTo("xxx");        // 如果随机数大于0.5,附加Field3查询条件        if (Math.random() > 0.5){            criteria.andField3EqualTo(2)                    .andField4EqualTo(new Date());        }        this.tbMapper.selectByExample(oldEx);        // new        this.tbMapper.selectByExample(                new TbExample()                .createCriteria()                .andField1EqualTo(1)                .andField2EqualTo("xxx")                // 如果随机数大于0.5,附加Field3查询条件                .andIf(Math.random() > 0.5, new TbExample.Criteria.ICriteriaAdd() {                    @Override                    public TbExample.Criteria add(TbExample.Criteria add) {                        return add.andField3EqualTo(2)                                .andField4EqualTo(new Date());                    }                })                // 当然最简洁的写法是采用java8的Lambda表达式,当然你的项目是Java8+                .andIf(Math.random() > 0.5, add -> add                        .andField3EqualTo(2)                        .andField4EqualTo(new Date())                )                .example()        );                // -----------------------------------orderBy-----------------------------------        // old        TbExample ex = new TbExample();        ex.createCriteria().andField1GreaterThan(1);        ex.setOrderByClause("field1 DESC");        this.tbMapper.selectByExample(ex);        // new        this.tbMapper.selectByExample(                new TbExample()                .createCriteria()                .andField1GreaterThan(1)                .example()                .orderBy("field1 DESC")                // 这个配合数据Model属性对应Column获取插件(ModelColumnPlugin)使用                .orderBy(Tb.Column.field1.asc(), Tb.Column.field3.desc())        );    }}

5. Example 目标包修改插件

Mybatis Generator 插件默认把Model类和Example类都生成到一个包下,这样该包下类就会很多不方便区分,该插件目的就是把Example类独立到一个新包下,方便查看。
插件:

<!-- Example 目标包修改插件 --><plugin type="com.itfsw.mybatis.generator.plugins.ExampleTargetPlugin">    <!-- 修改Example类生成到目标包下 -->    <property name="targetPackage" value="com.itfsw.mybatis.generator.dao.example"/></plugin>

6. 批量插入插件

提供了批量插入batchInsert和batchInsertSelective方法,因为方法使用了使用了JDBC的getGenereatedKeys方法返回插入主键,所以只能在MYSQL和SQLServer下使用。 需配合数据Model属性对应Column获取插件(ModelColumnPlugin)插件使用,实现类似于insertSelective插入列!
PS:为了和Mybatis官方代码风格保持一致,1.0.5+版本把批量插入方法分开了,基于老版本1.0.5-版本生成的代码请继续使用“com.itfsw.mybatis.generator.plugins.BatchInsertOldPlugin”不影响使用
PS:继续PS,本来想继续保留老版本代码,不影响老版本已经生成代码使用的,但是始终没有绕过BindingException,只能把代码移入BatchInsertOldPlugin类~~~~~
插件:

<!-- 批量插入插件 --><plugin type="com.itfsw.mybatis.generator.plugins.BatchInsertPlugin"/>

使用:

public class Test {    public static void main(String[] args) {        // 构建插入数据        List<Tb> list = new ArrayList<>();        list.add(                new Tb.Builder()                .field1(0)                .field2("xx0")                .field3(0)                .createTime(new Date())                .build()        );        list.add(                new Tb.Builder()                .field1(1)                .field2("xx1")                .field3(1)                .createTime(new Date())                .build()        );        // 普通插入,插入所有列        this.tbMapper.batchInsert(list);        // !!!下面按需插入指定列(类似于insertSelective),需要数据Model属性对应Column获取插件(ModelColumnPlugin)插件        this.tbMapper.batchInsertSelective(list, Tb.Column.field1, Tb.Column.field2, Tb.Column.field3, Tb.Column.createTime);    }}

7. 逻辑删除插件

因为很多实际项目数据都不允许物理删除,多采用逻辑删除,所以单独为逻辑删除做了一个插件,方便使用。
插件:

<xml>    <!-- 逻辑删除插件 -->    <plugin type="com.itfsw.mybatis.generator.plugins.LogicalDeletePlugin">        <!-- 这里配置的是全局逻辑删除列和逻辑删除值,当然在table中配置的值会覆盖该全局配置 -->        <!-- 逻辑删除列类型只能为数字、字符串或者布尔类型 -->        <property name="logicalDeleteColumn" value="del_flag"/>        <!-- 未设置该属性或者该属性的值为null或者NULL,逻辑删除时会把该字段置为NULL。 -->        <property name="logicalDeleteValue" value="9"/>    </plugin>        <table tableName="tb">        <!-- 这里可以单独表配置逻辑删除列和删除值,覆盖全局配置 -->        <property name="logicalDeleteColumn" value="del_flag"/>        <property name="logicalDeleteValue" value="1"/>    </table></xml>

使用:

public class Test {    public static void main(String[] args) {        // 1. 逻辑删除ByExample        this.tbMapper.logicalDeleteByExample(                new TbExample()                .createCriteria()                .andField1EqualTo(1)                .example()        );        // 2. 逻辑删除ByPrimaryKey        this.tbMapper.logicalDeleteByPrimaryKey(1L);        // 3. 同时Example中提供了一个快捷方法来过滤逻辑删除数据        this.tbMapper.selectByExample(                new TbExample()                .createCriteria()                .andField1EqualTo(1)                // 新增了一个andDeleted方法过滤逻辑删除数据                .andDeleted(true)                // 当然也可直接使用逻辑删除列的查询方法,我们数据Model中定义了一个逻辑删除常量DEL_FLAG                .andDelFlagEqualTo(Tb.DEL_FLAG)                .example()        );    }}

8. 数据Model属性对应Column获取插件

项目中我们有时需要获取数据Model对应数据库字段的名称,一般直接根据数据Model的属性就可以猜出数据库对应column的名字,可是有的时候当column使用了columnOverride或者columnRenamingRule时就需要去看数据库设计了,所以提供了这个插件获取model对应的数据库Column。

  • 配合Example Criteria 增强插件(ExampleEnhancedPlugin)使用,这个插件还提供了asc()和desc()方法配合Example的orderBy方法效果更佳。

  • 配合批量插入插件(BatchInsertPlugin)使用,batchInsertSelective(@Param("list") List list, @Param("selective") XXX.Column ... insertColumns)。

插件:

<!-- 数据Model属性对应Column获取插件 --><plugin type="com.itfsw.mybatis.generator.plugins.ModelColumnPlugin"/>

使用:

public class Test {    public static void main(String[] args) {        // 1. 获取Model对应column        String column = Tb.Column.createTime.value();        // 2. 配合Example Criteria 增强插件(ExampleEnhancedPlugin)使用orderBy方法        // old        this.tbMapper.selectByExample(                new TbExample()                .createCriteria()                .andField1GreaterThan(1)                .example()                .orderBy("field1 DESC, field3 ASC")        );        // better        this.tbMapper.selectByExample(                new TbExample()                .createCriteria()                .andField1GreaterThan(1)                .example()                .orderBy(Tb.Column.field1.desc(), Tb.Column.field3.asc())        );                // 3. 配合批量插入插件(BatchInsertPlugin)使用实现按需插入指定列        List<Tb> list = new ArrayList<>();        list.add(                new Tb.Builder()                .field1(0)                .field2("xx0")                .field3(0)                .field4(new Date())                .build()        );        list.add(                new Tb.Builder()                .field1(1)                .field2("xx1")                .field3(1)                .field4(new Date())                .build()        );        // 这个会插入表所有列        this.tbMapper.batchInsert(list);        // 下面按需插入指定列(类似于insertSelective)        this.tbMapper.batchInsertSelective(list, Tb.Column.field1, Tb.Column.field2, Tb.Column.field3, Tb.Column.createTime);    }}

9. 存在即更新插件

使用MySQL的“insert ... on duplicate key update”实现存在即更新操作,简化数据入库操作([issues#2])。

插件:

<!-- 存在即更新插件 --><plugin type="com.itfsw.mybatis.generator.plugins.UpsertPlugin"/>

使用:

public class Test {    public static void main(String[] args) {        // 1. 未入库数据入库,执行insert        Tb tb = new Tb.Builder()                .field1(1)                .field2("xx0")                .delFlag((short)0)                .build();        int k0 = this.tbMapper.upsert(tb);        // 2. 已入库数据再次入库,执行update(!!需要注意如触发update其返回的受影响行数为2)        tb.setField2("xx1");        int k1 = this.tbMapper.upsert(tb);        // 3. 类似insertSelective实现选择入库        Tb tb1 = new Tb.Builder()                .field1(1)                .field2("xx0")                .build();        int k2 = this.tbMapper.upsertSelective(tb1);        tb1.setField2("xx1");        int k3 = this.tbMapper.upsertSelective(tb1);    }}


  • 2019-12-06 10:47:29

    date-fns日期工具的使用方法详解

    isToday() 判断传入日期是否为今天 isYesterday() 判断传入日期是否为昨天 isTomorrow() 判断传入日期是否为 format() 日期格式化 addDays() 获得当前日期之后的日期 addHours() 获得当前时间n小时之后的时间点 addMinutes() 获得当前时间n分钟之后的时间 addMonths() 获得当前月之后n个月的月份 subDays() 获得当前时间之前n天的时间 subHours() 获得当前时间之前n小时的时间 subMinutes() 获得当前时间之前n分钟的时间 subMonths() 获得当前时间之前n个月的时间 differenceInYears() 获得两个时间相差的年份 differenceInWeeks() 获得两个时间相差的周数 differenceInDays() 获得两个时间相差的天数 differenceInHours() 获得两个时间相差的小时数 differenceInMinutes() 获得两个时间相差的分钟数

  • 2019-12-06 10:49:39

    npm 查看源 换源

    npm,cnpm,查看源,切换源,npm config set registry https://registry.npmjs.org

  • 2019-12-06 11:01:31

    npm发布包流程详解 有demo

    npm发布包步骤,以及踩过的坑(见红颜色标准): 1.注册npm账号,并完成Email认证(否则最后一步提交会报Email错误) 2.npm添加用户或登陆:npm adduser 或 npm login

  • 2019-12-06 13:16:18

    vue mixins组件复用的几种方式

    最近在做项目的时候,研究了mixins,此功能有妙处。用的时候有这样一个场景,页面的风格不同,但是执行的方法,和需要的数据非常的相似。我们是否要写两种组件呢?还是保留一个并且然后另个一并兼容另一个呢? 不管以上那种方式都不是很合理,因为组件写成2个,不仅麻烦而且维护麻烦;第二种虽然做了兼容但是页面逻辑造成混乱,必然不清晰;有没有好的方法,有那就是用vue的混合插件mixins。混合在Vue是为了提出相似的数据和功能,使代码易懂,简单、清晰。

  • 2019-12-06 13:26:30

    vue的mixins混入合并规则

    混入minxins:分发vue组件中可复用功能的灵活方式。混入对象可以包含任意组件选项。组件使用混入对象时,所有混入对象的选项将混入该组件本身的选项。

  • 2019-12-06 16:50:34

    Intellij idea 如何关闭无用的提示

    Linux:Settings —> Editor —> Inspections —> General —> Duplicated Code Mac:Preferences --> Editor —> Inspections —> General —> Duplicated Code fragment 将对应的勾去掉。

  • 2019-12-09 15:36:56

    神秘的 shadow-dom 浅析,shadow-root

    顾名思义, shadow-dom,直译的话就是 影子dom ?我觉得可以理解为潜藏在黑暗中的 DOM 结构,也就是我们无法直接控制操纵的 DOM 结构。前端同学经常用开发者工具的话,查看 DOM 结构的时候,肯定看到过下面这样的结构:

  • 2019-12-10 11:13:50

    前端实战-基于Nuxt的SVG使用

    虽然我们在日常开发的时候,在使用iview 或者element ui等组件时,通常会包含一些常用icon;但是在面对一些特定的需求时,或者自己想high一下,这些通用的icon并不能很好的满足我们。这个时候我们可能会拿到一些SVG适量图,但是怎么去使用这些矢量图呢。

  • 2019-12-10 11:15:08

    用CSS给SVG 的内容添加样式

    SVG图形的一个最常见用例是图标系统,其中最常用的SVG sprite技术就是使用SVG<use> 元素在文档中任意位置“实例化”图标。 使用<use>元素实例化图标或任何其它的SVG元素或图像,给元素添加样式时经常会碰到一些问题。这篇文章的目的是尽可能给你介绍一些方法来解决:使用<use>引入的内容添加样式受限的问题。 但是在开始之前,我们先快速浏览一下SVG的主要结构和分组元素,然后慢慢进入use的世界中,以及shadow DOM,然后重回CSS的怀抱。我们会逐步讲解为什么给<use>内容添加样式会比较麻烦,以及有什么好的解决方案。