前提介紹
在mybatis如何進行多對一、一對多(一對一)的多表查詢呢?本章帶你認識如何非常順滑的解決!
基礎使用篇
一對一
association
association通常用來對映一對一的關係,例如,有個類user,對應的實體類如下:
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class Student {
private int id;
private String name;
/**
* 學生要關聯一個老師
*/
private Teacher teacher;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class Teacher {
private int id;
private String name;
}
Dao層進行Mapper查詢操作
public interface TeacherMapper {
Teacher getTeacher(@Param("tid") int id);
Teacher getTeacher2(@Param("tid") int id);
}
Dao層進行Mapper.xml檔案
<resultMap id="StudentTeacher" type="com.sunreal.pojo.Student">
<result column="id" property="id"></result>
<result column="name" property="name"></result>
<association property="teacher" column="id" javaType="com.sunreal.pojo.Teacher" select="getTeacher"/>
</resultMap>
<select id="getStudent" resultMap="StudentTeacher">
select *
from student
</select>
<select id="getTeacher" resultType="com.sunreal.pojo.Teacher">
select *
from teacher
where id = #{id}
</select>
<resultMap id="StudentTeacher2" type="com.sunreal.pojo.Student">
<result column="sid" property="id"></result>
<result column="sname" property="name"></result>
<association property="teacher" javaType="com.sunreal.pojo.Teacher">
<result property="name" column="tname"></result>
</association>
</resultMap>
<select id="getStudent2" resultMap="StudentTeacher2">
select s.id sid, s.name sname, t.name tname
from student s,
teacher t
where s.tid = t.id
</select>
- assocication:可以指定聯合的JavaBean物件
- select:指定相關查詢結果sqlid
- property="role“:指定哪個屬性是聯合的物件
- javaType:指定這個屬性物件的型別
- column="{javabean熟悉=資料庫欄位,Javabean屬性=資料庫欄位}"
<association property="role" javaType="com.queen.mybatis.bean.Role"> <id column="role_id" property="id"/> <result column="roleName" property="roleName"/> </association>
以上如果跨越名稱空間的情況下:select:需要用namespace.selectId進行指定。
collection
@Alias("Student")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class Student {
private int id;
private String name;
private int tid;
}
@Alias("Teacher")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class Teacher {
private int id;
private String name;
/**
* 一個老師包含多個學生
*/
private List<Student> studentList;
}
Dao層進行Mapper查詢操作
public interface TeacherMapper {
Teacher getTeacher(@Param("tid") int id);
Teacher getTeacher2(@Param("tid") int id);
}
Dao層進行Mapper.xml檔案
<resultMap id="TeacherStudent" type="Teacher">
<result property="id" column="tid"></result>
<result property="name" column="tname"></result>
<collection property="studentList" ofType="Student">
<result property="id" column="sid"></result>
<result property="name" column="sname"></result>
<result property="tid" column="tid"></result>
</collection>
</resultMap>
<select id="getTeacher" resultMap="TeacherStudent">
select s.id sid, s.name sname, t.name name, t.id tid
from student s,
teacher t
where s.tid = t.id
and t.id = #{tid}
</select>
<resultMap id="TeacherStudent2" type="Teacher">
<collection property="studentList" javaType="ArrayList" ofType="Student"
select="getStudentByTeacherId" column="id"/>
</resultMap>
<select id="getTeacher2" resultMap="TeacherStudent2">
select *
from teacher
where id = #{tid}
</select>
<select id="getStudentByTeacherId" resultType="Student">
select *
from student
where tid = #{tid}
</select>
注意:各個表之間儘量不要有重名欄位,包括主鍵id,不然可能會造成資料混亂錯誤;
- JavaType和ofType都是用來指定物件型別的
- property="指的是物件內部(List型別)的屬性資訊欄位名稱"
- JavaType是用來指定pojo中屬性的型別
- ofType指定的是對映到list集合屬性中pojo的型別。
- column="{javabean熟悉=資料庫欄位,Javabean屬性=資料庫欄位}"
- select:指定相關查詢結果sqlid
”特叔“使用篇
一對一對映
實體列 class Tb_blog/TbBlog
private long blogId;
private String blogTitle;
private String blogContent;
private Date createTime;
private String blogType;
private String sId;
private Tb_author author;
List<TbAuthor> tbAuthorList;
實體類 class TbAuthor
private long id;
private String username;
private String password;
private String email;
private String address;
private String phone;
private TbBlog tbBlog;
private List<TbBlog> tbBlogList;
resultMap標籤配置
<resultMap id="blogMap" type="Tb_blog" >
<id column="blogId" property="blogId"/>
<result column="blogTitle" property="blogTitle"/>
<result column="blogContent" property="blogContent"/>
<result column="blogType" property="blogType"/>
<result column="createTime" property="createTime"/>
<result column="sId" property="sId"/>
<result column="id" property="author.id"/> <!-- 對映第二張表的實體類屬性 -->
<result column="username" property="author.username"/>
<result column="password" property="author.password"/>
<result column="email" property="author.email"/>
</resultMap>
<select id="selectBlogAndAuthor" resultMap="blogMap">
select * from tb_blog g inner join tb_author r
on g.blogId = r.id
</select>
在sql加入別名alias與field屬性欄位一樣,也可以自動注入進入。
association標籤配置
<resultMap id="blogMap" type="Tb_blog" >
<id column="blogId" property="blogId"/>
<result column="blogTitle" property="blogTitle"/>
<result column="blogContent" property="blogContent"/>
<result column="blogType" property="blogType"/>
<result column="createTime" property="createTime"/>
<!-- 一對一高效率寫法 association一對一關聯 property屬性為實體類中的第二張表的屬性名 -->
<association property="tb_author" javaType="TbAuthor"><!--javaType屬性為 返回的實體類物件 -->
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="password" property="password"/>
<result column="email" property="email"/>
<result column="address" property="address"/>
</association>
</resultMap>
<select id="selectBlogAndAuthor" resultMap="blogMap">
select * from tb_blog g inner join tb_author r on g.blogId = r.id
</select>
collection標籤配置
mapper介面定義
AuthorMapper.interface
//!通過id 和對映檔案中 association的column屬性的值sId關聯 來巢狀查詢 巢狀查詢的第二條sql語句都要寫條件來關聯第一張表
List<TbAuthor> selectAuthorandBlogAssociation(int id);
BlogMapper.interface
List<TbBlog> selectBlogAndAuthorAssociation();
AuthorMapper.xml
<select id="selectAuthorandBlogAssociation" resultType="com.xqh.pojo.TbAuthor">
select * from tb_author where id=#{id}
</select>
<resultMap id="mapCollection" type="TbAuthor">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="password" column="password"/>
<result property="email" column="email"/>
<result property="phone" column="phone"/>
<result property="address" column="address"/>
<collection property="tbBlogList" column="id"
select="com.xqh.mapper.BlogMapper.selectBlogAndAuthor"
fetchType="lazy">
</collection>
</resultMap>
<select id="selectAuthor_BlogList" resultMap="mapCollection">
select * from tb_author
</select>
BlogMapper.xml
<select id="selectBlogAndAuthor" resultType="com.xqh.pojo.TbBlog">
select * from tb_blog where sId = #{id}
</select>
總結
多表查詢一對一對映
association標籤
不巢狀 property=當前實體類中的第二種表的屬性名 javaType=返回的實體類
巢狀 多加兩個屬性 column=當前實體類 關聯的 第二張表 的外來鍵欄位 select=“第二條查詢語句” (必須給第二條sql語句寫引數限制 不然會獲得所有值)
多表查詢一對多
collection標籤
不巢狀 property=當前實體類中的第二種表的屬性名 ofType=返回是實體類
property=當前實體類中的第二種表的屬性名 javaType=返回的實體類
巢狀 多加兩個屬性 column=當前實體類 關聯的 第二張表 的外來鍵欄位 select=“第二條查詢語句” (必須給第二條sql語句寫引數限制 不然會獲得所有值)
2.多表查詢一對多
collection標籤
不巢狀 property=當前實體類中的第二種表的屬性名 ofType=返回是實體類
巢狀 多加一個屬性 column=當前實體類 關聯的 第二張表 的外來鍵欄位 select=“第二條查詢語句” (必須給第二條sql語句寫引數限制 不然會獲得所有值) [ofType = collection一對多巢狀查詢 巢狀查詢所有結果 不需寫返回型別因為 select已經對映]