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

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - Java教程 - MyBatis直接執(zhí)行SQL的工具SqlMapper

MyBatis直接執(zhí)行SQL的工具SqlMapper

2021-06-24 10:56isea533 Java教程

今天小編就為大家分享一篇關(guān)于MyBatis直接執(zhí)行SQL的工具SqlMapper,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧

可能有些人也有過(guò)類似需求,一般都會(huì)選擇使用其他的方式如spring-jdbc等方式解決。

能否通過(guò)mybatis實(shí)現(xiàn)這樣的功能呢?

為了讓通用mapper更徹底的支持多表操作以及更靈活的操作,在2.2.0版本增加了一個(gè)可以直接執(zhí)行sql的新類sqlmapper。

我們來(lái)了解一下sqlmapper。

sqlmapper提供的方法

sqlmapper提供了以下這些公共方法:

  • map<string,object> selectone(string sql)
  • map<string,object> selectone(string sql, object value)
  • <t> t selectone(string sql, class<t> resulttype)
  • <t> t selectone(string sql, object value, class<t> resulttype)
  • list<map<string,object>> selectlist(string sql)
  • list<map<string,object>> selectlist(string sql, object value)
  • <t> list<t> selectlist(string sql, class<t> resulttype)
  • <t> list<t> selectlist(string sql, object value, class<t> resulttype)
  • int insert(string sql)
  • int insert(string sql, object value)
  • int update(string sql)
  • int update(string sql, object value)
  • int delete(string sql)
  • int delete(string sql, object value)

一共14個(gè)方法,這些方法的命名和參數(shù)和sqlsession接口的很像,只是基本上第一個(gè)參數(shù)都成了sql。

其中object value為入?yún)ⅲ雲(yún)⑿问胶蛃qlsession中的入?yún)⒁粯樱瑤в腥雲(yún)⒌姆椒ǎ谑褂脮r(shí)sql可以包含#{param}或${param}形式的參數(shù),這些參數(shù)需要通過(guò)入?yún)?lái)傳值。需要的參數(shù)過(guò)多的時(shí)候,參數(shù)可以使用map類型。另外這種情況下的sql還支持下面這種復(fù)雜形式:

?
1
2
string sql = "<script>select * from sys_user where 1=1" +
    "<if test=\"usertype != null\">usertype = #{usertype}</if></script>";

這種情況用的比較少,不多說(shuō)。

不帶有object value的所有方法,sql中如果有參數(shù)需要手動(dòng)拼接成一個(gè)可以直接執(zhí)行的sql語(yǔ)句。

在selectxxx方法中,使用class<t> resulttype可以指定返回類型,否則就是map<string,object>類型。

實(shí)例化sqlmapper

sqlmapper構(gòu)造參數(shù)public sqlmapper(sqlsession sqlsession),需要一個(gè)入?yún)qlsession sqlsession,在一般系統(tǒng)中,可以按照下面的方式獲取:

?
1
2
3
sqlsession sqlsession = (...);//通過(guò)某些方法獲取sqlsession
//創(chuàng)建sqlmapper
sqlmapper sqlmapper = new sqlmapper(sqlsession);

如果使用的spring,那么可以按照下面的方式配置<bean>:

?
1
2
3
<bean id="sqlmapper" class="com.github.abel533.sql.sqlmapper" scope="prototype">
 <constructor-arg ref="sqlsession"/>
</bean>

在service中使用的時(shí)候可以直接使用@autowired注入。

簡(jiǎn)單例子

在src/test/java目錄的com.github.abel533.sql包中包含這些方法的測(cè)試。

下面挑幾個(gè)看看如何使用。

selectlist

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//查詢,返回list<map>
list<map<string, object>> list = sqlmapper.selectlist("select * from country where id < 11");
//查詢,返回指定的實(shí)體類
list<country> countrylist = sqlmapper.selectlist("select * from country where id < 11", country.class);
//查詢,帶參數(shù)
countrylist = sqlmapper.selectlist("select * from country where id < #{id}", 11, country.class);
//復(fù)雜點(diǎn)的查詢,這里參數(shù)和上面不同的地方,在于傳入了一個(gè)對(duì)象
country country = new country();
country.setid(11);
countrylist = sqlmapper.selectlist("<script>" +
    "select * from country " +
    "  <where>" +
    "    <if test=\"id != null\">" +
    "      id < #{id}" +
    "    </if>" +
    "  </where>" +
    "</script>", country, country.class);

selectone

?
1
2
3
4
map<string, object> map = sqlmapper.selectone("select * from country where id = 35");
map = sqlmapper.selectone("select * from country where id = #{id}", 35);
country country = sqlmapper.selectone("select * from country where id = 35", country.class);
country = sqlmapper.selectone("select * from country where id = #{id}", 35, country.class);

insert,update,delete

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//insert
int result = sqlmapper.insert("insert into country values(1921,'天朝','tc')");
country tc = new country();
tc.setid(1921);
tc.setcountryname("天朝");
tc.setcountrycode("tc");
//注意這里的countrycode和countryname故意寫反的
result = sqlmapper.insert("insert into country values(#{id},#{countrycode},#{countryname})"
             , tc);
//update
result = sqlmapper.update("update country set countryname = '天朝' where id = 35");
tc = new country();
tc.setid(35);
tc.setcountryname("天朝");
int result = sqlmapper.update("update country set countryname = #{countryname}" +
      " where id in(select id from country where countryname like 'a%')", tc);
//delete
result = sqlmapper.delete("delete from country where id = 35");
result = sqlmapper.delete("delete from country where id = #{id}", 35);

注意

通過(guò)上面這些例子應(yīng)該能對(duì)此有個(gè)基本的了解,但是如果你使用參數(shù)方式,建議閱讀下面的文章:

深入了解mybatis參數(shù)

實(shí)現(xiàn)原理

最初想要設(shè)計(jì)這個(gè)功能的時(shí)候,感覺(jué)會(huì)很復(fù)雜,想的也復(fù)雜,需要很多個(gè)類,因此當(dāng)時(shí)沒(méi)有實(shí)現(xiàn)。

突發(fā)奇想,設(shè)計(jì)了現(xiàn)在的這種方式。并且有種強(qiáng)烈的感覺(jué)就是幸好昨天沒(méi)有嘗試去實(shí)現(xiàn),因?yàn)樽蛱焱砩纤伎歼@個(gè)問(wèn)題的時(shí)候是晚上10點(diǎn)多,而今天晚上7點(diǎn)開(kāi)始思考。我很慶幸在一個(gè)更清醒的狀態(tài)下去寫這段代碼。

下面簡(jiǎn)單說(shuō)思路和實(shí)現(xiàn)方式。

在寫mybatis分頁(yè)插件的時(shí)候熟悉了mappedstatement類。

在寫通用mapper的時(shí)候熟悉了xml轉(zhuǎn)sqlnode結(jié)構(gòu)。

如果我根據(jù)sql動(dòng)態(tài)的創(chuàng)建一個(gè)mappedstatement,然后使用mappedstatement的id在sqlsession中執(zhí)行不就可以了嗎?

想到這一點(diǎn),一切就簡(jiǎn)單了。

看看下面select查詢創(chuàng)建mappedstatement的代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
 * 創(chuàng)建一個(gè)查詢的ms
 * @param msid
 * @param sqlsource 執(zhí)行的sqlsource
 * @param resulttype 返回的結(jié)果類型
 */
private void newselectmappedstatement(string msid, sqlsource sqlsource, final class<?> resulttype) {
  mappedstatement ms = new mappedstatement.builder(
      configuration, msid, sqlsource, sqlcommandtype.select)
    .resultmaps(new arraylist<resultmap>() {
      {
        add(new resultmap.builder(configuration,
            "defaultresultmap",
            resulttype,
            new arraylist<resultmapping>(0)).build());
      }
    })
    .build();
  //緩存
  configuration.addmappedstatement(ms);
}

代碼是不是很簡(jiǎn)單,這段代碼的關(guān)鍵是參數(shù)sqlsource,下面是創(chuàng)建sqlsource的方法,分為兩種。

一種是一個(gè)完整的sql,不需要參數(shù)的,可以直接執(zhí)行的:

?
1
staticsqlsource sqlsource = new staticsqlsource(configuration, sql);

其中configuration從sqlsession中獲取,sql就是用戶傳入到sql語(yǔ)句,是不是也很簡(jiǎn)單?

另一種是支持動(dòng)態(tài)sql的,支持參數(shù)的sqlsource:

?
1
sqlsource sqlsource = languagedriver.createsqlsource(configuration, sql, parametertype);

是不是也很簡(jiǎn)單?這個(gè)方法其實(shí)可以兼容上面的staticsqlsource,這里比上面多了一個(gè)parametertype,因?yàn)檫@兒是可以傳遞參數(shù)的,另外languagedriver是從configuration中獲取的。

是不是很簡(jiǎn)單?

我一開(kāi)始也沒(méi)想到mybatis直接執(zhí)行sql實(shí)現(xiàn)起來(lái)會(huì)這么的容易。

insert,delete,update方法的創(chuàng)建更容易,因?yàn)樗麄兊姆祷刂刀际莍nt,所以處理起來(lái)更簡(jiǎn)單,有興趣的可以查看sqlmapper的源碼。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)服務(wù)器之家的支持。如果你想了解更多相關(guān)內(nèi)容請(qǐng)查看下面相關(guān)鏈接

原文鏈接:https://blog.csdn.net/isea533/article/details/44193939

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲AV精品一区二区三区不卡 | 国产精品精品 | 吉川爱美与黑人解禁 | 温柔校草高h| 三级午夜宅宅伦不卡在线 | 国产福利一区二区三区四区 | 99视频精品全部 在线 | 亚洲午夜性春猛交xxxx | 好大好湿好硬好爽好深免费视频 | 国产成人精品免费视频软件 | 日本色淫| 暴露狂婷婷医院暴露tx | 久久99视热频国只有精品 | 亚洲狠狠婷婷综合久久久久网站 | 高清国产激情视频在线观看 | 免费免费啪视频在线观播放 | 亚洲视频1 | 香蕉国产成版人视频在线观看 | 天堂a视频| 4444kk在线看片| 先锋资源av| 亚洲日日做天天做日日谢 | 91亚洲精品国产自在现线 | 国产成人精品系列在线观看 | 欧亚精品一区二区三区 | 天天狠天天透 | 国产伦精品一区二区 | 91国语自产拍在线观看 | 免费一级特黄特色大片 | 日本人成在线视频免费播放 | 美女张开大腿让男人桶 | 亚洲精品一二三四区 | 国产人成激情视频在线观看 | 好大好爽好硬我要喷水了 | 国产亚洲精aa在线观看香蕉 | 国产成人免费视频 | 欧美精品综合一区二区三区 | 春光乍泄在线 | 久久久乱码精品亚洲日韩 | hd性欧美俱乐部中文 | 精品视频一区二区三区 |