數(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">
屬性 | 描述 |
---|---|
id
|
在命名空間中唯一的標(biāo)識(shí)符,可以被用來(lái)引用這條語(yǔ)句。 |
parameterType
|
將會(huì)傳入這條語(yǔ)句的參數(shù)的類全限定名或別名。這個(gè)屬性是可選的,因?yàn)?MyBatis 可以通過(guò)類型處理器(TypeHandler)推斷出具體傳入語(yǔ)句的參數(shù),默認(rèn)值為未設(shè)置(unset)。 |
parameterMap |
|
flushCache
|
將其設(shè)置為 true 后,只要語(yǔ)句被調(diào)用,都會(huì)導(dǎo)致本地緩存和二級(jí)緩存被清空,默認(rèn)值:(對(duì) insert、update 和 delete 語(yǔ)句)true。 |
timeout
|
這個(gè)設(shè)置是在拋出異常之前,驅(qū)動(dòng)程序等待數(shù)據(jù)庫(kù)返回請(qǐng)求結(jié)果的秒數(shù)。默認(rèn)值為未設(shè)置(unset)(依賴數(shù)據(jù)庫(kù)驅(qū)動(dòng))。 |
statementType
|
可選 STATEMENT,PREPARED 或 CALLABLE。這會(huì)讓 MyBatis 分別使用 Statement,PreparedStatement 或 CallableStatement,默認(rèn)值:PREPARED。 |
useGeneratedKeys
|
(僅適用于 insert 和 update)這會(huì)令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法來(lái)取出由數(shù)據(jù)庫(kù)內(nèi)部生成的主鍵(比如:像 MySQL 和 SQL Server 這樣的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng)的自動(dòng)遞增字段),默認(rèn)值:false。 |
keyProperty
|
(僅適用于 insert 和 update)指定能夠唯一識(shí)別對(duì)象的屬性,MyBatis 會(huì)使用 getGeneratedKeys 的返回值或 insert 語(yǔ)句的 selectKey 子元素設(shè)置它的值,默認(rèn)值:未設(shè)置(unset )。如果生成列不止一個(gè),可以用逗號(hào)分隔多個(gè)屬性名稱。 |
keyColumn
|
(僅適用于 insert 和 update)設(shè)置生成鍵值在表中的列名,在某些數(shù)據(jù)庫(kù)(像 PostgreSQL)中,當(dāng)主鍵列不是表中的第一列的時(shí)候,是必須設(shè)置的。如果生成列不止一個(gè),可以用逗號(hào)分隔多個(gè)屬性名稱。 |
databaseId
|
如果配置了數(shù)據(jù)庫(kù)廠商標(biāo)識(shí)(databaseIdProvider),MyBatis 會(huì)加載所有不帶 databaseId 或匹配當(dāng)前 databaseId 的語(yǔ)句;如果帶和不帶的語(yǔ)句都有,則不帶的會(huì)被忽略。 |
下面是 insert,update 和 delete 語(yǔ)句的示例:
<insert id="insertAuthor">
insert into Author (id,username,password,email,bio)
values (#{id},#{username},#{password},#{email},#{bio})
</insert>
<update id="updateAuthor">
update Author set
username = #{username},
password = #{password},
email = #{email},
bio = #{bio}
where id = #{id}
</update>
<delete id="deleteAuthor">
delete from Author where id = #{id}
</delete>
如前所述,插入語(yǔ)句的配置規(guī)則更加豐富,在插入語(yǔ)句里面有一些額外的屬性和子元素用來(lái)處理主鍵的生成,并且提供了多種生成方式。
首先,如果你的數(shù)據(jù)庫(kù)支持自動(dòng)生成主鍵的字段(比如 MySQL 和 SQL Server),那么你可以設(shè)置 ?useGeneratedKeys=”true”
?,然后再把 ?keyProperty
設(shè)置為目標(biāo)屬性就 OK 了。例如,如果上面的 Author 表已經(jīng)在 id 列上使用了自動(dòng)生成,那么語(yǔ)句可以修改為:
<insert id="insertAuthor" useGeneratedKeys="true"
keyProperty="id">
insert into Author (username,password,email,bio)
values (#{username},#{password},#{email},#{bio})
</insert>
如果你的數(shù)據(jù)庫(kù)還支持多行插入, 你也可以傳入一個(gè) Author 數(shù)組或集合,并返回自動(dòng)生成的主鍵。
<insert id="insertAuthor" useGeneratedKeys="true"
keyProperty="id">
insert into Author (username, password, email, bio) values
<foreach item="item" collection="list" separator=",">
(#{item.username}, #{item.password}, #{item.email}, #{item.bio})
</foreach>
</insert>
對(duì)于不支持自動(dòng)生成主鍵列的數(shù)據(jù)庫(kù)和可能不支持自動(dòng)生成主鍵的 JDBC 驅(qū)動(dòng),MyBatis 有另外一種方法來(lái)生成主鍵。
這里有一個(gè)簡(jiǎn)單(也很傻)的示例,它可以生成一個(gè)隨機(jī) ID(不建議實(shí)際使用,這里只是為了展示 MyBatis 處理問(wèn)題的靈活性和寬容度):
<insert id="insertAuthor">
<selectKey keyProperty="id" resultType="int" order="BEFORE">
select CAST(RANDOM()*1000000 as INTEGER) a from SYSIBM.SYSDUMMY1
</selectKey>
insert into Author
(id, username, password, email,bio, favourite_section)
values
(#{id}, #{username}, #{password}, #{email}, #{bio}, #{favouriteSection,jdbcType=VARCHAR})
</insert>
在上面的示例中,首先會(huì)運(yùn)行 selectKey 元素中的語(yǔ)句,并設(shè)置 Author 的 id,然后才會(huì)調(diào)用插入語(yǔ)句。這樣就實(shí)現(xiàn)了數(shù)據(jù)庫(kù)自動(dòng)生成主鍵類似的行為,同時(shí)保持了 Java 代碼的簡(jiǎn)潔。
selectKey 元素描述如下:
<selectKey
keyProperty="id"
resultType="int"
order="BEFORE"
statementType="PREPARED">
屬性 | 描述 |
---|---|
keyProperty
|
selectKey 語(yǔ)句結(jié)果應(yīng)該被設(shè)置到的目標(biāo)屬性。如果生成列不止一個(gè),可以用逗號(hào)分隔多個(gè)屬性名稱。 |
keyColumn
|
返回結(jié)果集中生成列屬性的列名。如果生成列不止一個(gè),可以用逗號(hào)分隔多個(gè)屬性名稱。 |
resultType
|
結(jié)果的類型。通常 MyBatis 可以推斷出來(lái),但是為了更加準(zhǔn)確,寫上也不會(huì)有什么問(wèn)題。MyBatis 允許將任何簡(jiǎn)單類型用作主鍵的類型,包括字符串。如果生成列不止一個(gè),則可以使用包含期望屬性的 Object 或 Map。 |
order
|
可以設(shè)置為 BEFORE 或 AFTER 。如果設(shè)置為 BEFORE ,那么它首先會(huì)生成主鍵,設(shè)置 keyProperty 再執(zhí)行插入語(yǔ)句。如果設(shè)置為 AFTER ,那么先執(zhí)行插入語(yǔ)句,然后是 selectKey 中的語(yǔ)句 - 這和 Oracle 數(shù)據(jù)庫(kù)的行為相似,在插入語(yǔ)句內(nèi)部可能有嵌入索引調(diào)用。 |
statementType
|
和前面一樣,MyBatis 支持 STATEMENT ,PREPARED 和 CALLABLE 類型的映射語(yǔ)句,分別代表 Statement , PreparedStatement 和 CallableStatement 類型。 |
這個(gè)元素可以用來(lái)定義可重用的 SQL 代碼片段,以便在其它語(yǔ)句中使用。 參數(shù)可以靜態(tài)地(在加載的時(shí)候)確定下來(lái),并且可以在不同的 include 元素中定義不同的參數(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>
也可以在 include 元素的 refid 屬性或內(nèi)部語(yǔ)句中使用屬性值,例如:
<sql id="sometable">
${prefix}Table
</sql>
<sql id="someinclude">
from
<include refid="${include_target}"/>
</sql>
<select id="select" resultType="map">
select
field1, field2, field3
<include refid="someinclude">
<property name="prefix" value="Some"/>
<property name="include_target" value="sometable"/>
</include>
</select>
更多建議: