您的位置:首页 > 其它

Mybatis之逆向工程

2017-07-26 22:41 483 查看
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"
4000

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逆向工程的查询语句如何写。为此我简单的建了张表



a5c7

写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,多试几次你就明白了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: