一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Mybatis中ResultMap解決屬性名和數據庫字段名不一致問題

Mybatis中ResultMap解決屬性名和數據庫字段名不一致問題

2022-03-04 18:04Stephen GS Java教程

我們Pojo類的屬性名和數據庫中的字段名不一致的現象時有發生,本文就詳細的介紹一下Mybatis中ResultMap解決屬性名和數據庫字段名不一致問題,感興趣的可以了解一下

 

前言

我們Pojo類的屬性名和數據庫中的字段名不一致的現象時有發生,簡單的情況我們可以開啟駝峰命名法解決大小寫問題,但是遇到其它非大小寫問題,我們就不得不使用Mybatis中的結果集映射resultMap。

 

1. 字段名不一致

數據庫中的字段
Mybatis中ResultMap解決屬性名和數據庫字段名不一致問題

我們項目中實體類的字段

public class User {

    private int id;
    private String name;
    private String password;

 

解決方法:

 

第一種方式: 起別名

pwd as password

<select id="getUserById" parameterType="int" resultType="com.gs.pojo.User">
    select id,name,pwd as password from user1 where id = #{id};
</select>

 

第二種方式: 結果集映射 resultMap

使用resultMap匹配pojo類中屬性名與數據庫中字段的值。
其中column為數據庫中的字段,property為實體類中的屬性

<!--結果集映射-->
<resultMap id="UserMap" type="user">
    <!--column數據庫中的字段,property實體類中的屬性-->
    <result column="id" property="id"/>
    <result column="name" property="name"/>
    <result column="pwd" property="password"/>
</resultMap>


<select id="getUserById" parameterType="int" resultMap="UserMap">
    select * from user1 where id = #{id};
</select>

官方文檔有這么一段話:

  • resultMap元素是MyBatis中最重要強大的元素
  • ResultMap的設計思想是,對簡單的語句做到零配置,對于復雜一點的語句,只需要描述語句之間的關系就行了。
  • ResultMap的優秀之處在于你完全可以不用顯示的配置字段名已經相同的屬性

根據官方文檔,上面的結果集映射可以簡化為:

<!--結果集映射-->
<resultMap id="UserMap" type="user">
    <!--column數據庫中的字段,property實體類中的屬性-->
  
    <result column="pwd" property="password"/>
</resultMap>


<select id="getUserById" parameterType="int" resultMap="UserMap">
    select * from user1 where id = #{id};
</select>

 

2. 多對一處理

上面講述的只是普通字段名不一致的問題,使用結果集映射解決相對簡單。而在Mybatis中關于使用結果集映射解決的問題比較出名的有多對一的處理和一對多的處理(這兩種問題是相對而言的)

我們生活中有很多相關的例子,這里以老師和學生為例,對于學生而言,多個學生擁有一個共同的老師,這屬于多對一問題;對于老師而言,一個老師擁有多個學生,這又是一個一對多的問題。

Mybatis中ResultMap解決屬性名和數據庫字段名不一致問題

相關解析:
對于學生而言,屬于關聯現象,多個老師關聯一個老師 (多對一)
對于老師而言,屬于集合現象, 一個老師擁有很多學生(一對多)

測試環境搭建;
[1] 建立一個老師表和學生表

CREATE TABLE `teacher`(

   `id` INT(10) NOT NULL,
   `name` VARCHAR(30) DEFAULT NULL,
   PRIMARY KEY (`id`)
)ENGINE = INNODB DEFAULT CHARSET=utf8

INSERT INTO teacher(`id`,`name`) VALUES(1,"zs");


CREATE TABLE `student`(

   `id` INT(10) NOT NULL,
   `name` VARCHAR(30) DEFAULT NULL,
   `tid` INT(10) DEFAULT NULL,
    PRIMARY KEY(`id`),
    KEY `fktid` (`tid`),
    CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher`(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8


INSERT INTO `student`(`id`,`name`,`tid`) VALUES("1","小明","1");
INSERT INTO `student`(`id`,`name`,`tid`) VALUES("2","小紅","1");
INSERT INTO `student`(`id`,`name`,`tid`) VALUES("3","小張","1");
INSERT INTO `student`(`id`,`name`,`tid`) VALUES("4","小李","1");
INSERT INTO `student`(`id`,`name`,`tid`) VALUES("5","小工","1");

[2] 新建一個Maven項目,導入相關依賴,并編寫實體類及其映射
搭建后項目目錄為:

Mybatis中ResultMap解決屬性名和數據庫字段名不一致問題

<1> 導入依賴,并解決打包問題

 <!--導入依賴-->
    <dependencies>
        <!--mysql驅動-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
        </dependency>
        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.2</version>
        </dependency>
        <!--junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
        </dependency>
    </dependencies>

    <!--解決導出項目時resources的xml未打包問題-->
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

<2> 編寫數據庫配置文件 db.properties

driver = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8
username = root

<3> 編寫Mybatis核心配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--導入外部配置文件-->
    <properties resource="db.properties"/>
    
   <!-- <settings>
        &lt;!&ndash;標準的日志工廠實現&ndash;&gt;
        &lt;!&ndash;<setting name="logImpl" value="STDOUT_LOGGING"/>&ndash;&gt;
        <setting name="logImpl" value="LOG4J"/>
    </settings>-->

    <!--可以給實體類起別名-->
    <typeAliases>
       <package name="com.gs.pojo"/>
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
            </dataSource>
        </environment>

    </environments>

    <mappers>
        <mapper resource="com/gs/dao/TeacherMapper.xml"/>
        <mapper resource="com/gs/dao/StudentMapper.xml"/>
        <!--<mapper class="com.com.com.gs.dao.TeacherMapper"/>
        <mapper class="com.com.com.gs.dao.StudentMapper"/>-->
    </mappers>

</configuration>

<4> 編寫實體類
這里的Student類中有一個老師的字段,這正是與我們數據庫中不一致的地方,也是這次問題解決的重點
Student.class

package com.gs.pojo;

import lombok.Data;

/**
 * @Auther: Gs
 * @Date: 2020/6/9
 * @Description: com.com.com.gs.pojo
 * @version: 1.0
 */
@Data
public class Student {

    private int id;
    private String name;
    //組合進來一個老師
    private Teacher teacher;

}

Teacher.class

package com.gs.pojo;

import lombok.Data;

/**
 * @Auther: Gs
 * @Date: 2020/6/9
 * @Description: com.com.com.gs.pojo
 * @version: 1.0
 */
@Data
public class Teacher {

    private int id;
    private String name;

}

<5> 編寫接口 StudentMapper

public interface StudentMapper {

    //查詢所有的學生信息,以及對應的的老師的信息
    public List<Student> getStudent();
}    

<6> 使用resultMap解決問題

[1] 按結果嵌套查詢 使用association字段來匹配結果集中Teacher中的字段屬性

<!--按照結果嵌套處理-->
<select id="getStudent" resultMap="studentMapper2">
    select s.id sid, s.name sname, t.name tname
    from student s, teacher t
    where s.tid = t.id
</select>

<resultMap id="studentMapper2" type="student">
    <result property="id" column="sid"/>
    <result property="name" column="sname"/>
    <association property="teacher" javaType="Teacher">
        <result property="name" column="tname"/>
    </association>
</resultMap>

解析:一開始看這sql語句肯定很繞,我們先從原生的sql語句出發,編寫出能聯表查詢的語句(因為學生類里有老師這個實體屬性)
這里我們使用別名以及聯表查詢得到學號,學生姓名,老師姓名,不難發現我們使用簡單的reultType已經不能解決這個多屬性問題(resultType適合解決單一實體類,字段名和數據庫屬性一一對應的情況),所以我們想到使用結果集映射 resultMap.

select s.id sid, s.name sname, t.name tname
   from student s, teacher t
   where s.tid = t.id

resultMap中前兩項的字段名和屬性名比較好映射,直接是學生的id,學生的姓名,可是最后一項的屬性時一個Teacher對象,所以我們必須使用關聯association 來嵌套老師這個實體類的屬性。相關語句為:

<association property="teacher" javaType="Teacher">
    <result property="name" column="tname"/>
</association>

那么完整的隱射語句為:

<resultMap id="studentMapper2" type="student">
    <result property="id" column="sid"/>
    <result property="name" column="sname"/>
    <association property="teacher" javaType="Teacher">
        <result property="name" column="tname"/>
    </association>
</resultMap>

最后我們再把這兩個語句拼接就能得到我們最終的語句了。

[2] 按照查詢嵌套處理 (理解起來相對復雜)

<!--思路: 1.查詢所有的學生信息
          2.根據查詢出來的學生的tid,尋找對應的老師 子查詢
-->

<select id="getStudent" resultMap="studentMapper">
    select * from student;
</select>
<resultMap id="studentMapper" type="student">
    <result property="id" column="id"/>
    <result property="name" column="name"/>
    <!--復雜的屬性,我們需要單獨處理 對象: association  集合: collection -->
    <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>

<select id="getTeacher" resultType="Teacher">
    select * from teacher where id = #{id};
</select>

解析:看著語句更加暈了,這其實相當于我們原生Sql的子查詢,這里分三步走,把原本的結果集在通過查詢進行封裝。
<1> 編寫簡單的學生查詢

<select id="getStudent" resultMap="studentMapper">
    select * from student;
</select>

<2> 完成相關實體類屬性和數據庫字段的映射,前兩個依舊簡單,關鍵還是Teacher這個實體類,這次我們不嵌套屬性,而是通過一次子查詢解決問題 (property對應實體類屬性,column對應數據庫名稱,javaType標明類型,select表示使用查詢的方法)

  <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>

這里使用 getTeacher的方法獲取新的屬性值

<select id="getTeacher" resultType="Teacher">
    select * from teacher where id = #{id};
</select>

完整的映射

<resultMap id="studentMapper" type="student">
    <result property="id" column="id"/>
    <result property="name" column="name"/>
    <!--復雜的屬性,我們需要單獨處理 對象: association  集合: collection -->
    <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>

最后,我們把這三句sql進行拼裝,就能得到我們上面最終的結果了。

 

3. 一對多處理

同樣是上面的例子,對老師而言,就是一對多的關系
[1] 環境搭建和上面的一樣
[2] 測試的實體類的變化
Student

@Data
public class Student {
	//學生id
    private int id;
    //學生姓名
    private String name;
    //教師id
    private int tid;
}

Teacher

@Data
public class Teacher {

    private int id;
    private String name;

    //一個老師有多個學生
    private List<Student> students;

}

[3] 業務需求:獲取指定老師下所有學生及老師自身的信息
<1> 編寫接口

//獲取指定老師下所有學生及老師的信息
Teacher getTeacher(@Param("tid") int id);

<2> 解決方式依舊是兩種,一種是按結果嵌套查詢(即所謂的連接查詢),另外一種是按照查詢嵌套處理(即所謂的子查詢)
第一種方式:按結果嵌套查詢

編寫連接查詢的sql語句

<!--按結果嵌套查詢-->
<select id="getTeacher" resultMap="teacherMap">
    select s.id sid, s.name sname, t.id tid, t.name tname from student s, teacher t
    where s.tid = t.id and  t.id = #{tid}
</select>

通過結果集映射找到相應的屬性(由于是一對多關系,所以使用集合類型 collection)

<resultMap id="teacherMap" type="teacher">
    <result property="id" column="tid"/>
    <result property="name" column="tname"/>
    <!--復雜的屬性:我們需要單獨處理對象, 對象:association 集合:collection
    javaType="" 指定屬性類型
    ofType 指定屬性中的泛型類型
    -->
    <collection property="students" ofType="Student">
        <result property="id" column="sid"/>
        <result property="name" column="sname"/>
        <result property="tid" column="tid"/>
    </collection>
</resultMap>

相關解析:
復雜的屬性:我們需要單獨處理對象, 多對一時使用 association,一對多是使用collection;
若是普通的pojo類使用 javaType="" 指定屬性類型,若是泛型類型則要使用ofType 指定屬性中的泛型類型
3) 我們拼接一下上面兩段代碼即得到我們的結果

<!--按結果嵌套查詢-->
<select id="getTeacher" resultMap="teacherMap">
    select s.id sid, s.name sname, t.id tid, t.name tname from student s, teacher t
    where s.tid = t.id and  t.id = #{tid}
</select>
<resultMap id="teacherMap" type="teacher">
    <result property="id" column="tid"/>
    <result property="name" column="tname"/>
    <!--復雜的屬性:我們需要單獨處理對象, 對象:association 集合:collection
    javaType="" 指定屬性類型
    ofType 指定屬性中的泛型類型
    -->
    <collection property="students" ofType="Student">
        <result property="id" column="sid"/>
        <result property="name" column="sname"/>
        <result property="tid" column="tid"/>
    </collection>
</resultMap>

第二種方式:按照查詢嵌套處理

使用子查詢進行拼接
<1> 先查出指定老師的信息

<!--子查詢-->
<select id="getTeacher" resultMap="teacherMap2">
    select * from teacher where id = #{tid}
</select>

<2> 由于查詢的信息里有學生對象信息,所以得進行結果集映射

<resultMap id="teacherMap2" type="Teacher">
    <result property="id" column="id"/>
    <collection property="students" column="id" javaType="ArrayList" ofType="Student" select="getStudent"/>
</resultMap>

解析:

<collection property="students" column="id" javaType="ArrayList" ofType="Student" select="getStudent"/>

property表明要查詢的實體類屬性名,javaType表明查詢的類型,ofType表明泛型的類型,select表明使用查詢的方式,這里比較疑惑的應該是column的值,它對應的是數據庫中的列,那它應該使用什么呢,我們不難發現,我們要查詢的是老師下的所有學生,而學生表示通過老師id進行關聯的,那么它對應的值應該是數據庫的教師id的列名
<3> 最后編寫通過老師id查詢學生的方法.getStudent

<select id="getStudent" resultType="Student">
    select * from student where tid=#{id}
</select>

<4> 最后我們把上面的代碼塊進行拼接就能滿足我們的業務需求了。

<!-- =============================== -->
<!--子查詢-->
<select id="getTeacher" resultMap="teacherMap2">
    select * from teacher where id = #{tid}
</select>
<resultMap id="teacherMap2" type="Teacher">
    <result property="id" column="id"/>
    <collection property="students" column="id" javaType="ArrayList" ofType="Student" select="getStudent"/>
</resultMap>
<select id="getStudent" resultType="Student">
    select * from student where tid=#{id}
</select>

 

小結

解決屬性名不一致的問題大體上分為三種情況。簡單的名字不同,類型相同我們可以起別名解決。對于名字不同,類型也不同,我們只能使用結果集映射解決,這種方式又分為兩種情況,一種是多對一,一種是一對多,我們在解決多對一時,可以聯想學生和老師的關系,多個學生關聯一個老師,那么我們使用association(關聯)這個關鍵詞,而反過來,一個老師下有多個學生,屬于集合關系,那么我們可以使用collection(集合)。

到此這篇關于Mybatis中ResultMap解決屬性名和數據庫字段名不一致問題的文章就介紹到這了,更多相關Mybatis 屬性名和數據庫字段名不一致內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://blog.csdn.net/TheWindOfSon/article/details/106696437

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲一区 在线播放 | 日本黄色一区 | 男女被爆动漫羞羞动漫 | 3d蒂法受辱在线播放 | 欧美国产精品久久 | 色综合天天综合网国产人 | 久久婷婷五月综合色丁香 | 喜爱夜蒲2三级做爰 | 成人欧美一区二区三区白人 | 久久精品亚洲精品国产欧美 | 国士李风起全文在线阅读 | 深夜激情网站 | 男人狂躁女人下半身 | 免费欧美视频 | 天天gan| 日韩精品视频免费 | 色综合久久夜色精品国产 | 国产精品网站在线观看 | 嫩草影院永久一二三入口 | 精品丰满人妻无套内射 | 天天做天天爱天天综合网 | 国产成人啪精品午夜在线播放 | 美女脱小内内给男生摸j | 国产精品视频久久久 | 美女尿口照片 | 好逼365| 欧美搞逼视频 | 潘甜甜在线观看 | 欧美一级片免费在线观看 | 亚洲人成在线播放 | 俄罗斯年轻男同gay69 | 女人pp被扒开流水了 | 亚洲精品中文字幕久久久久久 | 久久九九久精品国产尤物 | 亚洲国产一区二区三区a毛片 | 网站久久 | 乳环贵妇堕落开发调教番号 | 欧美日韩国产一区二区三区在线观看 | 欧美高清milf在线播放 | jazz中国女人护士 | 国模一区二区三区视频一 |