Mybatis实现多表联查
一、Mybatis实现多表联查询
1、Mybatis实现多表联查询方式
- 业务装配对两个表写单独的sql语句,在业务(service)把查询结果进行联合。
- 使用Auto Mapping特性,在实现两个表联合查询时通过别名完成自动映射。
-
使用Mybatis的<resultMap>标签进行实现
2、多表查询时类中包含另一个对象的分类
- 单个对象
- 集合对象
二、resultMap标签
1、<resultMap>标签单表中的映射
写在<select>标签中,不用谢resultType属性,可以单独的在<resultMap>中将数据库字段与java属性不匹配进行映射。
2、使用<resultMap>标签在两个表中关联单个对象(N+1方式)
- N+1查询的方式,先查询出一个表的全部信息,根据这个表的信息查询另一个表的信息。
- 实现步骤在Student类中包含一个Teacher对象
- 在StudentMapper.xml文件中写上查询学生的sql,然后通过<resultMap>来完成Teacher对象的查询
具体代码:
java实体类:
-
public
class
Student {
-
private
int id;
-
private String name;
-
private
int age;
-
private
int tid;
-
private Teacher teacher;
TeacherMapper.xml文件中提供一个查询老师对象的sql:
-
<mapper namespace="com.test.mapper.TeacherMapper">
-
<select id="selById" parameterType="int" resultType="Teacher">
-
select * from teacher where id =#{0}
-
</select>
-
</mapper>
在StudentMapper.xml中写上查询学生信息:
-
<mapper namespace="com.test.mapper.StudentMapper">
-
<resultMap type="Student" id="stuMap">
-
<id column="id" property="id"/>
-
<result column="name" property="name"/>
-
<result column="age" property="age"/>
-
<result column="tid" property="tid"/>
-
<association property="teacher" select="com.test.mapper.TeacherMapper.selById"
-
column=
"tid">
</association>
-
</resultMap>
-
<select id="selAll" resultMap="stuMap" >
-
select * from student
-
</select>
-
</mapper>
几个属性标签说明:
- <id> 主键
- <result> 其它字段
- <association>装配对象时使用,其中 property 表示类中的属性名 select 表示要执行的sql语句(写完整的sql语句) column 要传过去的字段参数
解释:(N+1指的是每个学生类中有一个老师对象,因此一条sql查询出所有的学生,然后在查每个学生中的老师,即N+1).看日志信息:
补充说明:当其它字段一样时,可以在<resultMap>中不用写,但对于要传递的参数字段mybatia只装配一次因此要写
3、使用<resultMap>实现关联单个对象(联合查询方式)
只需要写一条SQL,在StudentMapper.xml中完成,对于学生属性直接用<id>或<result>进行装配(将字段别名与属性匹配),对于Teacher对象直接用<association>标签来映射,其中 property还是代表在类中该对象属性的名称 另外要设置javaType表示返回值类型,其它的还一次对应匹配即可。具体代码实例:
-
<!-- 在mapper中实现联合查询 -->
-
<resultMap type="Student" id="stuMap1">
-
<id column="sid" property="id"/>
-
<result column="sname" property="name"/>
-
<result column="sage" property="age"/>
-
<result column="tid" property="tid"/>
-
<association property="teacher" javaType="teacher">
-
<id column="tid" property="id"/>
-
<result column="tname" property="name"/>
-
</association>
-
</resultMap>
-
-
<select id="selAll1" resultMap="stuMap1">
-
select s.id sid,s.name sname,s.age sage,t.id tid,t.name tname
-
from student s left join teacher t on s.tid = t.id;
-
</select>
4、使用<resultMap>查询关联集合对象(N+1)
- 在实体类Teacher中加上含有多个Student的属性list,代码:
-
public
class
Teacher {
-
private
int id;
-
private String name;
-
private List<Student> list;
- 在StudentMapper.xml中添加通过tid查询学生的sql语句,代码:
-
<mapper namespace="com.test.mapper.StudentMapper">
-
<select id="selByTid" resultType="student" parameterType="int" >
-
select * from student where tid = #{0}
-
</select>
-
</mapper>
- 在TeacherMapper.xml中添加查询全部,然后通过<resultMap>来装配其它的,代码:
-
<mapper namespace="com.test.mapper.TeacherMapper">
-
<resultMap type="Teacher" id="teacMap">
-
<id column="id" property="id"/>
-
<result column="name" property="name"/>
-
<collection property="list" select="com.test.mapper.StudentMapper.selByTid" column="id"/>
-
</resultMap>
-
<select id="selAll" resultMap="teacMap">
-
select * from teacher
-
</select>
-
</mapper>
还是和查询单个对象一样这里<resultMap>中使用<collection>来匹配集合,其中property还是类中的属性名,select是要执行的sql语句,column为要传递的参数字段。
5、使用<resultMap>实现加载集合数据(联合查询方式)
只需要写一条SQL,在TeacherMapper.xml中完成,对于老师的属性在<resultMap>中直接用<id>或<result>进行装配(将字段别名与属性匹配),对于Student对象集合用<collection>标签来映射,其中 property还是代表在类中该对象集合属性的名称 另外要设置ofType表示返回集合的泛型,其它的还一次对应匹配即可。具体代码实例:
-
<!-- 使用联合查询 -->
-
<resultMap type="Teacher" id="teacMap1">
-
<id column="tid" property="id"/>
-
<result column="tname" property="name"/>
-
<collection property="list" ofType="Student">
-
<id column="sid" property="id"/>
-
<result column="sname" property="name"/>
-
<result column="age" property="age"/>
-
<result column="tid1" property="tid"/>
-
</collection>
-
</resultMap>
-
<select id="selAll1" resultMap="teacMap1">
-
select t.id tid, t.name tname, s.id sid, s.name sname,age ,s.tid tid1
-
from teacher t left join student s on t.id = s.tid
-
</select>
三、使用Auto Mapping结合别名实现多表查询
- 只能使用多表联合查询方式.
- 要求:查询出的列别和属性名相同.
- 实现方式,在 SQL 是关键字符,两侧添加反单引号
- 只能适用于单个对象
代码实例:
-
<select id="selAll" resultType="student">
-
select t.id `teacher.id`,t.name `teacher.name`,s.id id,s.name name,age,tid
-
from student s LEFT JOIN teacher t on t.id=s.tid
-
</select>
四、Mybatis注解
- 注解:为了简化配置文件.
- Mybatis 的注解简化 mapper.xml 文件.
- 如果涉及动态 SQL 依然使用 mapper.xml
- mapper.xml 和注解可以共存.
- 使用注解时 mybatis.xml 中<mappers>使用
- <package/>或 <mapper class=””/>
一般实例:
- 实现查询:
-
@Select("select * from teacher")
-
List<Teacher>
selAll
();
- 实现新增
-
@Insert("insert into teacher values(default,#{name})")
-
int
insTeacher
(Teacher teacher);
将主键带回来的方式:设置@Options注解并配置(useGeneratedKeys=true,keyProperty="id")
-
@Insert("insert into log values(default,#{accOut},#{accIn},#{money})")
-
@Options(useGeneratedKeys=true,keyProperty="id")
-
int
insLog
(Log log);
- 实现删除(主要看基本类型参数的取法)
-
@Delete("delete from teacher where id=#{0}")
-
int
delById
(int id);