Mybatis-Spring Boot 手寫SQL語句


一、技術概述

MyBatis 是支持普通 SQL 查詢,存儲過程和高級映射的優秀持久層框架。MyBatis 消除了幾乎所有的JDBC代碼和參數的手工設置以及結果集的檢索。MyBatis 使用簡單的 XML 或注解用於配置和原始映射,將接口和 Java 的 POJOs(Plain Ordinary Java Objects,普通的 Java對象)映射成數據庫中的記錄。

在本次團隊項目中,數據庫的操作占了大頭,因此學習 Mybatis 來提高編程效率變得至關重要。Mybatis 提供方便簡易的自動生成的SQL語句,但涉及復雜數據庫操作需要自行編寫SQL語句,要求對SQL語句、XML 語言有較高的掌握程度。

二、技術詳述

當遇到復雜的數據庫操作,自動生成的SQL語句滿足不了我們的需求時,就需要自己動手寫SQL語句來實現期望的效果,那么究竟從哪里來入手寫呢?

1.創建所需的DTO對象作為返回類型(若不需要DTO對象則跳過此步)

當所需的返回數據不存在現成的對象時,可以創建一個DTO對象來存放由數據庫操作所得到的數據。

package edu.fzu.zhishe.core.dto;

import io.swagger.annotations.ApiModelProperty;

public class CmsClubMemberBriefDTO {

@ApiModelProperty(value = "用戶 id")
private Integer userId;

@ApiModelProperty(value = "用戶名")
private String username;

@ApiModelProperty(value = "昵稱")
private String nickname;

@ApiModelProperty(value = "頭銜")
private String honor;

@ApiModelProperty(value = "角色")
private String role;

@ApiModelProperty(value = "活躍度")
private Integer credit;

@ApiModelProperty(value = "頭像地址")
private String avatarUrl;

public Integer getUserId() {return userId;}

public void setUserId(Integer userId) {this.userId = userId;}

public String getUsername() {return username;}

public void setUsername(String username) {this.username = username;}

public String getNickname() {return nickname;}

public void setNickname(String nickname) {this.nickname = nickname;}

public String getHonor() {return honor;}

public void setHonor(String honor) {this.honor = honor;}

public String getRole() { return role; }

public void setRole(String role) {this.role = role;}

public Integer getCredit() { return credit; }

public void setCredit(Integer credit) {this.credit = credit;}

public String getAvatarUrl() {return avatarUrl;}

public void setAvatarUrl(String avatarUrl) {this.avatarUrl = avatarUrl;}
}

2.基於DTO對象,在mapper中編寫所需的ResultMap

根據所需要的數據庫中的數據,編寫resultmap。
【注】避免在自動生成的mapper中添加自己手寫的resultmap,否則重新部署數據庫將會被刪除!

<resultMap id="ClubMap5" type="edu.fzu.zhishe.core.dto.CmsClubMemberBriefDTO">
    <id column="user_id" jdbcType="INTEGER" property="userId" />
    <result column="username" jdbcType="VARCHAR" property="username" />
    <result column="nickname" jdbcType="VARCHAR" property="nickname" />
    <result column="description" jdbcType="VARCHAR" property="role" />
    <result column="honor_name" jdbcType="VARCHAR" property="honor" />
    <result column="credit" jdbcType="INTEGER" property="credit" />
    <result column="avatar_url" jdbcType="VARCHAR" property="avatarUrl" />
  </resultMap>

3.基於編寫的ResultMap,編寫SQL語句

<select id="listClubMember" resultMap="ClubMap5">
    SELECT
      u.id AS user_id,
      u.username,
      u.nickname,
      r.description,
      uc.credit,
      h.`name` AS honor_name,
      u.avatar_url
    FROM
      ( SELECT * FROM cms_user_club_rel WHERE club_id = #{clubId} ) AS uc
      LEFT JOIN sys_user u ON uc.user_id = u.id
      LEFT JOIN sys_role r ON uc.role_id = r.id
      LEFT JOIN cms_member_honor h ON uc.honor_id = h.id
    <where>
      <if test="queryParam.name!=null and queryParam.name!=''">
        AND (username LIKE concat("%",#{queryParam.name},"%") OR
            nickname LIKE concat("%",#{queryParam.name},"%"))
      </if>
      <if test="queryParam.honorId!=null and queryParam.honorId!=''">
        AND uc.honor_id = #{queryParam.honorId, jdbcType=INTEGER}
      </if>
    </where>
    ORDER BY
      uc.join_date DESC
  </select>

4.在DAO層聲明方法

List<CmsClubMemberBriefDTO> listClubMember(@Param("clubId") Integer clubId, @Param("queryParam") CmsClubMemberQuery clubMemberQuery);

完成這些步驟就可以調用對應方法,使用自己編寫的SQL語句了。

三、遇到的問題和解決過程

一開始在選定返回類型的時候(也就是技術詳述中的第一步)只是單純地將DTO對象作為一個封裝數據的容器,將DTO對象作為mapper中的返回類型,但在聲明方法的時候返回類型用了另一個部署數據庫自動生成的一個對象(包含DTO對象所有屬性),雖然可以成功運行並且得到結果,但是為了避免潛在的未知的bug,還是將返回類型統一成了DTO對象。

暫時沒有遇到其他問題。

四、總結

當碰到復雜的數據庫操作時,除了可以將自動生成的SQL組合進行使用以外,自己編寫所需的SQL語句也是非常方便且高效的方法,可以很大程度提高代碼效率。

五、參考文獻


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM