基于Mybatis的配置文件入門必看篇
Mybatis 配置文件入門
從這篇文章開始,我們將從其核心配置文件入手,對(duì)Mybatis支持的核心配置文件進(jìn)行簡(jiǎn)單詳細(xì)的描述。
從下面這段代碼是我們?cè)谑褂胢ybatis前的配置初始化過(guò)程
我們通過(guò)閱讀其源碼來(lái)逐步了解內(nèi)部實(shí)現(xiàn)原理。
// Mybatis 通過(guò)SqlSessionFactory獲取SqlSession, 然后才能通過(guò)SqlSession與數(shù)據(jù)庫(kù)進(jìn)行交互 private static SqlSessionFactory getSessionFactory() { SqlSessionFactory sessionFactory = null; String resource = "configuration.xml"; try { sessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader(resource)); } catch (IOException e) { e.printStackTrace(); } return sessionFactory; }
我們進(jìn)入到SqlSessionFactoryBuilder類里面
查看其源碼:
/** * Copyright 2009-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.ibatis.session; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.util.Properties; import org.apache.ibatis.builder.xml.XMLConfigBuilder; import org.apache.ibatis.exceptions.ExceptionFactory; import org.apache.ibatis.executor.ErrorContext; import org.apache.ibatis.session.defaults.DefaultSqlSessionFactory; /** * Builds {@link SqlSession} instances. * * @author Clinton Begin */ public class SqlSessionFactoryBuilder { public SqlSessionFactory build(Reader reader) { return build(reader, null, null); } public SqlSessionFactory build(Reader reader, String environment) { return build(reader, environment, null); } public SqlSessionFactory build(Reader reader, Properties properties) { return build(reader, null, properties); } public SqlSessionFactory build(Reader reader, String environment, Properties properties) { try { XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties); return build(parser.parse()); } catch (Exception e) { throw ExceptionFactory.wrapException("Error building SqlSession.", e); } finally { ErrorContext.instance().reset(); try { reader.close(); } catch (IOException e) { // Intentionally ignore. Prefer previous error. } } } public SqlSessionFactory build(InputStream inputStream) { return build(inputStream, null, null); } public SqlSessionFactory build(InputStream inputStream, String environment) { return build(inputStream, environment, null); } public SqlSessionFactory build(InputStream inputStream, Properties properties) { return build(inputStream, null, properties); } public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) { try { XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties); return build(parser.parse()); } catch (Exception e) { throw ExceptionFactory.wrapException("Error building SqlSession.", e); } finally { ErrorContext.instance().reset(); try { inputStream.close(); } catch (IOException e) { // Intentionally ignore. Prefer previous error. } } } public SqlSessionFactory build(Configuration config) { return new DefaultSqlSessionFactory(config); } }
在這個(gè)類中,支持多種構(gòu)造SqlSessionFactory的方法。可以只傳入mybatis配置文件,也可以同時(shí)傳入properties配置文件替代mybatis配置文件中的<properties>元素標(biāo)簽,另外也支持傳入環(huán)境參數(shù)envirmont參數(shù)。
我們跟隨著源碼繼續(xù)往下看:
public SqlSessionFactory build(Reader reader, String environment, Properties properties) { try { XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties); return build(parser.parse()); } catch (Exception e) { throw ExceptionFactory.wrapException("Error building SqlSession.", e); } finally { ErrorContext.instance().reset(); try { reader.close(); } catch (IOException e) { // Intentionally ignore. Prefer previous error. } } }
這里創(chuàng)建了一個(gè)XMLConfigBuilder類實(shí)例,通過(guò)他來(lái)對(duì)mybatis配置文件(一個(gè)xml配置文件)進(jìn)行解析。
解析的代碼入口如下所示:
public Configuration parse() { if (parsed) { throw new BuilderException("Each XMLConfigBuilder can only be used once."); } parsed = true; parseConfiguration(parser.evalNode("/configuration")); return configuration; } private void parseConfiguration(XNode root) { try { Properties settings = settingsAsPropertiess(root.evalNode("settings")); //issue #117 read properties first propertiesElement(root.evalNode("properties")); loadCustomVfs(settings); typeAliasesElement(root.evalNode("typeAliases")); pluginElement(root.evalNode("plugins")); objectFactoryElement(root.evalNode("objectFactory")); objectWrapperFactoryElement(root.evalNode("objectWrapperFactory")); reflectorFactoryElement(root.evalNode("reflectorFactory")); settingsElement(settings); // read it after objectFactory and objectWrapperFactory issue #631 environmentsElement(root.evalNode("environments")); databaseIdProviderElement(root.evalNode("databaseIdProvider")); typeHandlerElement(root.evalNode("typeHandlers")); mapperElement(root.evalNode("mappers")); } catch (Exception e) { throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e); } }
從這里看出,配置文件是以configuration為根節(jié)點(diǎn),在根節(jié)點(diǎn)之下有多個(gè)子節(jié)點(diǎn),它們分別為:settings、properties、typeAliases、plugins、objectFactory、objectWrapperFactory、environments、databaseIdProvider、typeHandlers、mappers。
MyBatis核心配置文件標(biāo)簽簡(jiǎn)介
XML 映射配置文件
MyBatis
的配置文件包含了影響MyBatis行為甚深的設(shè)置(settings)和屬性(properties)信息。文檔的頂層結(jié)果如下:
configuration
配置
properties
屬性
setting
設(shè)置
typeAliases
類型命名
typeHandlers
類型處理器
objectFactory
對(duì)象工廠
plugins
插件
environments
環(huán)境
environment
環(huán)境變量
transactionManager
事務(wù)管理器
dataSource
數(shù)據(jù)源
databaseIdProyider
數(shù)據(jù)庫(kù)廠商標(biāo)識(shí)
mappers
映射
properties
屬性都是可外部配置且可動(dòng)態(tài)替換的,既可以在典型的Java屬性文件中配置,亦可通過(guò)properties元素的子元素來(lái)傳遞。
例如:
<!-- mybatis的核心配置文件 1.數(shù)據(jù)庫(kù)的連接信息(連接池) --> <properties resource="jdbc.properties"></properties>
其中的屬性就可以在整個(gè)配置文件中使用來(lái)替換需要?jiǎng)討B(tài)配置的屬性值。
比如:
<!-- 默認(rèn)連接池 --> <dataSource type="POOLED"> <property name="driver" value="${driverClass}"/> <property name="url" value="${url}"/> <property name="username" value="${userid}"/> <property name="password" value="${password}"/> </dataSource>
properties
屬性:將數(shù)據(jù)庫(kù)連接參數(shù)單獨(dú)配置在jdbc.properties中,只需要在mybatis.xml文件中加載jdbc.properties的屬性值。 在mybatis.xml中就不需要對(duì)數(shù)據(jù)庫(kù)連接參數(shù)硬編碼(硬編碼是指將可變變量用一個(gè)固定值來(lái)代替的方法)。在properties 元素體內(nèi)定義的屬性首先被讀取。然后會(huì)讀取properties元素中resource或url加載屬性,它會(huì)覆蓋已讀取的同名屬性。
注意:如果在properties標(biāo)簽里面定義的屬性被${}所引用了,對(duì)#{}不管用。那么它不會(huì)讀取parameterType里面的參數(shù)值。比如properties里面定義了id屬性,值為40,在映射文件中引用該值,${id}那么我從parameterType里面?zhèn)髦禃r(shí),不管我傳基本類型還是引用類型進(jìn)去都不會(huì)覆蓋這個(gè)${id}值。始終都會(huì)讀取40.
屬性也可以被傳遞到SqlSessionBuilder.build()方法中。
例如:
SqlSessionFactoryBuilder
源碼:
public SqlSessionFactory build(Reader reader, Properties properties) { return build(reader, null, properties); } public SqlSessionFactory build(Reader reader, String environment, Properties properties) { try { XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties); return build(parser.parse()); } catch (Exception e) { throw ExceptionFactory.wrapException("Error building SqlSession.", e); } finally { ErrorContext.instance().reset(); try { reader.close(); } catch (IOException e) { // Intentionally ignore. Prefer previous error. } } }
typeAliases
類型別名是為Java類型設(shè)置一個(gè)短的名字。它只和XML配置有關(guān),存在意義僅在于用來(lái)減少類完全限定名的冗余。
例如:
<!-- 給類定義別名 --> <typeAliases> <typeAlias type="cn.et.lesson02.annotion.Food" alias="food"/> <typeAlias alias="Author" type="domain.blog.Author"/> <typeAlias alias="Blog" type="domain.blog.Blog"/> </typeAliases>
當(dāng)這樣配置時(shí),Blog可以用在任何使用domain.blog.Blog的地方。
也可以指定一個(gè)包名,MyBatis會(huì)在包名下面搜索需要的Java Bean
比如:
<typeAliases> <package name="domain.blog"/> </typeAliases>
每一個(gè)包domain.blog中的Java Bean,在沒(méi)有注解的情況下,會(huì)使用Bean的首字母小寫的非限定類名來(lái)作為它的別名。比如domain.blog.Author的別名為author;若有注解,則別名為其注解值。
看下面的例子:
@Alias("author") public class Author { ... }
mapper
標(biāo)簽(映射配置):加載映射文件
<mappers> <!-- 通過(guò)resource加載單個(gè)映射文件 加載單個(gè)類路徑下的映射文件 使用相對(duì)于類路徑的資源: --> <mapper resource="cn/et/lesson01/FoodMapper.xml"/> <!-- 使用類路徑加載單個(gè)映射文件 <mapper url="cn.domarvel.dao.UserMapper"/> 注意:此種方法要求mapper接口名稱和mapper映射文件名稱相同,且放在同一個(gè)目錄中。并且還有一個(gè)前提是:使用的是mapper代理方法 --> <!-- 自動(dòng)批量加載指定包下的所有Mapper接口配置文件 <package name="cn.domarvel.dao"/> 注意:此種方法要求mapper接口名稱和mapper映射文件名稱相同,且放在同一個(gè)目錄中。并且還有一個(gè)前提是:使用的是mapper代理方法 --> </mappers>
Mapper XML文件
MyBatis的真正強(qiáng)大在于他的映射語(yǔ)句,也是它的魔力所在,由于它的異常強(qiáng)大,映射器的XML文件就顯得相對(duì)簡(jiǎn)單。如果拿它跟具有相同功能的JDBC代碼進(jìn)行對(duì)比,你會(huì)立即發(fā)現(xiàn)省掉了將近95%的代碼。MyBatis就是針對(duì)SQL構(gòu)建的,并且比普通的方法做的更好。
mapper
標(biāo)簽:映射文件的根節(jié)點(diǎn),在根節(jié)點(diǎn)中支持九個(gè)元素。
namespace是用于綁定Dao接口的,當(dāng)你的namespace綁定接口后,你可以不用寫接口實(shí)現(xiàn)類,mybatis會(huì)通過(guò)該綁定自動(dòng)幫你找到對(duì)應(yīng)要執(zhí)行的SQL語(yǔ)句
注意:接口中的方法與映射文件中的SQL語(yǔ)句的ID一一對(duì)應(yīng)
<mapper namespace="a"> </mapper> <mapper namespace="cn.et.lesson02.xml.FoodMapper" > </mapper>
SQL映射文件有很少的幾個(gè)頂級(jí)元素(按照它們應(yīng)該被定義的順序):
cache
:給定命名空間的緩存配置
cache-ref
:其命名空間緩存配置的引用。
resultMap
:是最復(fù)雜也是最強(qiáng)大的元素,用來(lái)描述如何從數(shù)據(jù)庫(kù)結(jié)果集中來(lái)加載對(duì)象。
parameterMap
:已廢棄,老式風(fēng)格的參數(shù)映射。內(nèi)聯(lián)參數(shù)是首選,這個(gè)元素可能在將來(lái)被移除,這里不會(huì)記錄。
sql
:可被其他語(yǔ)句引用的可重用語(yǔ)句塊。
insert
:映射插入語(yǔ)句
update
:映射更新語(yǔ)句
delete
:映射更新語(yǔ)句
select
:映射查詢語(yǔ)句
select
查詢語(yǔ)句是MyBatis中最常用的元素之一,光能把數(shù)據(jù)存到數(shù)據(jù)庫(kù)中價(jià)值并不大,如果還能重新取出來(lái)才有用,多數(shù)應(yīng)用也都是查詢比修改要頻繁。對(duì)每個(gè)插入、更新或刪除操作,通常對(duì)應(yīng)多個(gè)查詢操作。這是MyBatis的基本原則之一,也是將焦點(diǎn)和努力放在查詢和結(jié)果映射的原因。簡(jiǎn)單查詢的select元素時(shí)非常簡(jiǎn)單的。
比如
<select id="selectPerson" parameterType="int" resultType="hashmap"> SELECT * FROM PERSON WHERE ID = #{id} </select>
這個(gè)語(yǔ)句被稱作selectPerson,接收一個(gè)int(或Integer)類型的參數(shù),并返回一個(gè)HashMap類型的對(duì)象,其中的鍵是列名,值便是結(jié)果行中的對(duì)應(yīng)值。
注意參數(shù)符號(hào):#{id}
select元素有很多屬性允許你配置,來(lái)決定每條語(yǔ)句的作用細(xì)節(jié)。
SELECT多條件查詢
parameterType用于傳遞參數(shù)多參數(shù)可以使用傳入對(duì)象以及map的方式傳遞多個(gè)參數(shù)。
#{}表示傳遞的參數(shù)值 類同jdbc的? ${}表示直接將參數(shù)值替換類同'%值%'
比如:
<select id=“selectPerson” parameterType=“map” resultType=“person”> SELECT * FROM PERSON WHERE ID = #{id} and name like ‘%${name}%' </select>
Map中必須存在id和name的鍵值對(duì)
SELECT調(diào)用存儲(chǔ)過(guò)程
創(chuàng)建存儲(chǔ)過(guò)程prg_add(p1 in number,p2 in number,p3 out number)
Mybatis映射文件中使用select調(diào)用存儲(chǔ)過(guò)程
<select id=“prgAdd" statementType="CALLABLE"> <![CDATA[ {call pro_hello ( #{p1,mode=IN,jdbcType=NUMBER}, #{p2,mode=IN,jdbcType=NUMBER}, #{result,mode=OUT,jdbcType=NUMBER})} ]]> </select>
測(cè)試調(diào)用過(guò)程
Map<String, String> param = new HashMap<String, String>(); param.put(“p1”, 1); param.put(“p2”, 2); String returnValue = (String) session.selectOne(" prgAdd ", param); System.out.println("result=" + param.get("result")); System.out.println("returnValue=" + returnValue);
insert、update和delete
數(shù)據(jù)更變語(yǔ)句insert、update和delete的實(shí)現(xiàn)非常接近
<insert id="insertAuthor" parameterType="domain.blog.Author" flushCache="true" statementType="PREPARED" keyProperty="" keyColumn="" useGeneratedKeys="" timeout="20"> <update id="updateAuthor" parameterType="domain.blog.Author" flushCache="true" statementType="PREPARED" timeout="20"> <delete id="deleteAuthor" parameterType="domain.blog.Author" flushCache="true" statementType="PREPARED" timeout="20">
insert、update和delete參數(shù)
parameterType
:入?yún)⒌娜薅惷蝾愋蛣e名
keyColumn
:設(shè)置數(shù)據(jù)表自動(dòng)生成的主鍵名。對(duì)特定數(shù)據(jù)庫(kù)(如PostgreSQL),若自動(dòng)生成的主鍵不是第一個(gè)字段則必須設(shè)置
keyProperty
:默認(rèn)值unset,用于設(shè)置getGeneratedKeys方法或selectKey子元素返回值將賦值到領(lǐng)域模型的哪個(gè)屬性中
useGeneratedKey
:取值范圍true|false(默認(rèn)值)設(shè)置是否使用JDBC的getGenereatedKeys方法獲取主鍵并賦值到keyProperty設(shè)置的領(lǐng)域模型屬性中。
MySQL和SQLServer執(zhí)行auto-generated key field,因此當(dāng)數(shù)據(jù)庫(kù)設(shè)置好自增長(zhǎng)主鍵后,可通過(guò)JDBC的getGeneratedKeys方法獲取。但像Oralce等不支持auto-generated key field的數(shù)據(jù)庫(kù)就不能用這種方法獲取主鍵了
flushCache
:取值范圍true(默認(rèn)值)|false,設(shè)置執(zhí)行該操作后是否會(huì)清空二級(jí)緩存和本地緩存
timeout
:默認(rèn)為unset(依賴jdbc驅(qū)動(dòng)器的設(shè)置),設(shè)置執(zhí)行該操作的最大時(shí)限,超時(shí)將拋異常
databaseId
:取值范圍oracle|mysql等,表示數(shù)據(jù)庫(kù)廠家,元素內(nèi)部可通過(guò)`<if test="_databaseId = 'oracle'">`來(lái)為特定數(shù)據(jù)庫(kù)指定不同的sql語(yǔ)句
selectKey
對(duì)于不支持自動(dòng)生成類型的數(shù)據(jù)庫(kù)或可能不支持自動(dòng)生成主鍵JDBC驅(qū)動(dòng)來(lái)說(shuō),MyBatis有另外一種方法來(lái)生成主鍵。
這里有一個(gè)簡(jiǎn)單的示例,它可以生成一個(gè)隨機(jī)ID(最好不要這么做,但這里展示了MyBatis處理問(wèn)題的靈活性及其所關(guān)心的廣度):
<insert id="saveFood" > <!-- selectKey 在Mybatis中是為了解決Insert數(shù)據(jù)時(shí)不支持主鍵自動(dòng)生成的問(wèn)題,他可以很隨意的設(shè)置生成主鍵的方式。 SelectKey需要注意order屬性,像Mysql一類支持自動(dòng)增長(zhǎng)類型的數(shù)據(jù)庫(kù)中, order需要設(shè)置為after才會(huì)取到正確的值。像Oracle這樣取序列的情況,需要設(shè)置為before,否則會(huì)報(bào)錯(cuò)。 keyProperty:selectKey 語(yǔ)句結(jié)果應(yīng)該被設(shè)置的目標(biāo)屬性。 order:可設(shè)置為 BEFORE 或 AFTER,如果設(shè)置為 BEFORE,那么它會(huì)首先選擇主鍵,設(shè)置 keyProperty 然后執(zhí)行插入語(yǔ)句。 如果設(shè)置為 AFTER,那么先執(zhí)行插入語(yǔ)句,然后是 執(zhí)行selectKey元素 statementType:和前面的相 同,MyBatis 支持 STATEMENT ,PREPARED 和CALLABLE 語(yǔ)句的映射類型, 分別代表 PreparedStatement 和CallableStatement 類型。 注意:selectKey操作會(huì)將操作查詢結(jié)果賦值到insert元素的parameterType的入?yún)?shí)例下對(duì)應(yīng)的屬性中。并提供給insert語(yǔ)句使用 --> <selectKey keyProperty="foodId" order="BEFORE" resultType="int" statementType="STATEMENT"> select FOOD_SEC.Nextval from dual </selectKey> insert into food values(#{foodId},#{foodName},#{price}) </insert>
在上面的示例中,selectKey元素將會(huì)首先運(yùn)行,food的id會(huì)被設(shè)置,然后插入語(yǔ)句會(huì)被調(diào)用,這給了你一個(gè)和數(shù)據(jù)庫(kù)中來(lái)處理自動(dòng)生成的主鍵類似的行為,避免了使Java代碼變得復(fù)雜
SQL
這個(gè)元素可以被用來(lái)定義可重用的SQL代碼段,可以包含在其他語(yǔ)句中,它可以被靜態(tài)地(在加載參數(shù))參數(shù)化,不同的屬性值太高包含的實(shí)例變化。
比如:
<sql id="userColumns"> ${alias}.id,${alias}.username,${alias}.password </sql>
這個(gè)SQL片段可以被包含在其他語(yǔ)句中,例如:
<select id="selectUsers" resultType="map"> select <include refid="userColumns"> <property name="alias" value="t1"/></include>, <include refid="userColumns"><property name="alias" value="t2"/> </include> from some_table t1 cross join some_table t2 </select>
屬性值可以用于包含的refid屬性或者包含的字句里面的屬性值。
Result Map
resultMap 元素時(shí)MyBatis中最重要最強(qiáng)大的元素。它就是讓你遠(yuǎn)離90%的需要從結(jié)果集中取出數(shù)據(jù)的JDBC代碼的那個(gè)東西,而且在一些情形下允許你做一些JDBC不支持的事情。事實(shí)上,編寫相似于對(duì)復(fù)雜語(yǔ)句聯(lián)合映射這些等同的代碼,也許可以跨過(guò)上千行的代碼。ResultMap的設(shè)計(jì)就是簡(jiǎn)單語(yǔ)句不需要明確的結(jié)果映射,而很多復(fù)雜語(yǔ)句確實(shí)需要描述它們的關(guān)系。
<!-- resultMap 基本作用:建立SQL查詢結(jié)果字段與實(shí)體屬性的映射關(guān)系 屬性 id屬性 ,resultMap標(biāo)簽的標(biāo)識(shí)。 type屬性 ,返回值的全限定類名,或類型別名。 autoMapping 屬性 ,值范圍true(默認(rèn)值)|false,設(shè)置是否啟動(dòng)自動(dòng)映射功能, 自動(dòng)映射功能就是自動(dòng)查找與字段名小寫同名的屬性名,并調(diào)用setter方法。而設(shè)置為false后, 則需要在resultMap內(nèi)明確注明映射關(guān)系才會(huì)調(diào)用對(duì)應(yīng)的setter方法。 子元素: id元素 ,用于設(shè)置主鍵字段與領(lǐng)域模型屬性的映射關(guān)系 result元素 ,用于設(shè)置普通字段與領(lǐng)域模型屬性的映射關(guān)系 property 需要映射到JavaBean 的屬性名稱。 column 數(shù)據(jù)表的列名或者標(biāo)簽別名。 javaType 一個(gè)完整的類名,或者是一個(gè)類型別名。如果你匹配的是一個(gè)JavaBean, 那MyBatis 通常會(huì)自行檢測(cè)到。然后,如果你是要映射到一個(gè)HashMap, 那你需要指定javaType 要達(dá)到的目的。 jdbcType 數(shù)據(jù)表支持的類型列表。這個(gè)屬性只在insert,update 或delete 的時(shí)候針對(duì)允許空的列有用。 JDBC 需要這項(xiàng),但MyBatis 不需要。如果你是直接針對(duì)JDBC 編碼,且有允許空的列,而你要指定這項(xiàng)。 typeHandler 使用這個(gè)屬性可以覆寫類型處理器。這項(xiàng)值可以是一個(gè)完整的類名,也可以是一個(gè)類型別名。 association聯(lián)合 聯(lián)合元素用來(lái)處理“一對(duì)一”的關(guān)系。需要指定映射的Java實(shí)體類的屬性,屬性的javaType(通常MyBatis 自己會(huì)識(shí)別)。 對(duì)應(yīng)的數(shù)據(jù)庫(kù)表的列名稱。如果想覆寫的話返回結(jié)果的值,需要指定typeHandler。 不同情況需要告訴MyBatis 如何加載一個(gè)聯(lián)合。MyBatis 可以用兩種方式加載: select: 執(zhí)行一個(gè)其它映射的SQL 語(yǔ)句返回一個(gè)Java實(shí)體類型。較靈活; resultsMap: 使用一個(gè)嵌套的結(jié)果映射來(lái)處理通過(guò)join查詢結(jié)果集,映射成Java實(shí)體類型。 --> <resultMap type="grade" id="gradeMap" autoMapping="true" > <!-- 因?yàn)?autoMapping="false"(默認(rèn)是true) 所以要明確注明映射關(guān)系 如果為true則會(huì)自動(dòng)映射 不需要寫下面這行代碼 <result column="gid" property="gid"/> 還有下面這種方法 需要gid為主鍵的情況下使用 列和屬性的關(guān)系 主鍵使用id 非主鍵使用result <id column="gid" property="gid"/> --> <!-- 將查詢的結(jié)果gname賦給gname1 --> <id column="gid" property="gid"/> <result column="gname" property="gname"/> </resultMap>
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
淺談Spring Boot 整合ActiveMQ的過(guò)程
本篇文章主要介紹了淺談Spring Boot 整合ActiveMQ的過(guò)程,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12Spring啟動(dòng)過(guò)程源碼分析及簡(jiǎn)介
本文是通過(guò)AnnotationConfigApplicationContext讀取配置類來(lái)一步一步去了解Spring的啟動(dòng)過(guò)程。本文重點(diǎn)給大家介紹Spring啟動(dòng)過(guò)程源碼分析及基本概念,感興趣的朋友一起看看吧2021-10-10解決springboot application.properties server.port配置問(wèn)題
這篇文章主要介紹了解決springboot application.properties server.port配置問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08Maven的生命周期與自定義插件實(shí)現(xiàn)方法
Maven的生命周期就是對(duì)所有的構(gòu)建過(guò)程進(jìn)行抽象和統(tǒng)一。包含了項(xiàng)目的清理、初始化、編譯、測(cè)試、打包、集成測(cè)試、驗(yàn)證、部署和站點(diǎn)生成等幾乎所有的構(gòu)建步驟2022-12-12spring AOP實(shí)現(xiàn)@Around輸出請(qǐng)求參數(shù)和返回參數(shù)
這篇文章主要介紹了spring AOP實(shí)現(xiàn)@Around輸出請(qǐng)求參數(shù)和返回參數(shù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02