MyBatis基础篇

Mybatis的基本认识,映射文件、核心配置文件的配置


Mybatis简介

Mybatis官方文档
MyBatis是目前最为流行的持久层框架之一,相比于Hibernate框架,Mybatis更容易使用,并且支持定制SQL语句,存储过程以及高级映射。


Mybatis入门

要使用mybatis只需要导入mybatis-x.x.x.jar包即可,包下载地址:http://mvnrepository.com,使用mybatis需要对映射文件以及核心配置文件进行相关的配置。Mybatis要操作数据库需要配置SqlSessionFactory,利用工厂对象来获取sqlSession对象。SqlSessionFactory可以在xml文件中配置,也可以直接在Java类中配置。

在XML文件中配置SqlSessionFactory

关于在xml中配置SqlSessionFactory官方文档上是这样说的:

The configuration XML file contains settings for the core of the MyBatis system, including a
DataSource for acquiring database Connection instances, as well as a TransactionManager for
determining how transactions should be scoped and controlled.

也就是说我们需要配置数据库连接的数据源dataSource以及事务管理器,例如:

mybatis-config.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 读取数据库连接资源文件 -->
<properties resource="db.properties" />
<environments default="development">
<environment id="development">
<!-- 使用JDBC管理事务 -->
<transactionManager type="JDBC" />
<!-- 配置数据库连接池 -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
<!-- 引入SQL映射文件 -->
<mappers>
<mapper resource="org/mybatis/example/XxxMapper.xml"/>
</mappers>
</environments>
</configuration>

当然,这只是最基本的操作,事实上如果mybatis与spring整合了,那么关于数据库连接这一块的配置在Spring的配置文件中进行配置更加合理,这仅仅是一个简单的例子。进行了数据库连接相关的配置之后,就可以在Java类(DAO)中读取配置文件并创建SqlSessionFactory工厂了:

在类中加载资源文件
1
2
3
4
5
6
7
8
// 声明资源文件的位置(这里配置在src路径下)
String resource = "mybatis-config.xml";
// 读取资源文件
InputStream in = Resources.getResourceAsStream(resource);
// 创建SqlSessionFactory工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
// 获取session
SqlSession sqlSession = sessionFactory.openSession();

不使用XML构建SqlSessionFactory

在查阅官方文档的时候,关于不使用XML构建SqlSessionFactory的方法,官方给出来如下代码:

1
2
3
4
5
6
+ DataSource dataSource = BlogDataSourceFactory.getBlogDataSource();
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment("development", transactionFactory, dataSource);
Configuration configuration = new Configuration(environment);
configuration.addMapper(BlogMapper.class);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);

代码中用到了一个BlogDataSourceFactory,本来我估计是一个接口,但当我去查看源码的时候,发现好像并没有一个叫BlogDataSourceFactory的类或者接口。关于DataSource这一部分的包结构如下:

datasourcefactory

可以发现,mybatis提供了三种不同类型的数据源工厂类型:JndiDataSourceFactoryPooledDataSourceFactoryUnpooledDataSourceFactory,这三个类都是DataSourceFactory接口的实现类,这意味着我们可以创建三种不同类型的数据源,当然最为常用的肯定是连接池类型的数据源,即:PooledDataSourceFactory类,以这个类为例,不使用XMl文件来构建SqlSessionFactory:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 创建资源对象
Properties properties = new Properties();
// 设置属性
properties.setProperty("driver", "com.mysql.cj.jdbc.Driver");
properties.setProperty("url", "jdbc:mysql://localhost:3306/mybatis?useSSL=false&serverTimezone=GMT%2B8");
properties.setProperty("username", "mackvord");
properties.setProperty("password", "12345678");
// 创建连接池工厂
DataSourceFactory dataSourceFactory = new PooledDataSourceFactory();
dataSourceFactory.setProperties(properties);
// 获取数据源
DataSource dataSource = dataSourceFactory.getDataSource();
// 创建事务工厂
TransactionFactory transactionFactory = new JdbcTransactionFactory();
// 创建Environment对象
Environment environment = new Environment("development", transactionFactory, dataSource);
// 创建Configuration对象
Configuration configuration = new Configuration(environment);
// 添加映射类
configuration.addMapper(UserMapper.class);
// 创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);

Mybatis XML映射文件

在xml映射文件中一共有9个元素:
    1、cache - 配置给定命名空间的缓存。
    2、cache-ref – 从其他命名空间引用缓存配置。
    3、resultMap – 最复杂,也是最强大的元素,用来描述如何从数据库结果集中来加载你的对象。
    4、parameterMap – 已废弃!
    5、sql – 可以重用的 SQL 块,也可以被其他语句引用。
    6、insert – 映射插入语句
    7、update – 映射更新语句
    8、delete – 映射删除语句
    9、select – 映射查询语句

select元素

在以上几个元素中,select应该是最为常用的,此标签主要用于查询操作,例如:

1
2
3
<select id="findUserById" resultType="User">
SELECT * FROM USER WHERE ID = #{id}
</select>

id值可以自定义,但是为了规范,id值应该填写Mapper接口中对应的方法名,resultType为返回结果的类型。select元素可用的属性如下:

属性 描述
id 在命名空间中唯一的标识符,可用来引用select标签中的SQL语句
databaseid 数据库ID(数据库的版本)
fetchSize 设置驱动程序每次批量返回的结果行数
flushCache 清空缓存,默认值为false
parameterMap 这是引用外部 parameterMap,已废弃
parameterType 传入SQL语句的参数的完整类名或别名
resultOrdered 默认为false,适用于嵌套结果的Select语句
resultSets 设置多结果集名称
resultSetType 可选值:FORWARD_ONLY、SCROLL_SENSITIVE、SCROLL_INSENSITIVE。默认为不设置,由驱动程序决定
resultType 语句中返回类型的完整类名或别名。如果是集合,则是集合中泛型的类型
resultMap 命名引用外部的 resultMap
statementType 可选值:STATEMENT,PREPARED 或 CALLABLE,即: Statement,PreparedStatement 或 CallableStatement,默认为PREPARED
timeout 设置超时时间
useCache 默认为true,启用缓存,缓存SQL语句返回的结果

关于其他元素的属性值设置,可查看官方文档

sql元素
<sql id="xx">标签可以抽取SQL中重复的片段,在需要引用的地方可以使用<include id="xx">标签进行引用


动态SQL

什么是动态SQL?按我自己的理解就是在SQL映射文件中嵌入标签元素,使用这些标签能够帮助我们定制化SQL语句。

if标签

<if test=""></if>标签:进行参数判断,例如判断参数是否为空null或者为空字符串
<where>标签可以去掉第一个前and,即第一个条件判断成立的语句中的前面的第一个and会被去掉

forEach
forEach标签的collection属性,如果参数是数组,那么collection属性的值需填写array,如果是集合,那么填写list,如果参数是VO对象中的某个属性,那么直接填写VO对象的类名称即可。


逆向工程

官方文档
GitHub源码下载地址

mybatis中的逆向工程能实际上指的就是代码生成器,它能够帮助我们自动地生成一些低创造性的代码,例如POJO类、Mapper接口、Sql映射文件,这些类和接口都是最为基础性的、但同时又是不可或缺的,例如:数据库中有一百张数据表,那么意味着可能要为这一百张表创建一百个与之对应的POJO类,如果让程序员去做这件事的话,无疑是浪费人力财力,而Mybatis官方也考虑到了这个问题,为了能够提高开发的效率,让开发者更专注于有创造性的工作,Mybatis官方提供逆向工程的解决方案,帮助开发者解决这些简单而又繁琐的问题。


逆向工程的使用

在使用逆向工程生成POJO类、Mapper接口以及Sql映射文件时,为了避免影响现有的项目、建议新建一个项目来进行。下面以Oracle数据库中SCOTT用户下的EMP表和DEPT表为例,逆向生成POJO类、Mapper接口、Sql映射文件。


导包

jar


创建generatorConfig.xml文件

generatorConfig.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?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="OracleTables" targetRuntime="MyBatis3">
<!-- 配置数据库连接 -->
<jdbcConnection
driverClass="oracle.jdbc.driver.OracleDriver"
connectionURL="jdbc:oracle:thin:@localhost:1521:mack" userId="scott"
password="tiger">
</jdbcConnection>

<!-- 配置Java解析类型 -->
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>

<!-- 配置POJO类的生成位置 -->
<javaModelGenerator targetPackage="com.my.mybatis.pojo" targetProject=".\src">
<!-- 是否让schema作为包后缀 -->
<property name="enableSubPackages" value="false" />
<!-- 取出数据库返回值的前后空格 -->
<property name="trimStrings" value="true" />
</javaModelGenerator>

<!-- mapper映射文件的生成位置 -->
<sqlMapGenerator targetPackage="com.my.mybatis.mapper" targetProject=".\src">
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>

<!-- 配置mapper接口的生成位置 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.my.mybatis.mapper" targetProject=".\src">
<property name="enableSubPackages" value="false" />
</javaClientGenerator>

<!-- 指定用于逆向的数据表 -->
<table schema="" tableName="EMP" domainObjectName="Employee"></table>
<table schema="" tableName="DEPT" domainObjectName="Department"></table>
</context>
</generatorConfiguration>

编写工具类

核心代码Mybatis官网有提供,详情查看官方文档

SqlMapGenerator.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package com.my.util;

import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
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.exception.InvalidConfigurationException;
import org.mybatis.generator.exception.XMLParserException;
import org.mybatis.generator.internal.DefaultShellCallback;

/**
* mybatis逆向工程工具类,
* @author Mackvord
* @date 2018年8月22日
* @version 1.0
*/
public class SqlMapGenerator {

/**
* 生成POJO类、Mapper接口、Mapper映射文件
* @throws IOException
* @throws XMLParserException
* @throws InvalidConfigurationException
* @throws SQLException
* @throws InterruptedException
*/
public static void generator() throws IOException, XMLParserException, InvalidConfigurationException, SQLException, InterruptedException {
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);
}

}

测试

测试类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.my.test;

import java.io.IOException;
import java.sql.SQLException;

import org.junit.Test;
import org.mybatis.generator.exception.InvalidConfigurationException;
import org.mybatis.generator.exception.XMLParserException;

import com.my.util.SqlMapGenerator;

/**
* 测试mybatis逆向工程生成POJO、Mapper接口、Mapper映射文件
* @author Mackvord
* @date 2018年8月22日
* @version 1.0
*/
public class SqlMapGeneratorTest {

@Test
public void generatorTest() {
try {
SqlMapGenerator.generator();
} catch (IOException | XMLParserException | InvalidConfigurationException | SQLException
| InterruptedException e) {
e.printStackTrace();
}
}

}

结果:

binggo


如果您觉得我的文章对您有帮助,请随意赞赏,您的支持将鼓励我继续创作!
0%