MyBatis
是一款优秀的支持自定义SQL
查询、存储过程和高级映射的持久层框架,消除了几乎多有的JDBC
代码和参数的手动设置和结果集的检索。MyBatis
可以使用XML
和注解进行配置和映射,MyBatis
通过将参数映射到配置的SQL
形成最终执行的SQL
语句,最后将执行SQL
的结果映射成Java
对象返回。
Maven
是一个优秀的项目构建和管理工具,使用Maven
构建项目非常方便,可以非常方便地处理Jar
包依赖问题。这里提供构建MyBatis
应用的的pom.xm
l配置内容。
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.lemongroupId>
<artifactId>lemon-mybatisartifactId>
<version>1.0-SNAPSHOTversion>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<mybatis.version>3.4.6mybatis.version>
<junit.version>4.12junit.version>
<mysql.connector.version>8.0.11mysql.connector.version>
<slf4j.version>1.7.25slf4j.version>
<log4j.version>1.2.17log4j.version>
<lombok.version>1.16.20lombok.version>
properties>
<dependencies>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>${mybatis.version}version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>${junit.version}version>
<scope>testscope>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>${mysql.connector.version}version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-apiartifactId>
<version>${slf4j.version}version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-log4j12artifactId>
<version>${slf4j.version}version>
<scope>testscope>
dependency>
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>${log4j.version}version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>${lombok.version}version>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>3.7.0version>
<configuration>
<source>1.8source>
<target>1.8target>
<encoding>UTF-8encoding>
configuration>
plugin>
plugins>
build>
project>
其中
标签指定了源代码的编码方式为UTF-8
,以及项目所依赖的Jar
包的版本。除了引入MyBatis
应用所必须的Jar
以外,还引入了lombok
,lombok
是一款非常优秀的插件,它可以被安装到Eclipse
和IntelliJ IDEA
上,使用lombok
的相关注解可以使得创建JavaBean
的代码十分简洁,至于如何使用,可以去CSDN
上找到相关博客学习一下。
这里准备一个非常简单的MySQL
数据库,数据库的编码方式设置为UTF-8
,现在提供相关的SQL
语句来建立数据库并插入测试数据。
-- 创建名称为lemon-mybatis的数据库
CREATE DATABASE lemon-mybatis DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
-- 使用数据库
use lemon-mybatis;
-- 创建数据库表并插入数据
DROP TABLE IF EXISTS `country`;
CREATE TABLE `country` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`countryName` varchar(255) DEFAULT NULL,
`countryCode` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
);
INSERT `country` (`countryName`, `countryCode`)
VALUES ('中国', 'CN'), ('美国', 'US'),
('俄罗斯', 'RU'), ('英国', 'GB'), ('法国', 'FR');
配置MyBatis
的方式有多种,最常见的是使用XML
形式进行配置,当然,与Spring
进行整合的时候,也可以使用Spring Bean
的方式进行配置,另外还可以通过Java
编码方式进行配置,但是这种方式不常用,这里仅仅使用XML
形式配置MyBatis
。
在项目的src/main/resources
文件夹下面创建mybatis-config.xml
配置文件,具体配置的内容如下:
<configuration>
<settings>
<setting name="logImpl" value="LOG4J"/>
settings>
<typeAliases>
<package name="com.lemon.example.model"/>
typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">
<property name="" value=""/>
transactionManager>
<dataSource type="UNPOOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://192.168.171.133:3306/lemon-mybatis?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="com/lemon/example/mapper/CountryMapper.xml"/>
mappers>
configuration>
简单介绍一下这个配置文件:
中的logImpl
属性配置指定使用LOG4J
输出日志
配置了一个包的别名,通常情况下,辨别一个类使用的是类的全限定名称,比如com.lemon.example.model.Country
,在Mybatis
中会频繁使用到类的全限定名称,所以配置包的别名以后,在配置文件中需要使用到全限定名称的时候直接写简单的类名即可,如Country
。
环境配置中主要配置了数据库连接,可以同时配置多个数据库连接环境,内部使用
隔离不同的环境。
标签是配置配置Mapper
文件的标签,其内部可以配置多个多个类似CountryMapper.xml
,使用的是
标签,也可以使用
标签,更加便捷,后面会介绍更多细节。
MyBatis
是一个结果映射型框架,一般在数据库设计和实体类设计的过程中,都是一个表对应一个实体类,对数据库的增删改查一般都是将实体类作为数据载体。而这里的Mapper.xml
文件,是SQL
语句和结果映射的基本载体,一般的命名习惯是实体类的名称加上Mapper
,比如CountryMapper.xml
。在实际的开发过程中,一个实体类Country
对应一个接口CountryMapper.java
和CountryMapper.xml
文件,其中接口CountryMapper.java
放在src/main
下面的包里,比如com.lemon.example.mapper
,而CountryMapper.xml
文件则放在src/main/resources
文件夹下,建立的各层文件夹和对应的接口包名一致,如com/lemon/example/mapper
,其中接口并不是必须的。
本例中实体类Country
的代码为:
package com.lemon.example.model;
import lombok.Data;
/**
* @author lemon
* @date 2018/4/22 下午9:32
*/
@Data
public class Country {
private Long id;
private String countryName;
private String countryCode;
}
这里导入了lombok
的Data
注解,在运行时会自动为实体类创建getter
和setter
方法。本例中没有创建CountryMapper
接口,所以直接创建CountryMapper.xml
文件,代码如下:
<mapper namespace="com.lemon.example.mapper.CountryMapper">
<select id="selectAll" resultType="Country">
select id, countryName, countryCode from country
select>
mapper>
对于上面的Mapper
文件,进行如下解释:
标签
是XML
的根元素,属性namespace
定义了当前XML
的命名空间,是唯一的,如果没有创建该Mapper
文件的Mapper
接口,那么这个命名空间可以随意设置,如果创建了接口,那么这个命名空间的值必须是对应接口的全限定类名。
标签是定义查询的语句的标签,它的属性
id
是该标签的标识,是唯一的,如果该Mapper
文件有对应的接口,那么id
是对应接口的方法名称,属性resultType
是描述查询结果映射到哪个实体类中,由于在mybatis-config.xml
文件中配置了别名,所以这里仅仅需要写Country
(不区分大小写,但是为了统一,建议和类名一致)即可,否则将需要写全限定类名com.lemon.example.model.Country
。
对于项目的开发,一看都要量身定制日志文件,以便调优,这里将在src/main/resources
文件夹下建立log4j.properties
文件,代码如下:
# 全局配置
log4j.rootLogger=ERROR, stdout
# Mybatis日志配置
log4j.logger.com.lemon.example.mapper=TRACE
# 控制台输出配置
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
日志的全局配置是Error
级别的,设置的是控制台输出,这是最简单的设置,也是开发阶段比较实用的设置。Mybatis
日志配置指定了包名com.lemon.example.mapper
,它对应的是接口,TRACE
是最低级别的日志,这可以使得SQL
语句执行的信息也会被打印出来。控制台输出配置了控制台日志打印的基本格式。
本篇文章是一个入门案例,介绍了Mybatis
最基本的配置,接下来编写一个测试代码,看看代码的运行效果。测试代码一般在Maven
项目中都是写在src/test/java
下的包中的,建立包com.lemon.example.mapper
,并在该包下创建基础测试类BaseMapperTest
,代码如下:
package com.lemon.example.mapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.BeforeClass;
import java.io.IOException;
import java.io.Reader;
/**
* 测试基础类
*
* @author lemon
* @date 2018/5/20 下午11:37
*/
public class BaseMapperTest {
private static SqlSessionFactory sqlSessionFactory;
@BeforeClass
public static void init() {
try {
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public SqlSession getSqlSession() {
return sqlSessionFactory.openSession();
}
}
这是一个基础类,主要负责加载mybatis-config.xml
来创建SqlSession
实例对象,因为后期会有很多测试,如果每个测试都要重复编写获取SqlSession
实例对象的代码,就显得有些多余了,这里进行了基本的代码重构复用。对于CountryMapper
的测试,代码如下:
package com.lemon.example.mapper;
import com.lemon.example.model.Country;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
/**
* @author lemon
* @date 2018/5/8 下午5:22
*/
public class CountryMapperTest extends BaseMapperTest {
@Test
public void testSelectAll() {
try (SqlSession sqlSession = getSqlSession()) {
List<Country> countryList = sqlSession.selectList("com.lemon.example.mapper.CountryMapper.selectAll");
printCountryList(countryList);
}
}
private void printCountryList(List<Country> countryList) {
for (Country country : countryList) {
System.out.printf("%-4d%4s%4s\n", country.getId(), country.getCountryName(), country.getCountryCode());
}
}
}
对上面两段代码进行如下解释:
通过Resources
工具类将mybatis-config.xml
配置读入Reader
。
再通过SqlSessionFactoryBuilder
建造类使用Reader
创建SqlSessionFactory
工厂对象,在创建SqlSessionFactory
工厂对象过程中,首先会解析mybatis-config.xml
配置文件,解析完成之后,SqlSessionFactory
工厂对象就包含了所有的属性配置和执行SQL
的信息。
通过继承BaseMapperTest
类,直接调用父类的getSqlSession
方法可以直接获取SqlSession
对象。
通过SqlSession的selectList
方法查找到CountryMapper.xml
中id="selectAll"
方法,执行SQL
语句,MyBatis
底层使用JDBC
执行SQL
语句,并将查询到的结果集ResultSet
后,根据resultType
的配置将结果映射到Country
类型的集合中,返回查询结果。
最后将查询到的结果按照指定的格式进行输出到控制台。记得要关闭SqlSession
,常见的做法是将其写在finally
块中,但是代码中使用的是JDK1.7
的新特性,直接写在try
后面的圆括号里面,资源在利用完毕之后会自动关闭,这样做代码更加简洁。
执行测试代码,输出的日志如下所示:
DEBUG [main] - ==> Preparing: select id, countryName, countryCode from country
DEBUG [main] - ==> Parameters:
TRACE [main] - <== Columns: id, countryName, countryCode
TRACE [main] - <== Row: 1, 中国, CN
TRACE [main] - <== Row: 2, 美国, US
TRACE [main] - <== Row: 3, 俄罗斯, RU
TRACE [main] - <== Row: 4, 英国, GB
TRACE [main] - <== Row: 5, 法国, FR
DEBUG [main] - <== Total: 5
1 中国 CN
2 美国 US
3 俄罗斯 RU
4 英国 GB
5 法国 FR
这篇博文仅仅是对Mybatis
进行了一个简单的案例实战,后面会继续发布多篇Mybatis
的学习笔记,欢迎阅读,我们共同进步。
更多干货分享,欢迎关注我的微信公众号:爪哇论剑(微信号:itlemon)