0
点赞
收藏
分享

微信扫一扫

Mybatis多表连接查询


Mybatis多表连接查询 需要借助<resultMap>标签

1.<resultMap>标签的使用

在MyBatis中, 查询标签有两个属性, resultType和resultMap. 都代表返回结果的类型. 区别在于:

  • resultType指定的一个类型, MyBatis会进行自动映射(Auto-Mapping). 列名和属性名一致则进行映射, 否则属性被赋值为null.
  • resultMap属性指定的是标签的id值. 表示MyBatis不进行自动映射, 需要程序员自己定义映射关系.

2.表格设计

# 选中数据库
use db_ssm;
# 创建班级表
create table tb_class (
id integer primary key auto_increment,
name varchar(10) not null,
room varchar(10)
);

# 创建学生表
create table tb_student (
id integer primary key auto_increment,
name varchar(20) not null,
gender char(1),
birthday date,
cid integer
);

# 建立约束
alter table tb_student add constraint fk_cid foreign key (cid) references tb_class (id);

# 添加数据
insert into tb_class values
(default, 'Java', '505'),
(default, 'UI', '510'),
(default, '大数据', '405');

insert into tb_student values
(default, '张无忌', '男', '1998-12-12', 1),
(default, '赵敏', '女', '1999-12-12', 2),
(default, '谢逊', '男', '1998-12-12', 2),
(default, '成昆', '男', '1998-12-12', 3),
(default, '周芷若', '女', '1998-12-12', 3),
(default, '小昭', '女', '1998-12-12', 3);

3.实体类创建

  • Clazz类, 班级表. 学生泛型的List集合, 表示班级下所有的学生信息.
  • Student类, 学生表. 班级对象, 表示学生所属的班级信息.
    如果需要toString方法, 注意不要出现无限递归的情况. 防止发生堆栈溢出异常.

4.多表连接查询的几种情况

  • 关联方式查询
    通过多表关联的SQL语法进行查询, 需要使用join, on, …来实现查询. 执行一条SQL语句就可以将所有需要的数据全部查询到. 我们需要做的就是将查到的数据进行映射即可.

<resultMap id="smap" type="student" autoMapping="true">
<!--关联单个对象要使用association-->
<association property="clazz" javaType="clazz" autoMapping="true">
<id column="cid" property="id" />
<result column="cname" property="name" />
</association>
</resultMap>

<select id="selAll" resultMap="smap">
select
s.*, c.name cname, c.room
from
tb_student s
left join
tb_class c
on
s.cid = c.id
</select>

  • N+1方式查询
    表示所有数据要获取到需要执行N+1条SQL语句. 每次查询都是单表查询, 查多次就拿到所有数据了.

<resultMap id="smap2" type="student">
<!--映射单个对象-->
<association
property="clazz"
javaType="clazz"
select="com.bjsxt.mapper.ClazzMapper.selById"
column="cid" />
</resultMap>
<select id="selAll2" resultMap="smap2">
select * from tb_student
</select>
<mapper namespace="com.bjsxt.mapper.ClazzMapper">
<select id="selById" resultType="clazz">
select * from tb_class where id=#{id}
</select>
</mapper>

b)一对多查询: 基于班级查学生, 使用标签<collection>

  • 关联查询

<resultMap id="cmap" type="clazz" autoMapping="true">
<!--关联集合对象, 使用collection标签-->
<collection property="students" javaType="list" ofType="student" autoMapping="true">
<id column="sid" property="id" />
<result column="sname" property="name" />
</collection>
</resultMap>

<select id="selAll" resultMap="cmap">
select
c.*, s.id sid, s.name sname, s.gender, s.birthday
from
tb_class c
left join
tb_student s
on
c.id = s.cid
</select>

  • N+1查询

<resultMap id="cmap2" type="clazz">
<!--如果这一列作为参数继续传递, 会导致自动映射失败-->
<id column="id" property="id" />
<collection
property="students"
javaType="list"
ofType="student"
select="com.bjsxt.mapper.StudentMapper.selByCid"
column="id" />
</resultMap>
<select id="selAll2" resultMap="cmap2">
select * from tb_class
</select>
<mapper namespace="com.bjsxt.mapper.StudentMapper">
<select id="selByCid" resultType="student">
select * from tb_student where cid=#{cid}
</select>
</mapper>

c)业务装配方式查询

  • sql语句是关联语法, 需要使用join…on…
  • 只需要执行1条SQL语句
  • 默认情况下, 不会自动映射, 可以通过设置autoMapping=true开启自动映射
  • SQL语句都是单表查询
  • 需要执行N+1次查询才能得到结果
  • 默认情况下, 就会自动映射.

注意:多表连接查询尽量开启懒加载 减少资源浪费

开启延迟加载的方式有两种

  • 1:全局配置

<?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>
<properties resource="jdbc.properties"/>
<settings>
<setting name="logImpl" value="LOG4J"/>
<!--开启延时加载-->
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="true"/>
</settings>
<typeAliases>
<package name="com.jdbc.pojo"/>
</typeAliases>
<environments default="development">

<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--<mapper resource="com/jdbc/mapper/StudentMapper.xml"/>-->
<package name="com.jdbc.mapper"></package>
</mappers>
</configuration>

  • 2.给某个方法单独配置 fetchType=“lazy”
    <collection property=“courses” ofType=“course” autoMapping=“true” fetchType=“lazy”>

<?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="com.jdbc.mapper.TeacherMapper">

<!--public List<Course> getCourseById(Integer id);-->
<resultMap id="myMap1" type="teacher">
<id column="tid" property="tid"/>
<result column="tname" property="tname"/>
<collection property="courses" ofType="course" autoMapping="true" fetchType="lazy">
</collection>

</resultMap>
<select id="getCourseById" resultMap="myMap1">
SELECT t.TId tid,t.Tname tname,c.CId cid,c.Cname cname
from teacher t LEFT JOIN course c on
t.tid = c.TId where t.TId =#{id}
</select>


<resultMap id="myStep" type="teacher" autoMapping="true">

<collection property="courses" select="com.jdbc.mapper.CourseMapper.getCourseById" column="tid" ofType="course">

</collection>
</resultMap>

<select id="getTeacherById" resultMap="myStep" >

select * from teacher where tid = #{id}
</select>


</mapper>

Mybatis多表连接查询_mysql


举报

相关推荐

0 条评论