新聞中心
可能有些人也有過類似需求,一般都會(huì)選擇使用其他的方式如Spring-JDBC等方式解決。
十多年的鷹手營子網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。成都全網(wǎng)營銷的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整鷹手營子建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)從事“鷹手營子網(wǎng)站設(shè)計(jì)”,“鷹手營子網(wǎng)站推廣”以來,每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
能否通過MyBatis實(shí)現(xiàn)這樣的功能呢?
為了讓通用Mapper更徹底的支持多表操作以及更靈活的操作,在2.2.0版本增加了一個(gè)可以直接執(zhí)行SQL的新類SqlMapper。
我們來了解一下SqlMapper。
SqlMapper提供的方法
SqlMapper提供了以下這些公共方法:
- Map
selectOne(String sql) - Map
selectOne(String sql, Object value) T selectOne(String sql, Class resultType) T selectOne(String sql, Object value, Class resultType) - List
- List
List selectList(String sql, Class resultType) List selectList(String sql, Object value, Class 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ù)需要通過入?yún)韨髦?。需要的參?shù)過多的時(shí)候,參數(shù)可以使用Map類型。另外這種情況下的sql還支持下面這種復(fù)雜形式:
String sql = "";
這種情況用的比較少,不多說。
不帶有Object value的所有方法,sql中如果有參數(shù)需要手動(dòng)拼接成一個(gè)可以直接執(zhí)行的sql語句。
在selectXXX方法中,使用Class
實(shí)例化SqlMapper
SqlMapper構(gòu)造參數(shù)public SqlMapper(SqlSession sqlSession),需要一個(gè)入?yún)qlSession sqlSession,在一般系統(tǒng)中,可以按照下面的方式獲?。?/p>
SqlSession sqlSession = (...);//通過某些方法獲取sqlSession //創(chuàng)建sqlMapper SqlMapper sqlMapper = new SqlMapper(sqlSession);
如果使用的Spring,那么可以按照下面的方式配置
在Service中使用的時(shí)候可以直接使用@Autowired注入。
簡單例子
在src/test/java目錄的com.github.abel533.sql包中包含這些方法的測(cè)試。
下面挑幾個(gè)看看如何使用。
selectList
//查詢,返回List
selectOne
Mapmap = 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
//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);
注意
通過上面這些例子應(yīng)該能對(duì)此有個(gè)基本的了解,但是如果你使用參數(shù)方式,建議閱讀下面的文章:
深入了解MyBatis參數(shù)
實(shí)現(xiàn)原理
最初想要設(shè)計(jì)這個(gè)功能的時(shí)候,感覺會(huì)很復(fù)雜,想的也復(fù)雜,需要很多個(gè)類,因此當(dāng)時(shí)沒有實(shí)現(xiàn)。
突發(fā)奇想,設(shè)計(jì)了現(xiàn)在的這種方式。并且有種強(qiáng)烈的感覺就是幸好昨天沒有嘗試去實(shí)現(xiàn),因?yàn)樽蛱焱砩纤伎歼@個(gè)問題的時(shí)候是晚上10點(diǎn)多,而今天晚上7點(diǎn)開始思考。我很慶幸在一個(gè)更清醒的狀態(tài)下去寫這段代碼。
下面簡單說思路和實(shí)現(xiàn)方式。
在寫MyBatis分頁插件的時(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),一切就簡單了。
看看下面select查詢創(chuàng)建MappedStatement的代碼:
/** * 創(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() { { add(new ResultMap.Builder(configuration, "defaultResultMap", resultType, new ArrayList (0)).build()); } }) .build(); //緩存 configuration.addMappedStatement(ms); }
代碼是不是很簡單,這段代碼的關(guān)鍵是參數(shù)sqlSource,下面是創(chuàng)建SqlSource的方法,分為兩種。
一種是一個(gè)完整的sql,不需要參數(shù)的,可以直接執(zhí)行的:
StaticSqlSource sqlSource = new StaticSqlSource(configuration, sql);
其中configuration從sqlSession中獲取,sql就是用戶傳入到sql語句,是不是也很簡單?
另一種是支持動(dòng)態(tài)sql的,支持參數(shù)的SqlSource:
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, parameterType);
是不是也很簡單?這個(gè)方法其實(shí)可以兼容上面的StaticSqlSource,這里比上面多了一個(gè)parameterType,因?yàn)檫@兒是可以傳遞參數(shù)的,另外languageDriver是從configuration中獲取的。
是不是很簡單?
我一開始也沒想到MyBatis直接執(zhí)行sql實(shí)現(xiàn)起來會(huì)這么的容易。
insert,delete,update方法的創(chuàng)建更容易,因?yàn)樗麄兊姆祷刂刀际莍nt,所以處理起來更簡單,有興趣的可以查看SqlMapper的源碼。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)創(chuàng)新互聯(lián)的支持。如果你想了解更多相關(guān)內(nèi)容請(qǐng)查看下面相關(guān)鏈接
網(wǎng)站標(biāo)題:MyBatis直接執(zhí)行SQL的工具SqlMapper
文章網(wǎng)址:http://fisionsoft.com.cn/article/jhjjcj.html