一、简介
MyBatis前身是iBATIS,是一款优秀的支持自定义SQL查询、存储过程和高级映射的持久层框架。消除了几乎所有JDBC代码和参数的手动设置,以及结果集的检索。MyBatis可以使用XML或注解进行配置和映射,MyBatis通过将参数映射到配置的SQL形成最终执行的SQL语句,最后将执行结果映射成java对象返回。
与其他ORM(对象关系映射)框架不同,MyBatis没有将java对象与数据库表相关联,而是将Java方法与sql语句关联。MyBatis允许用户充分利用数据库的各种功能:存储过程、视图、各种复杂查询以及某数据库的专有特性。
与JDBC相比,MyBatis简化了相关代码,SQL语句在一行代码中就能执行,MyBatis提供了一个映射引擎,声明式的将SQL语句的执行结果与对象树映射起来。通过一种內建的类XML表达式语言,SQL语句可以动态的生成。
MyBatis支持声明式数据缓存(declarative data caching),当一条SQL语句被标记为“可缓存”后,首次执行从数据库获取的所有数据会被存储在高速缓存中,后面再执行这条语句就会从高速缓存中获取结果而不是再次命中数据库。Mybatis提供了默认情况下基于java的HashMap缓存实现,以及用于与OSCache、EHCache、Hazelcast和Memcached连接的默认连接器,同时还提供了API供其他缓存实现使用。
二、上手(环境:IDEA、MySQL)
新建一个简单地Maven项目。
1.首先需要导入Mybatis、MySQL和log4j的依赖,如下:
<!--MyBatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.3.0</version>
</dependency>
<!--MySQL-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<!--日志-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
2.接着在mysql中新建mybatis的数据库,具体操作省略,可自行百度。新建表结构country:id(int自增),countryname(varchar,255),countrycode(varchar,255),插入几条数据
insert into country values(1,'中国','CN');
insert into country values(2,'美国','US');
insert into country values(3,'俄罗斯','RU');
3.接着在src/main/resources文件夹下创建mybatis-config.xml文件,进行如下简单配置:
<?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>
<settings>
<!--logImpl配置指定使用LOG4J输出日志-->
<setting name="logImpl" value="LOG4J"/>
</settings>
<typeAliases>
<!--配置类的全限定名称路径-->
<package name="xin.shenwan.simple.model"/>
</typeAliases>
<!--数据库链接-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">
<property name="" value=""/>
</transactionManager>
<dataSource type="UNPOOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value=""/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="xin/shenwan/simple/mapper/CountryMapper.xml"/>
</mappers>
</configuration>
其中:
<settings>中的logImpl属性配置指定使用LOG4J输出日志。
<typeAliases>元素下边配置了包的别名,因为在MyBatis中需要频繁使用类的全限定名称,所以为了方便,声明一个javabean包包的别名,这样在使用类时不需要写包名的部分,只写类名即可。
<environments>环境主要配置了数据库链接
<mapper>中配置了一个包含完全类路径的CountryMapper.xml,这是一个Mybatis的SQL语句和映射配置文件。
4.创建实体类和Mapper.xml文件
实体类:
package xin.shenwan.simple.model;
/**
* Created by 12450 on 2019/3/17.
*/
public class Country {
private Long id;
private String countryname;
private String countrycode;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCountryname() {
return countryname;
}
public void setCountryname(String countryname) {
this.countryname = countryname;
}
public String getCountrycode() {
return countrycode;
}
public void setCountrycode(String countrycode) {
this.countrycode = countrycode;
}
}
Mapper.xml文件
为了体现一致性,在src/main/resources下创建于javabean包名相对应的路径,不同的时将model改为mapper。在该目录下创建CountryMapper.xml文件,添加如下内容
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="xin.shenwan.simple.mapper.CountryMapper">
<select id="selectAll" resultType="Country">
SELECT id,countryname,countrycode from country
</select>
</mapper>
其中:
<mapper>:xml的根元素,属性namespace定义了当前xml的命名空间;
<select>:我们所定义的一个select查询
id属性:在整个xml文件中具有唯一性,一般与dao层接口中方法名一致
resultType:定义了当前查询的返回值类型,如果没有设置别名,要写类的全限定名
5.配置LOG4J
在src/main/resources中新建log4j.properties文件,加入如下内容:
#全局配置
log4j.rootLogger=ERROR,stdout
#Mybatis日志配置
log4j.logger.xin.shenwan.simple.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
MyBatis日志的最低级别时TRACE,在这个日志级别下,MyBatis会输出执行SQL过程中的详细信息。
6.编写测试代码
在src/test/main 中创建xin.shenwan.simple.mapper包,然后创建如下类,进行测试。
package xin.shenwan.simple.mapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.*;
import org.junit.BeforeClass;
import org.junit.Test;
import xin.shenwan.simple.model.Country;
import java.io.IOException;
import java.io.Reader;
import java.sql.Connection;
import java.util.List;
/**
* Created by 12450 on 2019/3/17.
*/
public class CountryMapperTest {
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();
}
}
@Test
public void testSelectAll(){
SqlSession sqlSession = sqlSessionFactory.openSession();
List<Country> list = sqlSession.selectList("selectAll");
printCountryList(list);
}
public void printCountryList(List<Country> list){
for (Country country:list) {
System.out.printf("%-4d%4s%4s\n",country.getId(),country.getCountryname(),country.getCountrycode());
}
}
}
MyBatis运行原理:
1.通过Resources工具类将mybatis-config.xml配置文件读入reader;
2.通过SqlSessionFactoryBuilder建造类使用Reader创建SqlSessionFactory工厂对象,在创建SqlSessionFactory对象的过程中,首先解析mybatis-config.xml文件,读取配置文件中的mappers配置后会读取全部的XXXMapper.xml进行具体方法的解析,在这些解析完成后,SqlSessionFactory就包含了所有的属性配置和执行SQL信息;
3.在使用时,通过SqlSessionFactory工厂对象获取一个SqlSession;
4.使用SqlSession的selectList方法进行查找到某个Mapper.xml中的id为"selectAll"的方法,执行SQL查询;
Mybatis底层使用JDBC执行SQL,获得查询的结果集ResultSet后,根据resultType的配置将结果映射成对应的类型,返回查询结果。
最后一定不要忘记 关闭SqlSession,否则数据库连接数过多,造成系统崩溃。