首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

MyBatis 實體類與資料表映射詳解

     編輯:Java 相關知識

前言

在使用 MyBatis 進行資料庫操作時,實體類屬性名與資料表欄位名不一致是常見問題。本文將透過完整範例,示範如何透過 SQL 別名與 <resultMap> 兩種方式解決欄位映射不匹配的問題。

一、準備測試資料表與資料

首先建立 orders 資料表並插入測試資料:

CREATE TABLE orders(
  order_id INT PRIMARY KEY AUTO_INCREMENT,
  order_no VARCHAR(20),
  order_price FLOAT
);
INSERT INTO orders(order_no, order_price) VALUES('aaaa', 23);
INSERT INTO orders(order_no, order_price) VALUES('bbbb', 33);
INSERT INTO orders(order_no, order_price) VALUES('cccc', 22);

二、定義實體類

實體類 Order 的屬性名(id、orderNo、price)與資料表欄位(order_id、order_no、order_price)並不對應:

package me.gacl.domain;

public class Order {
    private int id;          // 對應 order_id
    private String orderNo;  // 對應 order_no
    private float price;     // 對應 order_price
    // 省略 getter/setter/toString
}

三、編寫 Mapper 映射檔案

在 orderMapper.xml 中展示三種查詢方式:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="me.gacl.mapping.orderMapper">

  <!-- 1. 直接查詢:因欄位名不匹配,無法封裝結果 -->
  <select id="getOrderById" parameterType="int" resultType="me.gacl.domain.Order">
    select * from orders where order_id=#{id}
  </select>

  <!-- 2. 使用 SQL 別名讓欄位名與屬性名一致 -->
  <select id="selectOrder" parameterType="int" resultType="me.gacl.domain.Order">
    select order_id id, order_no orderNo, order_price price from orders where order_id=#{id}
  </select>

  <!-- 3. 使用 resultMap 進行精確映射 -->
  <select id="selectOrderResultMap" parameterType="int" resultMap="orderResultMap">
    select * from orders where order_id=#{id}
  </select>

  <resultMap type="me.gacl.domain.Order" id="orderResultMap">
    <id property="id" column="order_id"/>
    <result property="orderNo" column="order_no"/>
    <result property="price" column="order_price"/>
  </resultMap>

</mapper>

四、單元測試驗證

測試類 Test2 分別呼叫三個查詢方法:

@Test
public void testGetOrderById() {
    SqlSession sqlSession = MyBatisUtil.getSqlSession();
    String statement = "me.gacl.mapping.orderMapper.getOrderById";
    Order order = sqlSession.selectOne(statement, 1);
    sqlSession.close();
    System.out.println(order); // 輸出:null
}

@Test
public void testGetOrderById2() {
    SqlSession sqlSession = MyBatisUtil.getSqlSession();
    String statement = "me.gacl.mapping.orderMapper.selectOrder";
    Order order = sqlSession.selectOne(statement, 1);
    sqlSession.close();
    System.out.println(order); // 輸出:Order [id=1, orderNo=aaaa, price=23.0]
}

@Test
public void testGetOrderById3() {
    SqlSession sqlSession = MyBatisUtil.getSqlSession();
    String statement = "me.gacl.mapping.orderMapper.selectOrderResultMap";
    Order order = sqlSession.selectOne(statement, 1);
    sqlSession.close();
    System.out.println(order); // 輸出:Order [id=1, orderNo=aaaa, price=23.0]
}

五、總結

當實體類屬性與資料表欄位名稱不一致時,MyBatis 無法自動映射,會導致查詢結果為 null。解決方案有二:

  1. SQL 別名法:在查詢語句中為欄位起別名,使其與實體類屬性名一致。簡單直接,但 SQL 稍顯冗長。
  2. resultMap 映射法:使用 <resultMap> 明確定義屬性與欄位的對應關係。結構清晰、可維護性強,推薦用於複雜映射場景。

實務上建議優先使用 resultMap,特別是欄位較多或涉及關聯查詢時。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved