1.MyBaits简介
MyBatis 是一个优秀的持久层框架,它对 jdbc 的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需 要花费精力去处理例如注册驱动、创建 connection、创建 statement、手动设 置参数、结果集检索等 jdbc 繁杂的过程代码。MyBatis 通过 xml 或注解的方 式将要执行的各种 statement(statement、preparedStatemnt、 CallableStatement)配置起来,并通过 java 对象和 statement 中的 sql 进行 映射生成最终执行的 sql 语句,最后由 MyBatis 框架执行 sql 并将结果映射成 java 对象并返回。
2.创建Mapper.xml文件
创建Mapper.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="path"> </mapper>
path填入Mapper文件的路径
创建一个新的mapper,需要首先给它取一个namespace,这相当于是一个分隔符,因为我们在项目中,会存在很多个Mapper,每一个Mapper中都会定义相应的增删改查方法,为了避免方法冲突,也为了便于管理,每一个Mapper 都有自己的namespace,而且这个namespace不可以重复。
不要忽略 XML 配置:
我们可以在 pom.xml 中,添加如下配置,让 Maven 不要忽略我在 java 目录下的 XML 配置:
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
按照 Maven 的要求来,将 xml 文件放到 resources 目录下,但是,MyBatis 中默认情况下要求,xxxMapper.xml 和 xxxMapper 接口,必须放在一起, 所以,我们需要手动在 resources 目录下,创建一个和 xxxMapper 接口相同 的目录,这样,我们就不需要在 pom.xml 文件中添加配置了,因为这种写法同时满足 了 Maven 和 MyBatis 的要求。
3.resultMap 映射写法
- 一对一关系: 比如一本书,对应一个作者,对应的pojo如下:
public class Book {
private Integer id;
private String name;
private Author author;//Book中装了一个作者
...
//省略get,set方法
...
}
- 根据id查询book
Book getBookById(int id);
<?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="org.javaboy.mybatis.mapper.BookMapper">
<resultMap id="BookWithAuthor" type="org.javaboy.mybatis.model.Book">
<id column="id" property="id"/>
<result column="name" property="name"/>
<!-- association 节点用来描述一对一关系-->
<association property="author" javaType="org.javaboy.mybatis.model.Author">
<id column="aid" property="id"/>
<result column="aname" property="name"/>
<result column="aage" property="age"/>
</association>
</resultMap>
<select id="getBookById" resultMap="BookWithAuthor">
SELECT b.*,a.`age` AS aage,a.`id` AS aid,a.`name` AS aname FRO
M book b,author a WHERE b.`aid`=a.`id` AND b.`id`=#{id}
</select>
</mapper>
- 将公共的属性抽出来,可以减少重复的代码
<?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="org.javaboy.mybatis.mapper.BookMapper">
<resultMap id="BaseResultMap" type="org.javaboy.mybatis.model.Book">
<id column="id" property="id"/>
<result column="name" property="name"/>
</resultMap>
<!-- extends 节点用来继承上面的BaseResultMap这个公共的模板,这样就可以不需要写公共的属性了-->
<resultMap id="BookWithAuthor" type="org.javaboy.mybatis.model.Bo ok" extends="BaseResultMap">
<association property="author" javaType="org.javaboy.mybatis.model.Author">
<id column="aid" property="id"/>
<result column="aname" property="name"/>
<result column="aage" property="age"/> </association>
</resultMap>
<select id="getBookById" resultMap="BookWithAuthor">
SELECT b.*,a.`age` AS aage,a.`id` AS aid,a.`name` AS aname FRO
M book b,author a WHERE b.`aid`=a.`id` AND b.`id`=#{id}
</select>
</mapper>
- 使用懒加载
上面这种加载方式,是一次性的读取到所有数据。然后在 resultMap 中做映 射。如果一对一的属性使用不是很频繁,可能偶尔用一下,这种情况下,我们 也可以启用懒加载。懒加载,就是先查询 book,查询 book 的过程中,不去查询 author,当用户 第一次调用了 book 中的 author 属性后,再去查询 author。
- 再提供一个方法
Book getBookById(Integer id);
Author getAuthorById(Integer id);
<resultMap id="BaseResultMap" type="org.javaboy.mybatis.model.Book">
<id column="id" property="id"/>
<result column="name" property="name"/>
</resultMap>
<resultMap id="BookWithAuthor2" type="org.javaboy.mybatis.model.Book" extends="BaseResultMap">
<association property="author" javaType="org.javaboy.mybatis.model.Author" select="org.javaboy.mybatis.mapper.BookMapper.getAuthorById" column="aid" fetchType="lazy"/>
</resultMap>
<select id="getBookById2" resultMap="BookWithAuthor2">
select * from book where id = #{id};
</select>
<select id="getAuthorById" resultType="org.javaboy.mybatis.model.Author">
select * from author where id = #{aid};
</select>
这里,定义 association 的时候,不直接指定映射的字段,而是指定要执行的 方法,通过 select 字段来指定,column 表示执行方法时传递的参数字段,最 后的 fetchType 表示开启懒加载。当然,要使用懒加载,还需在全局配置中开启:
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>