Mybatis之逆向工程

Mybatis现在已经是非常受企业以及程序员喜爱的持久层框架之一了,同时Mybatis为了迎合java编程的趋势(面向接口编程),有了Mapper接口文件,更加方便了我们日常的开发,但与此同时,又出现了新的问题,跟随着互联网时代的热浪,大部分企业都开始追随着互联网公司做分布式架构,朝着高并发走,同时也需要优化自己的数据库,分表分库,尽量让自己的查询少关联,而针对这样的情况,我们程序员也不得不每个表都写一个实体类,写个mapper接口,再写个xml文件,实施上Mybatis已经帮我们想好了解决方法,可以自动生成单表的实体类,接口文件,xml映射文件,并且为了能够按条件进行单表查询还有另外两个类,Example和Criteria(“妈妈”再也不用为了100张单表查询看着我们写实体类了),单表查询再也不用写sql了。


今天的任务就是实现逆向工程,首先我们可以通过mybatis的官方网站或者CSDN上下载逆向工程的包,这步我就直接省略了,现在网上资源太多,后面我会撸代码,你们一看包名就知道怎么找了。
其实逆向工程正如其名,这是一个工程,而这个工程的作用就是生成上文中提到的4个类,他的main方法所在的类大家可以不用理会,我们主要用的是他的配置文件。
这里写图片描述
这也是我们最关注的部分,要用逆向工程就要会配置他的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>
    <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/simon" 
            userId="root"
            password="lcx66297022">
        </jdbcConnection>
        <!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和 
            NUMERIC 类型解析为java.math.BigDecimal -->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false" />
        </javaTypeResolver>

        <!-- targetProject:生成PO类的位置 -->
        <javaModelGenerator targetPackage="com.simon.entity"
            targetProject=".\src">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false" />
            <!-- 从数据库返回的值被清理前后的空格 -->
            <property name="trimStrings" value="true" />
        </javaModelGenerator>
        <!-- targetProject:mapper映射文件生成的位置 -->
        <sqlMapGenerator targetPackage="com.simon.dao" 
            targetProject=".\src">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false" />
        </sqlMapGenerator>
        <!-- targetPackage:mapper接口生成的位置 -->
        <javaClientGenerator type="XMLMAPPER"
            targetPackage="com.simon.dao" 
            targetProject=".\src">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false" />
        </javaClientGenerator>
        <!-- 指定数据库表 -->
        <table schema="" tableName="simon"></table>
    </context>
</generatorConfiguration>

其实在这个配置文件中数据库的配置我就不用说了

<jdbcConnection driverClass="com.mysql.jdbc.Driver"
            connectionURL="jdbc:mysql://localhost:3306/simon" 
            userId="root"
            password="lcx66297022">
</jdbcConnection>

最主要的也是大家最关心的是这几个包的问题,我们都知道需要生成4个文件,3个java的一个xml的,我们先说实体类的。
实体类

<javaModelGenerator targetPackage="com.simon.entity"
            targetProject=".\src">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false" />
            <!-- 从数据库返回的值被清理前后的空格 -->
            <property name="trimStrings" value="true" />
</javaModelGenerator>

TargetPackage就是你现在要将生成的试题类放在哪里的问题,我一般是直接放到我项目中的包里,也是为了图省事。
.\src:就是你当前的项目中,当然也可以指定其他的路径
不过还有一种需求,假如我希望我生成的类都继承一个类,Mybatis也提供了相应的属性

<property name="rootClass"value="com.simon.Domain" />

XML映射文件

<!-- targetProject:mapper映射文件生成的位置 -->
        <sqlMapGenerator targetPackage="com.simon.dao" 
            targetProject=".\src">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false" />
</sqlMapGenerator>
Mapper接口
<!-- targetPackage:mapper接口生成的位置 -->
        <javaClientGenerator type="XMLMAPPER"
            targetPackage="com.simon.dao" 
            targetProject=".\src">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false" />
</javaClientGenerator>

我把映射文件和接口放在一个类下面了,当然如果你想放在其他的地方都可以,我在这里主要是举例。
最后的步骤就是指定需要自动生成哪张表,或者哪几张表。
指定数据库中的表

<!-- 指定数据库表 -->
<table schema="" tableName="simon"></table>

到此,配置文件结束了,我们要生成simon这个表的文件还需要最后一步,那就是运行逆向工程。

public class GeneratorSqlmap {

    public void generator() throws Exception{

        List<String> warnings = new ArrayList<String>();
        boolean overwrite = true;
        //指定 逆向工程配置文件
        File configFile = new File("generatorConfig.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();
        }

    }
}

这是个main方法,右键run就可以了,我们可以看看结果
控制台输出

2017-07-26 17:37:02,628 [main] DEBUG [org.mybatis.generator.internal.db.DatabaseIntrospector] - Retrieving column information for table "simon"
2017-07-26 17:37:02,648 [main] DEBUG [org.mybatis.generator.internal.db.DatabaseIntrospector] - Found column "simonid", data type 4, in table "simon..simon"
2017-07-26 17:37:02,648 [main] DEBUG [org.mybatis.generator.internal.db.DatabaseIntrospector] - Found column "simonname", data type 12, in table "simon..simon"
2017-07-26 17:37:02,648 [main] DEBUG [org.mybatis.generator.internal.db.DatabaseIntrospector] - Found column "simonage", data type 4, in table "simon..simon"

控制台打出的内容还是很详细的对吧,这就证明逆向工程正常运行了,那我们看看生成的文件在哪里。
这里写图片描述
多出来了两个包,这就是逆向工程生成的,我们来看下这两个包里的类
这里写图片描述
从名称上已经看得出来了吧,但是其中有个类可能很多没有用过逆向工程的会不太清楚,这就是mybatis逆向工程能让你做到依据sql都不用写的工具。如果感兴趣的朋友可以去看看这个类里面的代码,大致的思路其实就是将你的查询条件拼成一个sql语句的片段,再执行,
我们通过一个例子来看看mybatis逆向工程的查询语句如何写。为此我简单的建了张表
这里写图片描述
写Demo之前我们先将生成的4个类放到我们的工程中。
这里写图片描述
可以对比之前的逆行工程中生成的包名,和这里是对应上的,这是我的习惯,这并不是固定的,是可以配置的,在此为了省事就这么做了。
逆向工程Demo
表和类都准备好了,那么逆向工程到底给我们带来了什么便利呢?
需求:
查询ID=1的数据
如果不是逆向工程,我们是需要些sql语句的,而现在,只要是单表查询,我们就不用再写sql了。
创建一个测试类

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath*:/spring/applicationContext-mvc.xml","classpath*:/spring/applicationContext-mybatis.xml"})
public class GeneratorTest {
}

测试类用了Spring整合的junit,关于这里,大家不要觉得疑惑,你也可以先用ApplicationContext对象去做测试,如果想要了解的话网上有很多的资料。我们一步步来操作,我们既然生成了mapper文件,其实和我们之前自己写mapper道理是一样的,原来怎么用,现在也一样。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath*:/spring/applicationContext-mvc.xml","classpath*:/spring/applicationContext-mybatis.xml"})
public class GeneratorTest {

    @Autowired
    private SimonMapper mapper;

    @Test
    public void testOne(){
    }
}

调用mapper的查询方法

@Test
    public void testOne(){
        mapper.selectByExample(example);
    }

发现这个方法和我们之前的不一样,之前我们自己写,自己传参数,而在这里他需要传入一个example,我们看下这个example是什么东西?
这里写图片描述

Example是逆向工程生成的一个类,而我们查询的时候需要传入这个类,那么我们来创建一个Example类。
创建Example类

@Test
    public void testOne(){
        SimonExample example = new SimonExample();
        mapper.selectByExample(example);
    }

写了查询语句应该是有返回值的对吧,在这里返回的是一个list集合,我们需要遍历这个集合获取到数据

@Test
    public void testOne(){
        SimonExample example = new SimonExample();
        List<Simon> list = mapper.selectByExample(example);
        for (Simon simon : list) {
            System.out.println(simon);
        }
    }

查看结果

Simon [simonid=1, simonname=赵六, simonage=13]
Simon [simonid=2, simonname=赵六, simonage=13]
Simon [simonid=3, simonname=王五, simonage=13]
Simon [simonid=4, simonname=王五, simonage=13]
Simon [simonid=5, simonname=马四, simonage=13]
Simon [simonid=7, simonname=科技时代, simonage=13]
Simon [simonid=8, simonname=赵六, simonage=13]
Simon [simonid=9, simonname=赵六, simonage=13]

我们发现结果出现了所有的数据,我们的需求是ID=1的数据,也就是说我们需要给查询语句添加查询条件,这时候就需要另一个类了,Criteria,这个类的作用就是给我们的查询语句添加条件,至于如何做到的大家可以看看example这个类,实现并不难,我们来实际操作下。
先创建Criteria类,这个类是Example的内部类

@Test
    public void testOne(){
        SimonExample example = new SimonExample();
        Criteria criteria = example.createCriteria();
        List<Simon> list = mapper.selectByExample(example);
        for (Simon simon : list) {
            System.out.println(simon);
        }
    }

用Criteria添加查询条件(查询ID=1的数据)

@Test
    public void testOne(){
        SimonExample example = new SimonExample();
        Criteria criteria = example.createCriteria();
        criteria.andSimonidEqualTo(1);
        List<Simon> list = mapper.selectByExample(example);
        for (Simon simon : list) {
            System.out.println(simon);
        }
    }

结果
这里写图片描述
到这里我们的Demo就结束了,其实用法和之前类似,但是多了一个Example类和Criteria类,这两个类的主要作用就是给你的sql加查询条件的,
从第一个例子中你会发现,当我不创建Example的内部类Criteria的时候,就相当于没有添加任何查询条件,那么查询的就是所有结果
返回值是List集合,不论查询一个还是多个,如果是一个你可以用list.get(0)获取到,就不用遍历了。
逆向工程还有insert方法,update方法,delete方法,这些大家可以尝试着去做做,其实逆向工程生成的代码不同的地方就在于如何给查询加条件,也就是Example和Criteria,多试几次你就明白了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值