spring和Mybatis的各種查詢

ning12發表於2024-06-09

目錄
  • 、MyBatis的各種查詢功能
    • 6.1、查詢一個實體類的物件
    • 6.2、查詢一個list集合
    • 6.3、查詢單個資料
    • 6.4、查詢一條資料為Map集合
    • 6.5、查詢多條資料為Map集合
  • 七、特殊SQL的執行
    • 7.1、模糊查詢
    • 7.2、批次刪除
    • 7.3、動態設定表名
    • 7.4、新增功能獲取自增的主鍵
  • 八、自定義對映resultMap 一對一、多對一、一對多、多對多
    • 8.1、resultMap處理欄位和屬性的對映關係
    • 8.2、一對一對映處理
    • 8.3、多對一對映處理
    • 8.4、一對多對映處理 部門 -->員工
    • 8.5、多對多對映關係

、MyBatis的各種查詢功能

6.1、查詢一個實體類的物件

6.2、查詢一個list集合

  • 當查詢的資料為多條記錄時,不能使用實體類作為返回值,否則會丟擲異常:TooManyResultsException,但是如果查詢的資料只有一條,可以使用實體類或集合作為返回值

6.3、查詢單個資料

6.4、查詢一條資料為Map集合

6.5、查詢多條資料為Map集合

  1. 方式一

    • 將表中的資料以map集合的方式查詢,一條資料對應一個map;如果有多條資料,就會產生多個map集合,此時可以將這些map放在一個list集合中獲取
  2. 方式二

    • 如果有多條資料,可以將每條資料轉換的map集合放在一個大的map集合中,但是必須要透過@MapKey註解來完成。將查詢的某個欄位的值作為大的Map集合的鍵(key)

七、特殊SQL的執行

7.1、模糊查詢

    <select id="方法名" resultType="返回值型別">
        SELECT *
        from user
        where username like "%"#{name}"%"
    </select>

7.2、批次刪除

    <delete id="deleteAll">
        delete
        from user
        where id in #{ids}
    </delete>

7.3、動態設定表名

    <select id="getUserList" resultType="object">
        SELECT *
        from ${tableName}
    </select>

7.4、新增功能獲取自增的主鍵

    <insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO user (username, password)
        VALUES (#{username}, #{password})
    </insert>

八、自定義對映resultMap 一對一、多對一、一對多、多對多

8.1、resultMap處理欄位和屬性的對映關係

如果欄位名和實體類中的屬性名不一致的情況下,可以透過resultMap設定自定義對映。

  1. 可以透過為欄位起別名的方式,別名起成和屬性名一致。保證欄位名和實體類中的屬性名一致
<select id="getEmpByEmpId" resultType="emp">
    select emp_id empId,emp_name empName,age,sex from emp where emp_id = #{empId}
</select>

  1. 如果欄位名和實體類中的屬性名不一致的情況下,但是欄位名符合資料庫的規則(使用_),實體類中使用的屬性名符合java的規則(使用駝峰命名),可以在MyBatis的核心配置檔案中設定一個全域性配置資訊mapUnderscoreToCamelCase,可以在查詢表中的資料時,自動將帶下劃線“_”的欄位名轉為駝峰命名
    • user_name:userName
    • emp_id:empId
<settings>
    <!--將資料庫欄位名的下劃線對映為駝峰-->
    <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!--Emp getEmpByEmpId(@Param("empId") Integer empId);-->
<select id="getEmpByEmpId" resultType="emp">
    select * from emp where emp_id = #{empId}
</select>
  1. 使用resutlMap自定義對映處理
<!--
    resultMap:設定自定義的對映關係
    id:唯一標識
    type:處理對映關係的實體類的型別 一般使用MyBatis的別名
    常用的標籤
    id:處理主鍵和實體類中屬性的對映關係
    result:處理普通欄位和實體類中屬性的對映關係
    column:設定對映關係中的欄位名,必須是sql查詢出的某個欄位
    property:設定對映關係中的屬性的屬性名,必須是處理的實體型別中的屬性名
-->
<resultMap id="empReslutMap" type="emp">
    <id property="empId" column="emp_id"></id>
    <result property="empName" column="emp_name"></result>
    <result property="age" column="age"></result>
    <result property="sex" column="sex"></result>
</resultMap>

8.2、一對一對映處理

人與身份證號

  1. 級聯方式處理
/**
 * 根據id查詢人員資訊
 * @param id
 * @return
 */
Person findPersonById(@Param("id") Integer id);

<!-- Person findPersonById(Integer id);-->
<select id="findPersonById" resultMap="IdCardWithPersonResult">
    SELECT person.*,idcard.code
    FROM person,idcard
    WHERE person.card_id=idcard.id AND person.id=#{id}
</select>

<resultMap id="IdCardWithPersonResult" type="person">
    <id property="id" column="id"></id>
    <result property="name" column="name"></result>
    <result property="age" column="age"></result>
    <result property="sex" column="sex"></result>
    <result property="card.id" column="id"></result>
    <result property="card.code" column="code"></result>
</resultMap>

  1. association
<resultMap id="IdCardWithPersonResult2" type="person">
    <id property="id" column="id"></id>
    <result property="name" column="name"></result>
    <result property="age" column="age"></result>
    <result property="sex" column="sex"></result>
    <association property="card" javaType="IdCard">
        <id property="id" column="id"></id>
        <result property="code" column="code"></result>
    </association>
</resultMap>

  1. 分步查詢
<!--分步查詢第一步-->
<!-- Person findPersonById3(@Param("id") Integer id);-->
<select id="findPersonById3" resultMap="IdCardWithPersonResult3">
    select * from person where id=#{id}
</select>

<resultMap id="IdCardWithPersonResult3" type="person">
    <id property="id" column="id"></id>
    <result property="name" column="name"></result>
    <result property="age" column="age"></result>
    <result property="sex" column="sex"></result>

    <!--
    association:處理一對一或者多對一的對映關係(處理的實體類型別的屬性)
    property:設定需要處理對映關係的屬性的屬性名
    javaType:設定要處理的屬性的型別
    column:第一步傳遞給第二步的欄位,對映關係的表關聯的欄位
    -->
    <association property="card" javaType="IdCard" column="card_id"
                 select="com.qcby.mybatis.mapper.IdCardMapper.findCodeById">

    </association>
</resultMap>

<!--分步查詢的第二步-->
<!--IdCard findCodeById(@Param("id") Integer id);-->
<select id="findCodeById" resultType="idcard">
    SELECT * from idcard where id=#{id}
</select>

8.3、多對一對映處理

場景模擬:

查詢員工資訊以及員工所對應的部門資訊

使用resultMap自定義對映處理
處理多對一的對映關係:

  • 級聯方式處理

  • association

  • 分步查詢

  1. 級聯方式處理
/**
 * 獲取員工以及所對應的部門資訊
 * @param empId
 * @return
 */
Emp getEmpAndDeptByEmpId(@Param("empId") Integer empId);

<!-- Emp getEmpAndDeptByEmpId(@Param("empId") Integer empId);-->
<select id="getEmpAndDeptByEmpId" resultMap="empAndDeptResultMap">
    SELECT emp.*,dept.*
    FROM emp
    LEFT JOIN dept
    ON emp.dept_id=dept.dept_id
    WHERE emp.emp_id=#{empId}
</select>

<resultMap id="empAndDeptResultMap" type="emp">
     <id column="emp_id" property="empId"></id>
     <result column="emp_name" property="empName"></result>
     <result column="age" property="age"></result>
     <result column="sex" property="sex"></result>
     <result column="dept_id" property="dept.deptId"></result>
     <result column="dept_name" property="dept.deptName"></result>
 </resultMap>

@Test
public void testGetEmpAndDeptByEmpId(){
    Emp emp = empMapper.getEmpAndDeptByEmpId(1);
    System.out.println(emp);
}

  1. association
<resultMap id="empAndDeptResultMap" type="emp">
    <id column="emp_id" property="empId"></id>
    <result column="emp_name" property="empName"></result>
    <result column="age" property="age"></result>
    <result column="sex" property="sex"></result>
   <association property="dept" javaType="dept">
       <id column="dept_id" property="deptId"/>
       <result column="dept_name" property="deptName"></result>
   </association>
</resultMap>

  1. 分步查詢

  2. 根據員工id查詢員工資訊

emp介面中

/**
 * 透過分步查詢來查詢員工以及所對應部門資訊的第一步
 * @param empId
 * @return
 */
Emp getEmpAndDeptByStepOne(@Param("empId") Integer empId);

dept介面中

/**
 * 透過分步查詢來查詢員工以及所對應部門資訊的第二步
 * @param deptId
 * @return
 */
Dept getEmpAndDeptByStepTwo(@Param("deptId") Integer deptId);

emp對映檔案中

<!--Emp getEmpAndDeptByStepOne(@Param("empId") Integer empId);-->
<select id="getEmpAndDeptByStepOne" resultMap="empAndDeptByStepResultMap">
    select * from emp where emp_id = #{empId}
</select>

<resultMap id="empAndDeptByStepResultMap" type="Emp">
    <id column="emp_id" property="empId"></id>
    <result column="emp_name" property="empName"></result>
    <result column="age" property="age"></result>
    <result column="sex" property="sex"></result>

    <association property="dept" column="dept_id"
                 select="com.qcby.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo"
                 ></association>
</resultMap>

dept對映檔案中

<!--Dept getEmpAndDeptByStepTwo(@Param("deptId") Integer deptId);-->
<select id="getEmpAndDeptByStepTwo" resultType="Dept">
    select * from dept where dept_id = #{deptId}
</select>

測試

@Test
public void testGetEmpAndDeptByStepOne(){
    Emp emp = empMapper.getEmpAndDeptByStepOne(1);
    System.out.println(emp);
}

分步查詢的優點:可以實現延遲載入(懶載入),但是必須在核心配置檔案中設定全域性配置資訊:

lazyLoadingEnabled:延遲載入的全域性開關。當開啟時,所有管理物件都會延遲載入

aggressiveLazyLoading:當開啟時,任何方法的呼叫都會載入該物件的所有屬性。否則,每個屬性會按需載入,此時就可以實現按需載入,獲取的資料是什麼,就會執行相應的sql語句

此時可以透過association和collection中的fetchType屬性設定當前的分步查詢是否使用延遲載入,fetchType=“lazy(延遲載入)|eager(立即載入)”

8.4、一對多對映處理 部門 -->員工

沒有級聯方式的查詢,只有collection 和分步查詢

8.4.1 collection

dept介面

/**
 * 查詢部門以及部門中的員工資訊
 * @param deptId
 * @return
 */
Dept getDeptAndEmpByDeptId(@Param("deptId") Integer deptId);

dept對映檔案中

<!--Dept getDeptAndEmpByDeptId(@Param("deptId") Integer deptId);-->
<select id="getDeptAndEmpByDeptId" resultMap="deptAndEmpResultMap">
    SELECT *
    FROM dept
    LEFT JOIN emp
    ON dept.dept_id=emp.dept_id
    WHERE dept.dept_id=#{deptId}
</select>

<resultMap id="deptAndEmpResultMap" type="dept">
    <id column="dept_id" property="deptId"></id>
    <result column="dept_name" property="deptName"></result>
    <!--ofType:設定集合型別的屬性中儲存的資料的型別-->
    <collection property="emps" ofType="emp">
        <id column="emp_id" property="empId"></id>
        <result column="emp_name" property="empName"></result>
        <result column="age" property="age"></result>
        <result column="sex" property="sex"></result>
    </collection>
</resultMap>

測試方法

@Test
public  void testGetDeptAndEmpByDeptId(){
    Dept dept = deptMapper.getDeptAndEmpByDeptId(1);
    System.out.println(dept);
}

8.4.1 分步查詢

⑴查詢部門資訊

/**
 * 透過分步查詢進行查詢部門及部門中的員工資訊的第一步:查詢部門資訊
 * @param deptId
 * @return
 */
Dept getDeptAndEmpBySetpOne(@Param("deptId") Integer deptId);

<!-- Dept getDeptAndEmpBySetpOne(@Param("deptId") Integer deptId);-->
<select id="getDeptAndEmpBySetpOne" resultMap="deptAndEmpResultMapByStep">
    select * from dept where dept_id = #{deptId}
</select>

<resultMap id="deptAndEmpResultMapByStep" type="dept">
    <id column="dept_id" property="deptId"></id>
    <result column="dept_name" property="deptName"></result>

    <collection property="emps" column="dept_id"
                select="com.qcby.mybatis.mapper.EmpMapper.getDeptAndEmpBySetpTwo"></collection>
</resultMap>

⑵查詢員工資訊

/**
 * 透過分步查詢進行查詢部門及部門中的員工資訊的第二步:查詢員工資訊
 * @param deptId
 * @return
 */
List<Emp> getDeptAndEmpBySetpTwo(@Param("deptId")Integer deptId);

<!-- List<Emp> getDeptAndEmpBySetpTwo(@Param("deptId")Integer deptId);-->
<select id="getDeptAndEmpBySetpTwo" resultType="emp">
    select  * from  emp where dept_id = #{deptId}
</select>

⑶測試方法

@Test
public void testGetDeptAndEmpBySetp(){
    Dept dept = deptMapper.getDeptAndEmpBySetpOne(2);
    System.out.println(dept);
}

8.5、多對多對映關係

8.5.1、pojo

8.5.2、collection

8.5.3 分步查詢

⑴查詢訂單資訊

/**
 * 透過分步查詢進行查詢訂單以及訂單中的商品資訊的第一步
 * @param id
 * @return
 */
List<Orders>  findOrdersWithProduct2(@Param("id") Integer id);

<!-- List<Orders>  findOrdersWithProduct2(@Param("id") Integer id);-->
<select id="findOrdersWithProduct2" resultMap="OrdersWithProductResult2">
    select * from  orders where id = #{id}
</select>
<resultMap id="OrdersWithProductResult2" type="orders">
    <id column="id" property="id"></id>
    <result column="number" property="number"></result>

    <collection property="productList" column="id" ofType="product"
                select="com.qcby.mybatis.mapper.ProductMapper.findProductById">
    </collection>
</resultMap>

⑵查詢商品資訊

/**
 * 透過分步查詢進行查詢訂單以及訂單中的商品資訊的第二步
 * @param id
 * @return
 */
List<Product> findProductById(@Param("id") Integer id);

<!--List<Product> findProductById(@Param("id") Integer id);-->
<select id="findProductById" resultType="product">
    select * from product where id in(
        select product_id from ordersitem where orders_id = #{id}
    )
</select>

⑶測試

@Test
public void testFindOrdersWithProduct2(){
    List<Orders> orders = ordersMapper.findOrdersWithProduct2(1);
    orders.forEach(System.out::println);
}

相關文章