天天看點

MyBatis精講(八)MyBatis注解用法之DAO資料注解對象實戰代碼詳解

作者:老K玩代碼

大家好,我是 @老K玩代碼。

本期是關于MyBatis基礎教程講義的最後一講了,我們要來說說MyBatis的一個特性——注解。

MyBatis裡有很多功能注解,我們可以通過這些注解,實作各種映射器接口,替代mapper.xml類檔案的作用。

到底應該怎麼做呢?我們一起開看一下。

MyBatis精講(八)MyBatis注解用法之DAO資料注解對象實戰代碼詳解

之前的内容可以通過下面的連結檢視:

  • 老K玩代碼:MyBatis精講(一)MyBatis基礎配置及持久層連接配接建立代碼實戰
  • 老K玩代碼:MyBatis精講(二)常用工具MyBatisUtils類的實作
  • 老K玩代碼:MyBatis精講(三)一篇文章讓你學會如何用MyBatis擷取資料
  • 老K玩代碼:MyBatis精講(四)查詢資料方法精講及實戰代碼集合
  • 老K玩代碼:MyBatis精講(五)CRUD操作及實戰代碼精講
  • 老K玩代碼:MyBatis精講(六)一對多資料查詢實戰分享
  • 老K玩代碼:MyBatis精講(七)動态SQL查詢方法實戰代碼講解

這一講對的内容有點多,建議可以先收藏起來,慢慢讀,慢慢消化。

一、準備工作

通過maven建立項目,以及在pom檔案裡配置依賴庫相關的步驟就不介紹了,有需要的可以看《MyBatis精講(一)MyBatis基礎配置及持久層連接配接建立代碼實戰》。

項目配置好後,我們先把資料庫通過sql語句的方式導入到項目裡:

DROP TABLE IF EXISTS `employee`;
CREATE TABLE `employee`  (
  `id` int UNSIGNED NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  `depart` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  `salary` decimal(10, 2) NOT NULL,
  `age` int NOT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

DROP TABLE IF EXISTS `department`;
CREATE TABLE `department`  (
  `did` int UNSIGNED NOT NULL AUTO_INCREMENT,
  `depart` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `member` int NULL DEFAULT NULL,
  PRIMARY KEY (`did`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

INSERT INTO `employee` VALUES (5001, '趙乾', '銷售部', 6000.00, 28);
INSERT INTO `employee` VALUES (5002, '孫禮', '銷售部', 7000.00, 34);
INSERT INTO `employee` VALUES (6001, '周武', '技術部', 6500.00, 27);
INSERT INTO `employee` VALUES (6002, '鄭望', '技術部', 7500.00, 40);

INSERT INTO `department` VALUES (1, '銷售部', 5);
INSERT INTO `department` VALUES (2, '技術部', 6);           

在項目路徑下建立一個dao目錄(本例中的完整路徑為./src/main/java/koder/mybatis/dao)。

DAO是Data Annotation Objects的首字母,表示資料注解對象實體。

然後在mybatis-config.xml進行如下配置(注:mybatis-config.xml檔案路徑參考《MyBatis精講(一)MyBatis基礎配置及持久層連接配接建立代碼實戰》中的内容。)

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="True"/>
    </settings>
    <environments default="dev">
        <environment id="dev">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url"
                          value="jdbc:mysql://localhost:3306/javasql?useUnicode=true&characterEncoding=utf-8"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <package name="koder.mybatis.dao"/>
    </mappers>
</configuration>           
  • <package>是用來配置映射器包的标簽,一般是包含映射器接口的目錄位置。

二、查詢資料

我們首先在映射器包(本例中該路徑為./src/main/java/koder/mybatis/dao)下建立一個接口類——HRDao.java,并編寫以下内容:

  • HRDao.java
import koder.mybatis.dto.EmployeeDTO;
import koder.mybatis.entity.Employee;
import org.apache.ibatis.annotations.*;

import java.util.List;

public interface HRDao {
    @Select("select * from employee where id = #{value}")
    public Employee selectById(@Param("value") Integer id);
}           
  • koder.mybatis.dto.EmployeeDTO是後面案例會用到的資料傳輸對象類,在這裡先導入;
  • org.apache.ibatis.annotations是mybatis的注解類;
  • 用@Select注解,定義sql查詢語句;
  • 對于sql查詢語句中的可變參數,用#{value}表示,這裡的value是自定義的,可以是任何變量名稱;
  • 用@Param注解定義變量參數,便是該參數對應在sql查詢語句中的名稱,本例中表示java方法參數id就是sql語句中的value值。

這樣,一個資料注解對象、也就是注解映射器就寫好了,接下來我們編寫測試用例:

  • MyBatisTest.java(檔案路徑和基本配置參見《MyBatis精講(三)一篇文章讓你學會如何用MyBatis擷取資料》)
@Test
public void TestDaoSelectById() {
    SqlSession sqlSession = null;
    try {
        sqlSession = MyBatisUtils.openSession();
        HRDao hrDao = sqlSession.getMapper(HRDao.class);
        Employee emp = hrDao.selectById(6001);
        System.out.println(emp.getName());
    }catch (Exception e) {
        e.printStackTrace();
    } finally {
        MyBatisUtils.closeSession(sqlSession);
    }
}           
  • 通過SqlSession的getMapper方法擷取資料注解對象類,本例中為HRDao的class;
  • 調用HRDao的查詢方法,就能直接對應映射的sql語句,執行查詢,傳回對應資料類型;

上述代碼運作後的結果為:

周武           

三、插入資料

插入資料的映射接口,可以用@Insert注解器實作:

  • HRDao.java
@Insert("insert into employee(name, depart, salary, age) values (#{name}, #{depart}, #{salary}, #{age})")
@SelectKey(statement = "select last_insert_id()", keyProperty = "id", keyColumn = "id", before = false, resultType = Integer.class)
public int insert(Employee employee);           
  • 上述代碼内容,應寫在HRDao接口内,是HRDao的内部方法;
  • @Insert可以接收sql的插入語句,如果傳入的是實體對象(如Employee),@Insert注解器會自動将實體類的成員變量通過駝峰轉換傳入sql語句;
  • @SelectKey相當于MyBatis的xml文法中的<selectKey>功能一緻,定義的sql語句會和主語句一起被執行。statement參數接收sql語句,keyProperty接受java類中的成員變量名,keyColumn接受資料庫中的字段列名,before表示該語句是在主語句之前還是之後執行,resultType是将執行後得到的資料存入那個資料類型中;

然後在MyBatisTest.java中寫入測試用例:

  • MyBatisTest.java
@Test
public void TestDaoInsert() {
    SqlSession session = null;
    try {
        session = MyBatisUtils.openSession();
        Employee employee = new Employee();
        employee.setAge(34);
        employee.setDepart("技術部");
        employee.setName("儲緯");
        employee.setSalary(7700.0f);
        HRDao hrDao = session.getMapper(HRDao.class);
        hrDao.insert(employee);
        session.commit();
        System.out.println(employee.getId());
    } catch (Exception e) {
        if (session != null) {
            session.rollback();
        }
        throw new RuntimeException(e);
    } finally {
        MyBatisUtils.closeSession(session);
    }
}           
  • 由于映射器接口中insert方法傳入的參數是Employee,是以我們先執行個體化一個Employee執行個體,傳入到HRDao.insert方法中;
  • insert方法使用事務機制,是以完成方法調用後,需要commit才能生效,并且失敗後需要rollback。

執行上述代碼後,得到結果如下:

6003           

并且,檢視資料庫也能發現新的資料被錄入成功!

四、修改資料

編寫映射接口。

  • HRDao.java
@Update("update employee set name = #{name}, depart = #{depart}, salary = #{salary}, age = #{age} where id = #{id}")
public int update(Employee employee);           
  • @Update是更新資料的注解方法,文法特征與@Insert類似。

而測試用例編寫如下:

  • MyBatis.java
@Test
public void TestDaoUpdate() {
    SqlSession session = null;
    try {
        session = MyBatisUtils.openSession();
        HRDao hrDao = session.getMapper(HRDao.class);
        Employee employee = hrDao.selectById(6001);
        employee.setSalary(7900f);
        hrDao.update(employee);
        session.commit();
        System.out.println(employee.getId());
    } catch (Exception e) {
        if (session != null) {
            session.rollback();
        }
        throw new RuntimeException(e);
    } finally {
        MyBatisUtils.closeSession(session);
    }
}           
  • 由于修改資料,需要先從資料庫中擷取,我們用查詢方法select ById擷取Employee執行個體;
  • 調用HRDao的update方法,執行更新資料的操作;
  • 由于是事務機制,是以需要添加commit和rollback語句;

執行上述代碼後,可以發現資料庫中對應條目的薪酬已改為7900.00。

五、删除資料

編寫映射接口:

  • HRDao.java
@Delete("delete from employee where id = #{value}")
public int delete(@Param("value") Integer id);           
  • @Delete是删除資料的注解類,注意要點與@Update、@Insert一緻;
  • 參數用@Param進行映射比對;

測試用例編寫如下:

  • MyBatis.java
@Test
public void TestDaoDelete() {
    SqlSession session = null;
    try {
        session = MyBatisUtils.openSession();
        HRDao hrDao = session.getMapper(HRDao.class);
        hrDao.delete(6003);
        session.commit();
    } catch (Exception e) {
        if (session != null) {
            session.rollback();
        }
        throw new RuntimeException(e);
    } finally {
        MyBatisUtils.closeSession(session);
    }
}           

執行上述代碼後,可以發現,之前插入的資料“儲緯”已被删除;

六、自定義ResultMap連結清單查詢

之前講過通過mapper.xml文法連表查詢需要用到resultMap标簽,那麼,如果用資料注解對象,如何解決連結清單查詢的問題呢?

首先在HRDao.java編寫接口:

  • HRDao.java
@Select("select e.*, d.* from employee e, department d where e.depart = d.depart")
@Results({
        @Result(property="employee.id", column="id", id = true),
        @Result(property="employee.name", column="name"),
        @Result(property="employee.salary", column="salary"),
        @Result(property="employee.depart", column="depart"),
        @Result(property="employee.depart", column="depart"),
        @Result(property="employee.age", column="age"),
        @Result(property="department.did", column="did"),
        @Result(property="department.member", column="member")
})
public List<EmployeeDTO> selectDTO();           
  • 我們先用@Select編寫連結清單查詢的語句;
  • 利用@Results注解定義目前方法的結果類;
  • 在@Results中通過@Result對資料屬性進行映射,參數property接收java類中的成員變量,參數column接收資料庫中的字段列名,id表示該字段是否作為id索引;

測試用例:

  • MyBatis.java
@Test
public void TestDaoSelectDto() {
    SqlSession session = null;
    try {
        session = MyBatisUtils.openSession();
        HRDao hrDao = session.getMapper(HRDao.class);
        List<EmployeeDTO> emps = hrDao.selectDTO();
        for (EmployeeDTO emp: emps) {
            System.out.println(emp.getEmployee().getName() + "所在的部門有"+emp.getDepartment().getMember() + "人。");
        }
    } catch (Exception e) {
        throw new RuntimeException(e);
    } finally {
        MyBatisUtils.closeSession(session);
    }
}           
  • DTO連結清單查詢和普通查詢代碼邏輯一樣;

執行上述代碼,獲得如下結果:

趙乾所在的部門有5人。
孫禮所在的部門有5人。
周武所在的部門有6人。
鄭望所在的部門有6人。           

以上,就是MyBatis的資料注解對象DAO常見的使用方法。

DAO相比起xml映射器,代碼的可讀性更強,對java工程師更友好,而且java編譯器能提供文法支援,更便于工程師們排查錯誤。

熟練掌握DAO映射接口的寫法,對高效使用MyBatis有很大的幫助!

MyBatis精講(八)MyBatis注解用法之DAO資料注解對象實戰代碼詳解

感謝你看到這裡。

如果你對老K分享的内容有任何疑問,歡迎随時在評論區留言或者私信我。

正在學習的小夥伴記得給老K一個贊哦,你的支援是我持續輸出課程内容最大的動力。

結束語

我是專注于開發領域的@老K玩代碼,會持續生産關于如何學習程式設計語言的優質内容。

如果你對程式設計和項目開發有興趣,可以關注我。

MyBatis精講(八)MyBatis注解用法之DAO資料注解對象實戰代碼詳解

#頭條創作挑戰賽#