ToB企服应用市场:ToB评测及商务社交产业平台
标题:
MyBatis(二)-CURD (ResultMap 一对一,一对多)
[打印本页]
作者:
怀念夏天
时间:
2022-9-16 17:19
标题:
MyBatis(二)-CURD (ResultMap 一对一,一对多)
1、insert 标签
1.1 获取SqlSessionFactory 对象的通用方法
方便后面分测试;
//获取SqlSessionFactory 对象的通用方法
public SqlSessionFactory getSqlSessionFactory() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
return new SqlSessionFactoryBuilder().build(inputStream);
}
复制代码
1.2 属性说明
属性名说明idnamespace指定接口中的
方法名
parameterType指定接口
方法入参类型
,可写可不写(
mybatis可用根据接口方法,自动推断类型
)useGeneratedKeyinsert标签的属性,告诉mybatis,执行插入操作,
需要返回自增的主键
keyColumn
自增主键的 字段名
(可以不写,一张表只用能有一个自增主键)keyPropert指定返回的自增主键值,交给
入参实体的哪个属性保存
注意:增删改操作,和select查询标签最大的区别是:返回
只有影响行数
,所有没有resultType属性,而
查询必须有resultType
;
1.3 SQL
<insert id="insertAnime" useGeneratedKeys="true" keyColumn="id" keyProperty="id" >
insert into `animes`(
`cid`,
`name`
)values(
#{cid},
#{name}
)
</insert>
复制代码
1.4 测试
注意:mybatis 默认对增删改操作,
事务
是
不自动提交
(自动提交是关闭的);
需要
开启自动提交
,
或这是手动提交
;
开启自动提交openSession(true);手动提交sqlSession.commit();
@Test
public void testMybatisMapperC() throws IOException {
//获取SqlSession对象
// SqlSession sqlSession = getSqlSessionFactory().openSession();
//方式2:创建SqlSession对象时,指定事务自动提交-true,默认false
SqlSession sqlSession = getSqlSessionFactory().openSession(true);
//获取mapper接口的代理实现对象
AnimeMapper animeMapper = sqlSession.getMapper(AnimeMapper.class);
System.out.println(animeMapper); //org.apache.ibatis.binding.MapperProxy@224edc67
//模拟从前端获取参数,封装请求实体
Anime animeForm = new Anime();
animeForm.setCid(1);
animeForm.setName("蜡笔小新");
//执行添加动漫
int row = animeMapper.insertAnime(animeForm);
//mybatis 默认对增删改操作,事务是不自动提交(自动提交是关闭的)
//方式1:手动提交
//sqlSession.commit();
System.out.println(String.format("----------执行添加动漫,影响行数:%d--------", row));
//获取自增主键
System.out.println(String.format("----------执行添加动漫,新增的自增id:%d--------", animeForm.getId()));
}
复制代码
2、update 标签
2.1 SQL
<update id="updateAnimeById">
update `animes` set
`cid` = #{cid},
`name` = #{name}
where `id` = #{id}
</update>
复制代码
2.2 测试
@Test
public void testMybatisMapperU() throws IOException {
SqlSession sqlSession = getSqlSessionFactory().openSession(true);
AnimeMapper animeMapper = sqlSession.getMapper(AnimeMapper.class);
//模拟从前端获取参数,封装请求实体
Anime animeForm = new Anime();
animeForm.setId(648);
animeForm.setCid(1);
animeForm.setName("蜡笔小新5");
//执行修改动漫
int row = animeMapper.updateAnimeById(animeForm);
System.out.println(String.format("----------执行修改动漫,影响行数:%d--------", row));
}
复制代码
3、delete 标签
3.1 SQL
<delete id="deleteAnimeById">
delete from `animes`
where `id` = #{animeId}
</delete>
复制代码
3.2 测试
@Test
public void testMybatisMapperD() throws IOException {
SqlSession sqlSession = getSqlSessionFactory().openSession(true);
AnimeMapper animeMapper = sqlSession.getMapper(AnimeMapper.class);
//模拟从前端获取参数,封装请求实体
Anime animeForm = new Anime();
animeForm.setId(648);
//执行删除动漫
int row = animeMapper.deleteAnimeById(animeForm.getId());
System.out.println(String.format("----------执行删除动漫,影响行数:%d--------", row));
}
复制代码
4、select 标签
4.1 属性说明
属性名说明id对应就是
namespace指定接口中的查询方法名
parameterType指定接口方法
入参类型
,
可写可不写
(建议不写)resultType指定接口返回的目标类型(
建议使用全类名
,也可以使用别名)
#{id}:这就告诉 MyBatis 创建一个预处理语句(PreparedStatement)参数,在 JDBC 中,这样的一个参数在 SQL 中会由一个“?”来标识,并被传递到一个新的预处理语句中;
如果接口
只有一个参数
,
参数名
,
可以随便写
,建议
跟形参
名保持
一致
;
4.2 一个参数
4.2.1 SQL
接口
只有一个参数
,参数名,可以随便写,
建议跟形参名保持一致;
<select id="selectAnimeById" resultType="com.kgc.mybatis.bean.Anime">
select `id`,
`cid`,
`name`
from `animes`
where `id` = #{animeId}
</select>
复制代码
4.2.2 测试
@Test
public void testMybatisMapperSelectParams1() throws IOException{
SqlSession sqlSession = getSqlSessionFactory().openSession();
AnimeMapper animeMapper = sqlSession.getMapper(AnimeMapper.class);
//调用mapper接口,根据动漫编号查询动漫信息
Anime anime = animeMapper.selectAnimeById(101);
System.out.println(String.format("1.一个参数 根据动漫编号:%d,查询动漫详情%s",anime.getId(),anime));
}
复制代码
4.3 两个参数
多个参数,
没有自定义参数别名时可以使用
形参名
内置参数 0,1,...
内置参数 param1,param2,...
自定义参数别名@Param("自定义参数名")时可以使用:
自定义参数名
内置参数 param1,param2,...
4.3.1 SQL
4.3.1.1
没有自定义参数
别名:
Anime selectAnimeByNameAndCid(String animeName,Integer animeId);
复制代码
<select id="selectAnimeByNameAndCid" resultType="com.kgc.mybatis.bean.Anime">
select `id`,
`cid`,
`name`
from `animes`
where `name` = #{animeName}
and `cid` = #{animeId}
</select>
复制代码
4.3.1.2
自定义参数别名
:
Anime selectAnimeByNameAndCid(@Param("animeName") String animeName,@Param("animeId") Integer animeId);
复制代码
Anime selectAnimeByNameAndCid(@Param("animeName") String animeName,@Param("animeId") Integer animeId);<select id="selectAnimeByNameAndCid" resultType="com.kgc.mybatis.bean.Anime">
select `id`,
`cid`,
`name`
from `animes`
where `name` = #{animeName}
and `cid` = #{animeId}
</select>
复制代码
自定义了参数名,如果使用#{0},#{1}会报错
Cause: org.apache.ibatis.binding.BindingException: Parameter '0' not found. Available parameters are [animeId, animeName, param1, param2]
4.3.2 测试
@Test
public void testMybatisMapperSelectParams2() throws IOException{
SqlSession sqlSession = getSqlSessionFactory().openSession();
AnimeMapper animeMapper = sqlSession.getMapper(AnimeMapper.class);
//通过动漫名称和分类编号查询动漫信息
Anime anime = animeMapper.selectAnimeByNameAndCid("完美世界",3);
System.out.println(String.format("2.两个参数 根据动漫编号:%d,查询动漫详情%s",anime.getId(),anime));
}
复制代码
4.4 实体参数
不自定义参数别名:
必须 只写 属性名
cid author
自定义参数别名:
使用
别名.属性名
使用
param1.属性名
4.4.1 SQL
4.4.1.1 不自定义参数别名
Anime selectAnimeByAnime(Anime animeForm);
复制代码
<select id="selectAnimeByAnime" resultType="com.kgc.mybatis.bean.Anime">
select `id`,
`cid`,
`name`
from `animes`
where `cid` = #{cid}
and `author` = #{author}
</select>
复制代码
4.4.1.2 自定义参数别名
Anime selectAnimeByAnime(@Param("animeForm") Anime animeForm);
复制代码
<select id="selectAnimeByAnime" resultType="com.kgc.mybatis.bean.Anime">
select `id`,
`cid`,
`name`
from `animes`
where `cid` = #{param1.cid}
and `author` = #{param1.author}
</select>
复制代码
4.4.2 测试
@Test
public void testMybatisMapperSelectParams3() throws IOException{
SqlSession sqlSession = getSqlSessionFactory().openSession();
AnimeMapper animeMapper = sqlSession.getMapper(AnimeMapper.class);
//通过动漫分类编号和作者查询动漫信息
Anime animeForm = new Anime();
animeForm.setCid(1);
animeForm.setAuthor("三少");
Anime anime = animeMapper.selectAnimeByAnime(animeForm);
System.out.println(String.format("3.实体参数 根据动漫编号:%d,查询动漫详情%s",anime.getId(),anime));
}
复制代码
4.5 Map集合参数
通过Map 的 **键值 **获取参数
4.5.1 SQL
<select id="selectAnimeByActorAndCid" resultType="com.kgc.mybatis.bean.Anime">
select `id`,
`cid`,
`name`
from `animes`
where `cid` = #{cid}
and `actor` = #{actor}
</select>
复制代码
4.5.2 测试
@Test
public void testMybatisMapperSelectParams4() throws IOException{
SqlSession sqlSession = getSqlSessionFactory().openSession();
AnimeMapper animeMapper = sqlSession.getMapper(AnimeMapper.class);
//通过动漫分类编号和主角查询动漫信息
Map<String,Object> queryMap = new HashMap<>();
queryMap.put("cid","2");
queryMap.put("actor","路飞");
Anime anime = animeMapper.selectAnimeByActorAndCid(queryMap);
System.out.println(String.format("4.集合参数 根据动漫编号:%d,查询动漫详情%s",anime.getId(),anime));
}
复制代码
4.6 #{} 和 ${} 的区别
#{}:
类似于PreparedStatement
可以获取
普通参数,自定义参数,实体参数,集合参数等;
底层使用的是
?占位符
,会进行
预编译处理
,可以
防止SQL注入问题,安全性高;
不可以进行表达式运算
;
${}:
类似于Statement
正常情况下,跟#{}获取参数的写法没有区别;
区别:
不能随意获取参数
,
不能
使用
内置参数
,
必须起别名;
底层是
字符串拼接
,不是占位符,
不安全
,当#{}解决不了,就必须使用${};
可以使用,动态表名,动态列名,表达式运算等
;
建议:MyBatis的SQL映射文件中,能
优先使用#{}
,就必须使用,
除非特殊情况,必须使用字符串拼接,才可以使用${};
4.6.1 SQL
使用动态表名查询动漫;
<select id="selectProduceAndCid" resultType="com.kgc.mybatis.bean.Anime">
select `id`,
`cid`,
`name`
from ${tableName}
where `produce` = #{produce}
and `cid` = #{cid}
</select>
复制代码
4.6.2 测试
@Test
public void testMybatisMapperSelectParams5() throws IOException{
SqlSession sqlSession = getSqlSessionFactory().openSession();
AnimeMapper animeMapper = sqlSession.getMapper(AnimeMapper.class);
Anime anime = animeMapper.selectProduceAndCid("腾讯动漫", 2, "animes");
System.out.println(String.format("4.集合参数 根据动漫编号:%d,查询动漫详情%s",anime.getId(),anime));
}
复制代码
4.7 查询多条数据
查询多条数据,
resultType 属性值还是实体类
;
resultType="com.kgc.mybatis.bean.Anime"
Mybatis会自己走
返回集合的方法
,
自动将数据放到集合中
;
//var1 select标签的id属性的值
<E> List<E> selectList(String var1);
//var2 为接口方法的参数
<E> List<E> selectList(String var1, Object var2);
//var3 为分页对象
<E> List<E> selectList(String var1, Object var2, RowBounds var3);
复制代码
4.7.1 SQL
<select id="selectAnimeListByCid" resultType="com.kgc.mybatis.bean.Anime">
select `id`,
`cid`,
`name`
from `animes`
where `cid` = #{cid}
</select>
复制代码
4.7.2 测试
@Test
public void testMyBatisMapperSelectResults() throws IOException {
SqlSession sqlSession = getSqlSessionFactory().openSession();
AnimeMapper animeMapper = sqlSession.getMapper(AnimeMapper.class);
//根据动漫分类编号查询动漫
List<Anime> animeList = animeMapper.selectAnimeListByCid(3);
for (Anime anime : animeList) {
System.out.println(anime);
}
}
复制代码
4.8 模糊查询
使用 #{} 建议使用
concat('%',#{name},'%');
使用 ${name}
必须给参数起别名
;
4.8.1 SQL
4.8.1.1 使用 #{name}
<select id="selectAnimeListByName" resultType="com.kgc.mybatis.bean.Anime">
select `id`,
`cid`,
`name`
from `animes`
where name like concat('%',#{name},'%')
</select>
复制代码
4.8.1.2 使用${name}
<select id="selectAnimeListByName" resultType="com.kgc.mybatis.bean.Anime">
select `id`,
`cid`,
`name`
from `animes`
where name like '%${name}%'
</select>
复制代码
使用${name} 如果不取别名, 取不到参数;
There is no getter for property named 'name' in 'class java.lang.String'
4.8.2 测试
@Test
public void testMyBatisMapperSelectResults2() throws IOException {
SqlSession sqlSession = getSqlSessionFactory().openSession();
AnimeMapper animeMapper = sqlSession.getMapper(AnimeMapper.class);
//根据动漫名称 模糊 查询动漫列表
List<Anime> animeList = animeMapper.selectAnimeListByName("魁");
for (Anime anime : animeList) {
System.out.println(anime);
}
}
复制代码
4.9 分页查询
方法一:
调用接口
的时候,
计算好分页起始行
,SQL中直接获取参数((pageNo - 1)*pageSize),实现分页;
方法二:使用
limit ${(pageNo - 1)*pageSize},#{pageSize}
(不建议使用)
方法三:使用select的子标签bind自定义属性,
4.9.1 SQL
<select id="selectAnimeListByProduce" resultType="com.kgc.mybatis.bean.Anime">
<bind name="pageIndex" value="((pageNo - 1)*pageSize)"/>
select `id`,
`cid`
from `animes`
where `produce` like concat('',#{produce},'%')
limit #{pageIndex},#{pageSize}
</select>
复制代码
4.9.2 测试
@Test
public void testSelectAnimeListByProduce() throws IOException {
SqlSession sqlSession = getSqlSessionFactory().openSession();
AnimeMapper animeMapper = sqlSession.getMapper(AnimeMapper.class);
//模拟获取分页参数
Integer pageNo = 1;
Integer pageSize = 3;
//调用mapper接口,模糊查询,查询分页列表
//方法一:调用接口的时候,计算好分页起始行,SQL中直接获取参数,实现分页
//方法二:使用 limit ${(pageNo - 1)*pageSize},#{pageSize}
//方法三:使用select的子标签bind,<bind name="pageIndex" value="((pageNo - 1)*pageSize)"/>
List<Anime> animeList = animeMapper.selectAnimeListByProduce("爱奇艺",pageNo,pageSize);
animeList.forEach(System.out::println);
}
复制代码
4.10 返回Map集合
4.10.1 列名作为key,数值作为value
以动漫详情为例模拟返回map集合,将
列名作为key
,
数值作为value
;
实际开发中,查询结果集,是单条记录,且没有实体对应,比如:数据统计,只有统计结果,没有统计实体;
5.10.1.1 SQL
Map,方法的返回类型是Map,key是String类型,value是Object类型,因为每个字段
有不同的类型
;
resultType="java.util.HashMap",因为将数据映射到map中;
<select id="selectAnimeMapById" resultType="java.util.HashMap">
select `id`,
`cid`,
`name`
from `animes`
where `id` = #{id}
</select>
复制代码
4.10.1.1 测试
@Test
public void testSelectAnimeByMapById() throws IOException {
SqlSession sqlSession = getSqlSessionFactory().openSession();
AnimeMapper animeMapper = sqlSession.getMapper(AnimeMapper.class);
Map<String, Object> animeMap = animeMapper.selectAnimeMapById(301);
System.out.println(animeMap);
Object actor = animeMap.get("actor");
System.out.println("actor==>"+actor);
}
复制代码
4.10.2主键key,实体为value
以动漫详情为例模拟返回map集合,将数据
主键列值作为key
,
整条数据作为value
;
实际开发中返回多条记录,并需要根据key,快速遍历,比如分组查询;
4.10.2.1 SQL
因为它不知道你要将哪个属性作为map的key值,所以需要
@MapKey("id")
,
指定一个实体的属性作为map的key值;
//以动漫详情为例模拟返回map集合,将数据主键列值作为key,整条数据作为value
@MapKey("id") //这里的MapKey 是实体的一个属性
Map<Integer,Anime> selectAnimeMapByCid(Integer cid);
复制代码
resultType="com.kgc.mybatis.bean.Anime",虽然返回的结果是map,但是数据是映射到Anime动漫实体中;
<select id="selectAnimeListByCid" resultType="com.kgc.mybatis.bean.Anime">
select `id`,
`cid`,
`name`
from `animes`
where `cid` = #{cid}
</select>
复制代码
4.10.2.2 测试
@Test
public void testSelectAnimeMapByCid() throws IOException {
SqlSession sqlSession = getSqlSessionFactory().openSession();
AnimeMapper animeMapper = sqlSession.getMapper(AnimeMapper.class);
Map<Integer, Anime> animeMap = animeMapper.selectAnimeMapByCid(3);
System.out.println(animeMap);
Anime anime = animeMap.get(301);
System.out.println(anime);
}
复制代码
5、ResultMap 结果集映射
5.1 列名 和 属性名 不匹配
可以
取别名
,查询出来的列名,取别名,
跟实体的属性名一致
;
自定义
resultMap映射
;
5.1.1 SQL
resultMap的参数说明idresultMap唯一idtype返回值类型autoMapping是否开启自动映射resultMap自定义标签内
指定的列才会映射
,如果查询的结果列,
不在自定义映射标签中
,但是
满足自动映射的条件
(列名和实体属性名一致),
仍然会自动映射
;
除非指定resultMap标签的
autoMapping
属性为
false
(
autoMapping="false"
),没有自定义映射的其他字段
才不会自动映射
;
<select id="selectAnimeByResultMap" resultMap="animeResultMap">
select `id`,
`cid`,
`name`,
`author`,
`actor`,
`produce`,
`create_date` `crateTime`
from `animes`
where `id` = #{id}
</select>
<resultMap id="animeResultMap" type="com.kgc.mybatis.bean.Anime" autoMapping="false">
<id column="id" property="id"></id>
<result column="cid" property="cid"></result>
<result column="name" property="name"></result>
<result column="crateTime" property="createDate"></result>
</resultMap>
复制代码
5.1.2 测试
@Test
public void testSelectAnimeByResultMap() throws IOException {
SqlSession sqlSession = getSqlSessionFactory().openSession();
AnimeMapper animeMapper = sqlSession.getMapper(AnimeMapper.class);
//使用自定义映射,查询动漫详情,解决列名和属性名不同意的映射
Anime anime = animeMapper.selectAnimeByResultMap(301);
System.out.println(anime);
}
复制代码
5.2 级联映射
实体属性,级联映射;
5.2.1 一对一
级联映射只适合一对一;
要求:查询
动漫Anime
,并且查询出动漫的
实体属性category 的信息
;
一个动漫
对
一个动漫分类
;
5.2.1.1 实体
动漫实体Anime
public class Anime {
//动漫编号
private Integer id;
//分类编号
private Integer cid;
//名称
private String name;
......
//分类详情实体,一对一 (也可以定义分类名称冗余到实体中也可以解决)
private Category category;
}
复制代码
分类实体Category
public class Category {
//分类编号
private Integer id;
//分类名称
private String name;
}
复制代码
5.2.1.2 SQL
[/code][table][tr]参数说明[/tr][tr][td]column="cid"[/td][td]连表查询出来的字段[/td][/tr][tr][td]property="category.id"[/td][td]实体属性 的属性[/td][/tr][/table]先通过[b]连表查询[/b],将动漫信息和分类信息查询出来,[b]再根据字段[/b],[b]一 一 映射[/b];
[code]<resultMap id="animeResultMapCascade" type="com.kgc.mybatis.bean.Anime" >
<id column="id" property="id"></id>
<result column="cid" property="cid"></result>
<result column="name" property="name"></result>
<result column="author" property="author"></result>
<result column="create_date" property="createDate"></result>
<result column="cid" property="category.id"></result>
<result column="cname" property="category.name"></result>
</resultMap>
复制代码
5.2.1.3 测试
@Test
public void testSelectAnimeByResultMapCascade() throws IOException {
SqlSession sqlSession = getSqlSessionFactory().openSession();
AnimeMapper animeMapper = sqlSession.getMapper(AnimeMapper.class);
//级联映射,动漫实体内部,分类实体属性的 级联映射
Anime anime = animeMapper.selectAnimeByResultMapCascade(301);
System.out.println(anime);
//Anime(id=301,
// cid=3,
// name=完美世界,
// ......
// category=Category(id=3, name=科幻)
// )
}
复制代码
5.3 关联映射 (高级映射)
实体属性,关联映射;
5.3.1 association 一对一
要求:查询
动漫Anime
,并且查询出动漫的
实体属性category 的信息
;
一个动漫
对
一个动漫分类
;
5.3.1 实体
动漫实体Anime
public class Anime {
//动漫编号
private Integer id;
//分类编号
private Integer cid;
//名称
private String name;
......
//分类详情实体,一对一
private Category category;
}
复制代码
分类实体Category
public class Category {
//分类编号
private Integer id;
//分类名称
private String name;
}
复制代码
5.3.2 SQL
先通过连表查询,查询出动漫信息,和动漫分类信息;
再通过
association标签
,对动漫的
实体属性 category 进行赋值
;
select a.`id`, a.`cid`, a.`name`, a.`author`, a.`actor`, a.`produce`, a.`create_date`, c.`name` 'cname' from `animes` a,`category` c where a.`cid` = c.`id` and a.`id` = #{id}<resultMap id="animeResultMapCascade" type="com.kgc.mybatis.bean.Anime" >
<id column="id" property="id"></id>
<result column="cid" property="cid"></result>
<result column="name" property="name"></result>
<result column="author" property="author"></result>
<result column="create_date" property="createDate"></result>
<result column="cid" property="category.id"></result>
<result column="cname" property="category.name"></result>
</resultMap>
复制代码
5.3.3 测试
@Test
public void testSelectAnimeByResultMapAssociation() throws IOException {
SqlSession sqlSession = getSqlSessionFactory().openSession();
AnimeMapper animeMapper = sqlSession.getMapper(AnimeMapper.class);
Anime anime = animeMapper.selectAnimeByResultMapAssociation(301);
System.out.println(anime);
//Anime(id=301,
// cid=3,
// name=完美世界,
// ......
// category=Category(id=3, name=科幻)
// )
}
复制代码
5.3.2 collection 一对多
要求:查询
分类Category
,并且查询出分类下的
动漫集合属性 animes 信息
;
一个动漫分类
对
多个动漫
;
5.3.1 实体
分类实体Category
public class Category {
//分类编号
private Integer id;
//分类名称
private String name;
//当前 分类下的 动漫集合
private List<Anime> animes;
}
复制代码
动漫实体Anime
public class Anime {
//动漫编号
private Integer id;
//分类编号
private Integer cid;
//名称
private String name;
......
}
复制代码
5.3.2 SQL
先通过连表查询,查询出动漫分类信息,和动漫信息;
再通过
collection标签
,对动漫分类的
集合属性 animes 进行赋值
;
select c.`id`, c.`name`, a.`id` 'aid', a.`cid`, a.`name` 'aname', a.`author`, a.`actor`, a.`create_date`, a.`produce` from `category` c,`animes` a where c.`id` = a.`cid` and c.`id` = #{id}<resultMap id="animeResultMapCascade" type="com.kgc.mybatis.bean.Anime" >
<id column="id" property="id"></id>
<result column="cid" property="cid"></result>
<result column="name" property="name"></result>
<result column="author" property="author"></result>
<result column="create_date" property="createDate"></result>
<result column="cid" property="category.id"></result>
<result column="cname" property="category.name"></result>
</resultMap>
复制代码
5.3.3 测试
@Test
public void testSelectCategoryByResultMapCollection() throws IOException {
SqlSession sqlSession = getSqlSessionFactory().openSession();
CategoryMapper categoryMapper = sqlSession.getMapper(CategoryMapper.class);
//查询动漫分类详情,内部集合类型 映射
Category category = categoryMapper.selectCategoryByResultMapCollection(3);
System.out.println(category);
//Category(id=3,
// name=科幻,
// animes=[Anime(id=301, cid=3, name=完美世界, ...),
// Anime(id=649, cid=3, name=蜡笔小新, ...)
// ]
// )
}
复制代码
5.4 嵌套select, 延迟加载 和 分步查询
开启延迟加载,
默认false,需要支持延迟
,改为true;
按需加载
,是否全部加载,
(前提必须是言辞加载是打开的,而且是
自定义映射,配合高级嵌套select查询)
;
在
3.4.1及之前的版本中默认为true,
全部加载(任意一方法的调用都会加载该对象的所有延迟加载属性);
只有改为false,才会分步加载
,需要调用该方法时,才进行 延迟加载属性;
5.4.1 association 一对一
要求:查询
动漫Anime
,并且查询出动漫的
实体属性category 的信息
;
一个动漫
对
一个动漫分类
;
5.4.1.1 实体
跟 关联映射 association 一对一 的实体一样;
5.4.1.2 SQL
[/code][table][tr]参数说明[/tr][tr][td]property[/td][td]实体的属性[/td][/tr][tr][td]select[/td][td]指定嵌套的select语句的唯一标识[/td][/tr][tr][td]column[/td][td]指定嵌套的sleect语句执行需要的参数,多参数JSON格式{key1=col1,key2=col2}[/td][/tr][tr][td]fetchType[/td][td]是否适配系统延迟加载,默认是lazy,如果需要局部关闭延迟加载,改为eager[/td][/tr][/table]先通过[b]id查询动漫Anime[/b],再通过动漫的[b]cid,去查询 动漫分类[/b];
AnimeMapper.xml
[code]<select id="selectAnimeByResultMap" resultMap="animeResultMap">
select `id`,
`cid`,
`name`,
`author`,
`actor`,
`produce`,
`create_date` `crateTime`
from `animes`
where `id` = #{id}
</select>
<resultMap id="animeResultMap" type="com.kgc.mybatis.bean.Anime" autoMapping="false">
<id column="id" property="id"></id>
<result column="cid" property="cid"></result>
<result column="name" property="name"></result>
<result column="crateTime" property="createDate"></result>
</resultMap>
复制代码
CategoryMapper.xml
<select id="selectCategoryById" resultType="com.kgc.mybatis.bean.Category">
select `id`,
`name`
from `category`
where `id`= #{id}
</select>
复制代码
5.4.1.3 测试
@Test
public void testSelectAnimeByResultMapAssociationLazyLoadingStep() throws IOException {
SqlSession sqlSession = getSqlSessionFactory().openSession();
AnimeMapper animeMapper = sqlSession.getMapper(AnimeMapper.class);
//高级映射,内部实体一对一 ,使用嵌套select 延迟加载和分布查询
Anime anime = animeMapper.selectAnimeByResultMapAssociationLazyLoadingStep(301);
System.out.println("如果只使用动漫的信息,不使用加载 动漫分类的SQL");
System.out.println(anime.getName());
System.out.println("=============================================");
System.out.println("动漫的分类名称:"+anime.getCategory().getName());
}
复制代码
开启延迟加载和按需加载
关闭延迟加载和按需加载,或者局部关闭延迟加载
5.4.2 collection 一对多
要求:查询
分类Category
,并且查询出分类下的
动漫集合属性 animes 信息
;
一个动漫分类
对
多个动漫
;
5.4.2.1 实体
跟 关联映射 collection 一对多 的实体一样;
5.4.2.2 SQL
先通过
id查询分类Category
,再通过动漫的
id,去查询cid等于id的动漫
;
CategoryMapper.xml
<select id="selectCategoryById" resultType="com.kgc.mybatis.bean.Category">
select `id`,
`name`
from `category`
where `id`= #{id}
</select>
复制代码
AnimeMapper.xml
<select id="selectAnimeMapByCid" resultType="com.kgc.mybatis.bean.Anime">
select `id`,
`cid`,
`name`,
`author`,
`actor`,
`produce`,
`create_date`
from `animes`
where `cid` = #{cid}
</select>
复制代码
5.4.2.3 测试
@Test
public void testSelectCategoryByResultMapCollectionAssociationLazyLoadingStep() throws IOException {
SqlSession sqlSession = getSqlSessionFactory().openSession();
CategoryMapper categoryMapper = sqlSession.getMapper(CategoryMapper.class);
Category category = categoryMapper.selectCategoryByResultMapCollectionAssociationLazyLoadingStep(1);
System.out.println("分类名称:"+category.getName());
System.out.println("=============================================");
System.out.println("该分类下的动漫:"+category.getAnimes());
}
复制代码
开启延迟加载和按需加载
关闭延迟加载和按需加载,或者局部关闭延迟加载
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4