您好,登錄后才能下訂單哦!
本篇內容介紹了“Mybatis中怎么使用ResultMap解決屬性名和數據庫字段名不一致問題”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
我們Pojo類的屬性名和數據庫中的字段名不一致的現象時有發生,簡單的情況我們可以開啟駝峰命名法解決大小寫問題,但是遇到其它非大小寫問題,我們就不得不使用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匹配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>
上面講述的只是普通字段名不一致的問題,使用結果集映射解決相對簡單。而在Mybatis中關于使用結果集映射解決的問題比較出名的有多對一的處理和一對多的處理(這兩種問題是相對而言的)
我們生活中有很多相關的例子,這里以老師和學生為例,對于學生而言,多個學生擁有一個共同的老師,這屬于多對一問題;對于老師而言,一個老師擁有多個學生,這又是一個一對多的問題。
相關解析:
對于學生而言,屬于關聯現象,多個老師關聯一個老師 (多對一)
對于老師而言,屬于集合現象, 一個老師擁有很多學生(一對多)
測試環境搭建;
[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項目,導入相關依賴,并編寫實體類及其映射
搭建后項目目錄為:
<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> <!–標準的日志工廠實現–> <!–<setting name="logImpl" value="STDOUT_LOGGING"/>–> <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進行拼裝,就能得到我們上面最終的結果了。
同樣是上面的例子,對老師而言,就是一對多的關系
[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>
“Mybatis中怎么使用ResultMap解決屬性名和數據庫字段名不一致問題”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。