MyBatis 学习笔记
Mybatis
准备工作
使用 MyBatis 必须导入其 jar 包,在 maven 中的 pom.xml 中声明以下依赖。
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
</dependencies>
名词声明
MyBatis 根配置文件
在本文中将 MyBatis 的配置文件(即 configuration 文件)统称为 MyBatis 根配置文件。
官方文档: mybatis - MyBatis 3 | 配置
一个最基本的 MyBatis 根配置文件如下:
<?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>
<environments default="dev">
<environment id="dev">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/db"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
</configuration>
常用配置: 环境配置(environments)、SQL 映射文件声明(mappers)、类型别名(typeAliases)
SQL 映射文件
在本文中将使用 XML 映射 SQL 语句的文件统称为 SQL 映射文件。
官方文档: mybatis - MyBatis 3 | XML 映射器
一个最基本的 SQL 映射文件如下:
<?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="">
</mapper>
命名空间(namespace)的作用有两个,一个是利用更长的全限定名来将不同的语句隔离开来,同时也可以实现接口绑定。长远来看,只要将命名空间置于合适的 Java 包命名空间之中,你的代码会变得更加整洁,也有利于你更方便地使用 MyBatis。
SQL 映射文件注意事项
- DQL 通过 resultType 指定返回值类型, 如果返回值是 List 则指定 List 中所存数据的的数据类型即可。
- DML 语句不能指定 restultType , 其返回值固定为 int 类型
加载不到 Mapper 的问题
原因一
报错信息:
Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for com.xtyuns.dao.impl.MessageDaoImpl.getAllMessage
原因: 未在 MyBatis 根配置文件中声明 SQL 映射文件
分析: 此时虽然编写了 SQL 映射文件, 但是 mybatis 并不知道哪些文件是 SQL 映射文件, 所以我们需要在 MyBatis 根配置文件中的 mappers
标签下 使用 mapper
标签声明哪些文件是 SQL 映射文件。
<mappers>
<mapper resource="com/xtyuns/dao/impl/MessageDaoImpl.xml"/>
</mappers>
原因二
报错信息:
(同原因一)Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for co.xtyuns.dao.impl.MessageDaoImpl.getAllMessage
原因: 如果原因一排查后依然产生该报错信息, 那么可能是 SqlSession 所执行的语句没有和 SQL 映射文件中的 id/namespace 对应。
分析: 使用 SqlSession 执行语句是根据 SQL 映射文件中的 namespace
+ id
来确定唯一的一条语句的, 因此此时应该检查你的 SqlSession 中执行的语句是否和 SQL 映射文件中的信息一致。
原因三
报错信息:
Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not find resource com/xtyuns/dao/impl/MessageDaoImpl.xml
原因: maven 在编译的过程中没有将 src/main/java 文件夹下的 SQL 映射文件进行编译。
分析: 此问题发生在将 SQL 映射文件(.xml) 写在 src/main/java 文件夹下时。
因为在 maven 的默认配置中 src/main/java 文件夹下只存在 Java文件(.java), 所以在执行编译的过程中将其他文件都忽略了, 就导致了编译后的目录中不存在 SQL 映射文件, 因此 MyBatis 的根配置文件中无法加载其中声明的 SQL 映射文件, 此时我们需要在 pom.xml 中重新指定资源文件路径。
注意: 自定义的 resources 标签会替换 Super POM 中默认的资源路径: ${project.basedir}/src/main/resources
, 并未为追加 resource 配置, 因此需要配置两条 resource 记录。
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
面试题
#{} 和 ${} 的区别
{} 和 ${} 最重要的不同点就是: 前者使用预编译处理来执行 SQL 语句, 而后置是直接将 ${xxx} 替换为目标变量。
{ name: "anyone" } -> select * from people where name=#{name}
编译结果: select * from people where name=?
{ name: "anyone" } -> select * from people where name=${name}
编译结果: select * from people where name='anyone'