查詢的幾種情況
// 1)查詢單行數據返回單個對象
public Employee getEmployeeById(Integer id );
// 2) 查詢多行數據返回對象的集合
public List<Employee> getAllEmps();
// 3) 查詢單行數據返回Map集合
public Map<String,Object> getEmployeeByIdReturnMap(Integer id );
// 4) 查詢多行數據返回Map集合
@MapKey("id") // 指定使用對象的哪個屬性來充當map的key
public Map<Integer,Employee> getAllEmpsReturnMap();
<!--
查詢單行數據返回Map集合
public Map<String, Object> getEmployeeByIdReturnMap(Integer id );
-->
<select id="getEmployeeByIdReturnMap" resultType="java.util.HashMap">
select id ,last_name,email,gender from tbl_employee where id = #{id}
</select>
<!--
查詢多行數據返回Map集合
@MapKey("id") // 指定使用對象的哪個屬性來充當map的key
public Map<Integer,Employee> getAllEmpsReturnMap();
-->
<select id="getEmpsReturnMap" resultType="com.atguigu.mybatis.beans.Employee">
select id ,last_name,email,gender from tbl_employee
</select>
自動映射類型取決於將數據存儲成什么類型,上面的例子雖然最終是多條數據封裝成map,但每一條數據的存儲類型是Employ對象,所以resultType定義成Employ對象
-
Select
標簽來定義查詢操作。 -
Id
:唯一標識符。用來引用這條語句,需要和接口的方法名一致
-
parameterType
:參數類型。
可以不傳,MyBatis會根據TypeHandler自動推斷 -
resultType
:返回值類型。
別名或者全類名,如果返回的是集合,定義集合中元素的類型。不能和resultMap
同時使用
結果集的封裝方式(重點)
resultType 自動映射(適合單表查詢)
autoMappingBehavior
默認是PARTIAL
,表示開啟自動映射的功能。唯一的要求是列名和JavaBean屬性名一致- 如果
autoMappingBehavior
設置為null則會取消自動映射 - 數據庫字段符合命名規范,POJO屬性符合駝峰命名法,如A_COLUMN與aColumn,我們可以開啟自動駝峰命名規則映射功能,
mapUnderscoreToCamelCase=true
不再舉例,上面的例子都是自動映射方式
resultMap自定義映射(多表查詢)
-
constructor
- 類在實例化時, 用來注入結果到構造方法中- idArg - ID 參數; 標記結果作為 ID 可以幫助提高整體效能
- arg - 注入到構造方法的一個普通結果
-
id
– 一個 ID 結果; 標記結果作為 ID 可以幫助提高整體效能 -
result
– 注入到字段或 JavaBean 屬性的普通結果 -
association
– 一個復雜的類型關聯;許多結果將包成這種類型- 嵌入結果映射 – 結果映射自身的關聯,或者參考一個
-
collection
– 復雜類型的集- 嵌入結果映射 – 結果映射自身的集,或者參考一個
-
discriminator
– 使用結果值來決定使用哪個結果映射case – 基於某些值的結果映射
嵌入結果映射 – 這種情形結果也映射它本身,因此可以包含很多相同的元素,或者它可以參照一個外部的結果映射。
public class Employee {
private Integer id ;
private String lastName;
private String email ;
private Integer gender ;
//聯合部門對象屬性
private Department dept ;
}
/* 自定義映射
type: 最終結果集封裝的類型
<id>: 完成主鍵列的映射
column: 數據庫字段列名
property:對象的屬性名
<result>:完成普通列的映射
*/
/*
需求: 查詢員工對象, 並且查詢員工所在 的部門信息.
*/
<select id="getEmpAndDept" resultMap="myEmpAndDept">
SELECT e.id eid , e.last_name, e.email,e.gender , d.id did , d.dept_name
FROM tbl_employee e , tbl_dept d
WHERE e.d_id = d.id AND e.id = #{id}
</select>
/*
eid last_name email gender did dept_name
1005 瑪利亞老師 mly@sina.com 0 4 人事部
*/
<resultMap type="com.atguigu.mybatis.beans.Employee" id="myEmpAndDept">
<id column="eid" property="id"/>
<result column="last_name" property="lastName"/>
<result column="email" property="email"/>
<result column="gender" property="gender"/>
/* 級聯
<result column="did" property="dept.id"/>
<result column="dept_name" property="dept.departmentName"/>
*/
/*
association: 完成關聯、聯合屬性的映射
property: 聯合屬性名
javaType: 聯合屬性的類型
*/
<association property="dept" javaType="com.atguigu.mybatis.beans.Department">
<id column="did" property="id" />
<result column="dept_name" property="departmentName"/>
</association>
</resultMap>
分步查詢
實際的開發中,對於每個實體類都應該有具體的增刪改查方法,也就是DAO層, 因此對於查詢員工信息並且將對應的部門信息也查詢出來的需求,就可以通過分步的方式
① 先通過員工的id查詢員工信息
② 再通過查詢出來的員工信息中的外鍵(部門id)查詢對應的部門信息.
/*
association 使用分步查詢:
需求: 查詢員工信息並且查詢員工所在的部門信息.
1. 先根據員工的id查詢員工信息
2. 使用外鍵 d_id查詢部門信息
*/
<!-- public Employee getEmpAndDeptStep(Integer id ); -->
<select id="getEmpAndDeptStep" resultMap="myEmpAndDeptStep">
select id, last_name, email,gender ,d_id from tbl_employee where id = #{id}
</select>
<resultMap type="com.atguigu.mybatis.beans.Employee" id="myEmpAndDeptStep">
<id column="id" property="id"/>
<result column="last_name" property="lastName"/>
<result column="email" property="email"/>
<result column="gender" property="gender"/>
//分步查詢
<association property="dept"
select="com.atguigu.mybatis.dao.DepartmentMapperResultMap.getDeptById"
column="{did=d_id}" fetchType="eager">
</association>
</resultMap>
分步查詢多列值的傳遞
如果分步查詢時,需要傳遞給調用的查詢中多個參數,則需要將多個參數封裝成Map來進行傳遞,語法如下: {k1=v1, k2=v2....}
在所調用的查詢方發中,取值時就要參考Map的取值方式,需要嚴格的按照封裝map時所用的key來取值.
association 或 collection的 fetchType屬性
1)在association和collection標簽中都可以設置fetchType,指定本次查詢是否要使用延遲加載。默認為 fetchType=”lazy” ,如果本次的查詢不想使用延遲加載,則可設置為fetchType=”eager”.
2)fetchType可以靈活的設置查詢是否需要使用延遲加載,而不需要因為某個查詢不想使用延遲加載將全局的延遲加載設置關閉.
collection
POJO中的屬性可能會是一個集合對象,我們可以使用聯合查詢,並以級聯屬性的方式封裝對象。使用collection標簽定義對象的封裝規則
public class Department {
private Integer id ;
private String departmentName ;
private List<Employee> emps ;
}
<select id="getDeptAndEmpsById" resultMap="myDeptAndEmps">
SELECT d.id did, d.dept_name ,e.id eid ,e.last_name ,e.email,e.gender
FROM tbl_dept d LEFT OUTER JOIN tbl_employee e ON d.id = e.d_id
WHERE d.id = #{id}
</select>
<resultMap type="com.atguigu.mybatis.beans.Department" id="myDeptAndEmps">
<id column="did" property="id"/>
<result column="dept_name" property="departmentName"/>
/*
property: 關聯的屬性名
ofType: 集合中元素的類型
*/
<collection property="emps" ofType="com.atguigu.mybatis.beans.Employee">
<id column="eid" property="id"/>
<result column="last_name" property="lastName"/>
<result column="email" property="email"/>
<result column="gender" property="gender"/>
</collection>
</resultMap>
collection分布查詢
實際的開發中,對於每個實體類都應該有具體的增刪改查方法,也就是DAO層, 因此
對於查詢部門信息並且將對應的所有的員工信息也查詢出來的需求,就可以通過分步的方式完成查詢。
① 先通過部門的id查詢部門信息
② 再通過部門id作為員工的外鍵查詢對應的部門信息.
<select id="getDeptAndEmpsByIdStep" resultMap="myDeptAndEmpsStep">
select id ,dept_name from tbl_dept where id = #{id}
</select>
<resultMap type="com.atguigu.mybatis.beans.Department" id="myDeptAndEmpsStep">
<id column="id" property="id"/>
<result column="dept_name" property="departmentName"/>
<collection property="emps"
select="com.atguigu.mybatis.dao.EmployeeMapper.getEmpsByDid"
column="id">
</collection>
</resultMap>