MyBatis 是一款优秀的支持自定义 SQL 查询、存储过程和高级映射的持久层框架,消除了几乎所有的 JDBC 代码和参数的手动设置以及结果集的检索。MyBatis 可以使用 XML 或注解进行配置和映射,MyBatis 通过将参数映射到配置的 SQL 形成最终执行的 SQL 语句,最后将执行 SQL 的结果映射成 Java 对象返回。
与其他 ORM 框架不同,MyBatis 并没有将 Java 对象与数据库关联起来,而是将 Java 方法与 SQL 语句关联。MyBatis 提供了一个映射引擎,声明式地将 SQL 语句的执行结果与对象映射起来。通过使用一种内建的类 XML 表达式语言,SQL 语句可以被动态生成。
首先创建一个入门的 demo,采用 maven 管理依赖。
项目编写完成后的完整目录:
首先在 pom.xml 文件中添加依赖。
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.18</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
首先添加 mybatis-config.xml 这个配置文件是 MyBatis 的核心配置文件。除了 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>
<typeAliases>
<package name="tk.mybatis.simple.model" />
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<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="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="tk/mybatis/simple/mapper/CountryMapper.xml"/>
</mappers>
</configuration>
<typeAliases>元素下面配置了一个包的别名,这样配置后,在使用类的时候不需要写包名的部分。
<enviroments>配置了数据库连接信息。
<mappers>中配置了一个包含完整类路径的 XML 配置文件,这个一个 MyBatis 的 SQL 语句和映射配置文件。
创建 Country 实体类,和对应的 mapper 包下的 CountryMapper.xml 文件。下面是 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="tk.mybatis.simple.mapper.CountryMapper">
<select id="selectAll" resultType="Country">
select id, countryname, countrycode from country
</select>
</mapper>
如果在 mybatis-config.xml 中没有配置 <typeAliases> 这个属性时,那么在 CountryMapper.xml 中的 resultType 中的值时需要写全类名。
然后编写一个测试类。
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() {
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
List<Country> countryList = sqlSession.selectList("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());
}
}
}
在这个测试类中, 首先加载 mybatis-config.xml 这个配置文件,然后通过 SqlSession 的 selectList 方法查找到 CountryMapper.xml 中的 id=”selectAll" 的方法,执行 SQL 查询。MyBatis 底层使用 JDBC 执行 SQL,获得查询结果集 ResultSet 后,根据 resultType 的配置将结果映射为 Country 类型的集合,返回查询结果。
这样就完成了这个 demo,运行后即可得到这个测试结果。
补充一下 JDBC 的代码写法。
public class DbUtil {
public static final String URL = "jdbc:mysql://localhost:3306/imooc";
public static final String USER = "liulx";
public static final String PASSWORD = "123456";
public static void main(String[] args) throws Exception {
//1.加载驱动程序
Class.forName("com.mysql.jdbc.Driver");
//2. 获得数据库连接
Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
//3.操作数据库,实现增删改查
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT user_name, age FROM imooc_goddess");
//如果有数据,rs.next()返回true
while(rs.next()){
System.out.println(rs.getString("user_name")+" 年龄:"+rs.getInt("age"));
}
}
}
MyBatis 的真正强大之处在于它的映射语句,这也是它的魔力所在。以前使用 SqlSession 通过命名空间调用 MyBatis 方法时,首先需要用到命名空间和方法 id 组成的字符串来调用相应的方法。使用接口调用方法就会方便很多,MyBatis 使用 Java 的动态代理可以直接通过接口来调用相应的方法。
修改上面的 demo 将上面改成通过接口来调用相应的方法。新增一个文件 CountryMapper.java 如下图。
然后在修改测试文件中的 testSelectAll 方法。
@Test
public void testSelectAll() {
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
//List<Country> countryList = sqlSession.selectList("selectAll");
CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
List<Country> countryList = mapper.selectAll();
printCountryList(countryList);
}
}
注释的那一行是旧的方法。新的代码是通过接口调用的。
由于 XML 映射文件较多,依次配置较为麻烦,可以修改 mybatis-config.xml 中 <mappers> 标签内容为如下内容。
<mappers>
<!--
<mapper resource="tk/mybatis/simple/mapper/CountryMapper.xml"/>
-->
<package name="tk.mybatis.simple.mapper"/>
</mappers>
注释的内容是之前的配置,新的配置会先查找配置的包下所有的接口,循环对接口进行如下操作:
1 判断接口对应的命名空间是否存在,如果存在就抛出异常,不存在就继续;
2 加载接口对应的 XML 映射文件,将接口全限定名转换为路径,例如,将接口 tk.mybatis.simple.mapper.UserMapper 转换为 tk/mybatis/simple/mapper/UserMapper.xml,以 .xml 为后缀搜索 XML 资源,如果找到就解析XML;
3 处理接口中的注解方法。
可以发现,XML 中的 select 标签的 id 属性值和定义的接口方法名是一样的。
MyBatis 就是通过这种方式将接口方法和 XML 中定义的 SQL 语句关联到一起的。
以上就是关于 MyBatis 的基本使用。
参考:
本文是阅读刘增辉的《MyBatis从入门到精通》时记录的笔记,非原创。