MyBatis中resultType和parameterType和resultMap使用總結(jié)
resultType 與 parameterType 的基本使用的區(qū)別
1、使用 resultType:主要針對(duì)于從數(shù)據(jù)庫(kù)中提取相應(yīng)的數(shù)據(jù)出來(lái)
2、使用parameterType:主要針對(duì)于 將信息存入到數(shù)據(jù)庫(kù)中 如: insert 增加數(shù)據(jù)到數(shù)據(jù)庫(kù)zhong Update等
- resultType是sql語(yǔ)句查詢結(jié)果集的封裝類型,也就是說(shuō)把sql查詢的結(jié)果封裝在bean里返回回去,是存數(shù)據(jù)用的。
- paramType是從傳過(guò)來(lái)的Bean中取數(shù)據(jù)放進(jìn)例如insert語(yǔ)句的values中當(dāng)實(shí)參用,是取數(shù)據(jù)用的。
MyBatis中 resultType 和 resultMap 的區(qū)別
resultType和resultMap功能類似 ,都是返回對(duì)象信息 ,但是resultMap要更強(qiáng)大一些 ,可自定義。
因?yàn)閞esultMap要配置一下,表和類的一一對(duì)應(yīng)關(guān)系,所以說(shuō)就算你的字段名和你的實(shí)體類的屬性名不一樣也沒(méi)關(guān)系,都會(huì)給你映 射出來(lái),但是,resultType就比較雞肋了,必須字段名一樣,比如說(shuō) cId和c_id 這種的都不能映射 。
下面介紹幾個(gè)常用的映射關(guān)系:
1.單表查詢
resultMap:當(dāng)使用resultMap做SQL語(yǔ)句返回結(jié)果類型處理時(shí),通常需要在mapper.xml中定義resultMap進(jìn)行pojo和相應(yīng)表字段的對(duì)應(yīng)。
<resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersUserResultMap"> ? ? <!-- 配置映射的訂單信息 --> ? ? <!-- id:指定查詢列中的唯 一標(biāo)識(shí),訂單信息的中的唯 一標(biāo)識(shí),如果有多個(gè)列組成唯一標(biāo)識(shí),配置多個(gè)id ? ? ? ? column:訂單信息的唯 一標(biāo)識(shí) 列 ? ? ? ? property:訂單信息的唯 一標(biāo)識(shí) 列所映射到Orders中哪個(gè)屬性 ? ? ? --> ? ? <id column="id" property="id"/> ? ? <result column="user_id" property="userId"/> ? ? <result column="number" property="number"/> ? ? <result column="createtime" property="createtime"/> ? ? <result column="note" property="note"/> ? ? ? ? </resultMap>
2.關(guān)聯(lián)查詢(一對(duì)一)
resultMap對(duì)于一對(duì)一表連接的處理方式通常為在主表的pojo中添加嵌套另一個(gè)表的pojo,然后在mapper.xml中采用association節(jié)點(diǎn)元素進(jìn)行對(duì)另一個(gè)表的連接處理。例如
<resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersUserResultMap"> ? ? <!-- 配置映射的訂單信息 --> ? ? <!-- id:指定查詢列中的唯 一標(biāo)識(shí),訂單信息的中的唯 一標(biāo)識(shí),如果有多個(gè)列組成唯一標(biāo)識(shí),配置多個(gè)id ? ? ? ? column:訂單信息的唯 一標(biāo)識(shí) 列 ? ? ? ? property:訂單信息的唯 一標(biāo)識(shí) 列所映射到Orders中哪個(gè)屬性 ? ? ? --> ? ? <id column="id" property="id"/> ? ? <result column="user_id" property="userId"/> ? ? <result column="number" property="number"/> ? ? <result column="createtime" property="createtime"/> ? ? <result column="note" property=note/> ? ?? ? ? <!-- 配置映射的關(guān)聯(lián)的用戶信息 --> ? ? <!-- association:用于映射關(guān)聯(lián)查詢單個(gè)對(duì)象的信息 ? ? property:要將關(guān)聯(lián)查詢的用戶信息映射到Orders中哪個(gè)屬性 ? ? ?--> ? ? <association property="user" ?javaType="cn.itcast.mybatis.po.User"> ? ? ? ? <!-- id:關(guān)聯(lián)查詢用戶的唯 一標(biāo)識(shí) ? ? ? ? column:指定唯 一標(biāo)識(shí)用戶信息的列 ? ? ? ? javaType:映射到user的哪個(gè)屬性 ? ? ? ? ?--> ? ? ? ? <id column="user_id" property="id"/> ? ? ? ? <result column="username" property="username"/> ? ? ? ? <result column="sex" property="sex"/> ? ? ? ? <result column="address" property="address"/> ? ?? ? ? </association> </resultMap>
3.關(guān)聯(lián)查詢(一對(duì)多)
resultMap的處理方式為在訂單表數(shù)據(jù)的pojo中添加一個(gè)list,list中為訂單明細(xì)表的屬性,在mapper.xml中采用如下的處理方式:
訂單及訂單明細(xì)的resultMap 使用extends繼承,不用在中配置訂單信息和用戶信息的映射
<resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersAndOrderDetailResultMap" extends="OrdersUserResultMap"> ?? ? <!- 訂單信息 --> ? ? <!- 用戶信息 --> ? ? <!- 使用extends繼承,不用在中配置訂單信息和用戶信息的映射 --> ? ? <!- 訂單明細(xì)信息 ? ? 一個(gè)訂單關(guān)聯(lián)查詢出了多條明細(xì),要使用collection進(jìn)行映射 ? ? collection:對(duì)關(guān)聯(lián)查詢到多條記錄映射到集合對(duì)象中 ? ? property:將關(guān)聯(lián)查詢到多條記錄映射到cn.itcast.mybatis.po.Orders哪個(gè)屬性 ? ? ofType:指定映射到list集合屬性中pojo的類型 ? ? ?--> ? ? ?<collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail"> ? ? ? ? ?<!-- id:訂單明細(xì)唯 一標(biāo)識(shí) ? ? ? ? ?property:要將訂單明細(xì)的唯 一標(biāo)識(shí) 映射到cn.itcast.mybatis.po.Orderdetail的哪個(gè)屬性 ? ? ? ? ? ?--> ? ? ? ? ?<id column="orderdetail_id" property="id"/> ? ? ? ? ?<result column="items_id" property="itemsId"/> ? ? ? ? ?<result column="items_num" property="itemsNum"/> ? ? ? ? ?<result column="orders_id" property="ordersId"/> ? ? ?</collection> ? ?? </resultMap>
樣例 student表(增刪改查)
?<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.qcby.dao.StudentMapper"> ? <resultMap id="BaseResultMap" type="com.qcby.entity.Student"> ? ? <id column="Sid" jdbcType="INTEGER" property="sid" /> ? ? <result column="Snum" jdbcType="VARCHAR" property="snum" /> ? ? <result column="Spassword" jdbcType="VARCHAR" property="spassword" /> ? ? <result column="Sname" jdbcType="VARCHAR" property="sname" /> ? ? <result column="Ssex" jdbcType="VARCHAR" property="ssex" /> ? ? <result column="Sgrade" jdbcType="VARCHAR" property="sgrade" /> ? ? <result column="Smajor" jdbcType="VARCHAR" property="smajor" /> ? </resultMap> ? <sql id="Base_Column_List"> ? ? Sid, Snum, Spassword, Sname, Ssex, Sgrade, Smajor ? </sql> ? <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap"> ? ? select? ? ? <include refid="Base_Column_List" /> ? ? from student ? ? where Sid = #{sid,jdbcType=INTEGER} ? </select> ? <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer"> ? ? delete from student ? ? where Sid = #{sid,jdbcType=INTEGER} ? </delete> ? <insert id="insert" parameterType="com.qcby.entity.Student"> ? ? insert into student (Sid, Snum, Spassword, ? ? ? Sname, Ssex, Sgrade,? ? ? ? Smajor) ? ? values (#{sid,jdbcType=INTEGER}, #{snum,jdbcType=VARCHAR}, #{spassword,jdbcType=VARCHAR},? ? ? ? #{sname,jdbcType=VARCHAR}, #{ssex,jdbcType=VARCHAR}, #{sgrade,jdbcType=VARCHAR},? ? ? ? #{smajor,jdbcType=VARCHAR}) ? </insert> ? <insert id="insertSelective" parameterType="com.qcby.entity.Student"> ? ? insert into student ? ? <trim prefix="(" suffix=")" suffixOverrides=","> ? ? ? <if test="sid != null"> ? ? ? ? Sid, ? ? ? </if> ? ? ? <if test="snum != null"> ? ? ? ? Snum, ? ? ? </if> ? ? ? <if test="spassword != null"> ? ? ? ? Spassword, ? ? ? </if> ? ? ? <if test="sname != null"> ? ? ? ? Sname, ? ? ? </if> ? ? ? <if test="ssex != null"> ? ? ? ? Ssex, ? ? ? </if> ? ? ? <if test="sgrade != null"> ? ? ? ? Sgrade, ? ? ? </if> ? ? ? <if test="smajor != null"> ? ? ? ? Smajor, ? ? ? </if> ? ? </trim> ? ? <trim prefix="values (" suffix=")" suffixOverrides=","> ? ? ? <if test="sid != null"> ? ? ? ? #{sid,jdbcType=INTEGER}, ? ? ? </if> ? ? ? <if test="snum != null"> ? ? ? ? #{snum,jdbcType=VARCHAR}, ? ? ? </if> ? ? ? <if test="spassword != null"> ? ? ? ? #{spassword,jdbcType=VARCHAR}, ? ? ? </if> ? ? ? <if test="sname != null"> ? ? ? ? #{sname,jdbcType=VARCHAR}, ? ? ? </if> ? ? ? <if test="ssex != null"> ? ? ? ? #{ssex,jdbcType=VARCHAR}, ? ? ? </if> ? ? ? <if test="sgrade != null"> ? ? ? ? #{sgrade,jdbcType=VARCHAR}, ? ? ? </if> ? ? ? <if test="smajor != null"> ? ? ? ? #{smajor,jdbcType=VARCHAR}, ? ? ? </if> ? ? </trim> ? </insert> ? <update id="updateByPrimaryKeySelective" parameterType="com.qcby.entity.Student"> ? ? update student ? ? <set> ? ? ? <if test="snum != null"> ? ? ? ? Snum = #{snum,jdbcType=VARCHAR}, ? ? ? </if> ? ? ? <if test="spassword != null"> ? ? ? ? Spassword = #{spassword,jdbcType=VARCHAR}, ? ? ? </if> ? ? ? <if test="sname != null"> ? ? ? ? Sname = #{sname,jdbcType=VARCHAR}, ? ? ? </if> ? ? ? <if test="ssex != null"> ? ? ? ? Ssex = #{ssex,jdbcType=VARCHAR}, ? ? ? </if> ? ? ? <if test="sgrade != null"> ? ? ? ? Sgrade = #{sgrade,jdbcType=VARCHAR}, ? ? ? </if> ? ? ? <if test="smajor != null"> ? ? ? ? Smajor = #{smajor,jdbcType=VARCHAR}, ? ? ? </if> ? ? </set> ? ? where Sid = #{sid,jdbcType=INTEGER} ? </update> ? <update id="updateByPrimaryKey" parameterType="com.qcby.entity.Student"> ? ? update student ? ? set Snum = #{snum,jdbcType=VARCHAR}, ? ? ? Spassword = #{spassword,jdbcType=VARCHAR}, ? ? ? Sname = #{sname,jdbcType=VARCHAR}, ? ? ? Ssex = #{ssex,jdbcType=VARCHAR}, ? ? ? Sgrade = #{sgrade,jdbcType=VARCHAR}, ? ? ? Smajor = #{smajor,jdbcType=VARCHAR} ? ? where Sid = #{sid,jdbcType=INTEGER} ? </update> ? <select id="stushow" ?resultMap="BaseResultMap"> ? ? select ? ? <include refid="Base_Column_List" /> ? ? from student ? </select> ? <select id="selectStuBySnum" parameterType="java.lang.String" resultType="com.qcby.entity.Student"> ? ? select ? ? <include refid="Base_Column_List" /> ? ? from student ? ? where Snum = #{Snum,jdbcType=VARCHAR} ? </select> ? <select id="selectStuLogin" parameterType="com.qcby.entity.Student" resultType="com.qcby.entity.Student"> ? ? select ? ? <include refid="Base_Column_List" /> ? ? from student ? ? where Snum = #{snum,jdbcType=VARCHAR} ? ? AND Spassword = #{spassword,jdbcType=VARCHAR} ? </select> </mapper>
注:什么時(shí)候必須加上 jdbcType
在 coding 的時(shí)候,有時(shí)候會(huì)發(fā)現(xiàn),比如在 User.xml 中,不管是用 userId = #{userId} 還是 userId = #{userId, jdbcType = Integer},都沒(méi)有問(wèn)題。但是什么時(shí)候必須要加上 jdbcType 呢?
Mybatis 的官方文檔是這樣描述 jdbcType 的 :
The JDBC Type from the list of supported types that follows this table. The JDBC type is only required for nullable columns upon insert, update or delete. This is a JDBC requirement, not a MyBatis one. So even if you were coding JDBC directly, you’d need to specify this type – but only for nullable values.
意思是說(shuō),只有當(dāng)將一個(gè)空值作用于插入、更新、刪除操作時(shí),jdbcType 才是必須的。這是 JDBC 的一個(gè)需求,并不是 MyBatis 的。所以即使你是直接編寫(xiě) JDBC,當(dāng)它是空的時(shí)候,你也一定要指定它的類型,其他情況不需要指定它的類型。
在 Stack Overflow 上,同樣有這樣的解釋:
Most of the times you don’t need to specify the jdbcType as MyBatis is smart enough to figure out the type from the objects you are working with. But if you send your parameters to the MyBatis statement inside a HashMap, for example, and one of the parameters is null, MyBatis won’t be able to determine the type of the parameter by looking at the HashMap because the HashMap is just a generic container and null itself carries no type information. At that point it would be o good idea to provide the jdbcType so that switching the database implementation later on does not cause any issues with null values.
就是說(shuō),在大部分時(shí)候,我們不需要指定 jdbcType,因?yàn)?MyBatis 足夠智能地可以辨別出對(duì)象的類型。
但是如果你傳過(guò)來(lái)的參數(shù)是一個(gè) HashMap,其中一個(gè)參數(shù)是空的,MyBatis 將不能通過(guò) HashMap 來(lái)決定對(duì)象的類型。
因?yàn)?HashMap 是一個(gè)通用的容器并且如果它本身是空的話,將不會(huì)攜帶任何的類型信息。
所以最好的做法是,當(dāng)值是空的時(shí)候去指定它的 jdbcType,這樣在之后轉(zhuǎn)換為 db 實(shí)現(xiàn)的時(shí)候就不會(huì)再引起任何問(wèn)題了。
jdbcType 和 javaType 的對(duì)應(yīng)關(guān)系
jdbcType | javaType |
---|---|
CHAR | String |
VARCHAR | String |
LONGVARCHAR | String |
NUMERIC | java.math.BigDecimal |
DECIMAL | java.math.BigDecimal |
BIT | boolean |
BOOLEAN | boolean |
TINYINT | byte |
SMALLINT | short |
INTEGER | int |
BIGINT | long |
REAL | float |
FLOAT | double |
DOUBLE | double |
BINARY | byte[] |
VARBINARY | byte[] |
LONGVARBINARY | byte[] |
DATE | java.sql.Date |
TIME | java.sql.Time |
TIMESTAMP | java.sql.Timestamp |
CLOB | Clob |
BLOB | Blob |
ARRAY | Array |
OTHER | |
UNDEFINED | |
NVARCHAR | |
NCHAR | |
NCLOB | |
CURSOR | |
NULL |
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
spring?mybatis環(huán)境常量與枚舉轉(zhuǎn)換示例詳解
這篇文章主要為大家介紹了spring?mybatis環(huán)境常量與枚舉轉(zhuǎn)換示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06SpringBoot實(shí)現(xiàn)異步的八種方法
Spring Boot 的異步處理主要是通過(guò)非阻塞I/O和回調(diào)機(jī)制來(lái)實(shí)現(xiàn)的,目的是提高應(yīng)用的并發(fā)性能,它支持多種方式來(lái)創(chuàng)建異步任務(wù),本文給大家介紹了SpringBoot實(shí)現(xiàn)異步的八種方法,需要的朋友可以參考下2024-07-07Spring?Boot?Admin集成與自定義監(jiān)控告警示例詳解
SpringBootAdmin是一個(gè)管理和監(jiān)控SpringBoot應(yīng)用程序的工具,可通過(guò)集成和配置實(shí)現(xiàn)應(yīng)用監(jiān)控與告警功能,本文給大家介紹Spring?Boot?Admin集成與自定義監(jiān)控告警示例詳解,感興趣的朋友跟隨小編一起看看吧2024-09-09SpringBoot Security整合JWT授權(quán)RestAPI的實(shí)現(xiàn)
這篇文章主要介紹了SpringBoot Security整合JWT授權(quán)RestAPI的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11詳解利用spring-security解決CSRF問(wèn)題
這篇文章主要介紹了詳解利用spring-security解決CSRF問(wèn)題,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-04-04Java實(shí)現(xiàn)整合文件上傳到FastDFS的方法詳細(xì)
FastDFS是一個(gè)開(kāi)源的輕量級(jí)分布式文件系統(tǒng),對(duì)文件進(jìn)行管理,功能包括:文件存儲(chǔ)、文件同步、文件上傳、文件下載等,解決了大容量存儲(chǔ)和負(fù)載均衡的問(wèn)題。本文將提供Java將文件上傳至FastDFS的示例代碼,需要的參考一下2022-02-02