亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

MyBatis直接執行SQL的工具SqlMapper

2024-07-14 08:43:20
字體:
來源:轉載
供稿:網友

可能有些人也有過類似需求,一般都會選擇使用其他的方式如Spring-JDBC等方式解決。

能否通過MyBatis實現這樣的功能呢?

為了讓通用Mapper更徹底的支持多表操作以及更靈活的操作,在2.2.0版本增加了一個可以直接執行SQL的新類SqlMapper。

我們來了解一下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個方法,這些方法的命名和參數和SqlSession接口的很像,只是基本上第一個參數都成了sql。

其中Object value為入參,入參形式和SqlSession中的入參一樣,帶有入參的方法,在使用時sql可以包含#{param}或${param}形式的參數,這些參數需要通過入參來傳值。需要的參數過多的時候,參數可以使用Map類型。另外這種情況下的sql還支持下面這種復雜形式:

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

這種情況用的比較少,不多說。

不帶有Object value的所有方法,sql中如果有參數需要手動拼接成一個可以直接執行的sql語句。

在selectXXX方法中,使用Class<T> resultType可以指定返回類型,否則就是Map<String,Object>類型。

實例化SqlMapper

SqlMapper構造參數public SqlMapper(SqlSession sqlSession),需要一個入參SqlSession sqlSession,在一般系統中,可以按照下面的方式獲?。?/p>

SqlSession sqlSession = (...);//通過某些方法獲取sqlSession//創建sqlMapperSqlMapper sqlMapper = new SqlMapper(sqlSession);

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

<bean id="sqlMapper" class="com.github.abel533.sql.SqlMapper" scope="prototype"> <constructor-arg ref="sqlSession"/></bean>

在Service中使用的時候可以直接使用@Autowired注入。

簡單例子

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

下面挑幾個看看如何使用。

selectList

//查詢,返回List<Map>List<Map<String, Object>> list = sqlMapper.selectList("select * from country where id < 11");//查詢,返回指定的實體類List<Country> countryList = sqlMapper.selectList("select * from country where id < 11", Country.class);//查詢,帶參數countryList = sqlMapper.selectList("select * from country where id < #{id}", 11, Country.class);//復雜點的查詢,這里參數和上面不同的地方,在于傳入了一個對象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

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

//insertint 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);//updateresult = 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);//deleteresult = sqlMapper.delete("delete from country where id = 35");result = sqlMapper.delete("delete from country where id = #{id}", 35);

注意

通過上面這些例子應該能對此有個基本的了解,但是如果你使用參數方式,建議閱讀下面的文章:

深入了解MyBatis參數

實現原理

最初想要設計這個功能的時候,感覺會很復雜,想的也復雜,需要很多個類,因此當時沒有實現。

突發奇想,設計了現在的這種方式。并且有種強烈的感覺就是幸好昨天沒有嘗試去實現,因為昨天晚上思考這個問題的時候是晚上10點多,而今天晚上7點開始思考。我很慶幸在一個更清醒的狀態下去寫這段代碼。

下面簡單說思路和實現方式。

在寫MyBatis分頁插件的時候熟悉了MappedStatement類。

在寫通用Mapper的時候熟悉了xml轉SqlNode結構。

如果我根據SQL動態的創建一個MappedStatement,然后使用MappedStatement的id在sqlSession中執行不就可以了嗎?

想到這一點,一切就簡單了。

看看下面select查詢創建MappedStatement的代碼:

/** * 創建一個查詢的MS * @param msId * @param sqlSource 執行的sqlSource * @param resultType 返回的結果類型 */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);}

代碼是不是很簡單,這段代碼的關鍵是參數sqlSource,下面是創建SqlSource的方法,分為兩種。

一種是一個完整的sql,不需要參數的,可以直接執行的:

StaticSqlSource sqlSource = new StaticSqlSource(configuration, sql);

其中configuration從sqlSession中獲取,sql就是用戶傳入到sql語句,是不是也很簡單?

另一種是支持動態sql的,支持參數的SqlSource:

SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, parameterType);

是不是也很簡單?這個方法其實可以兼容上面的StaticSqlSource,這里比上面多了一個parameterType,因為這兒是可以傳遞參數的,另外languageDriver是從configuration中獲取的。

是不是很簡單?

我一開始也沒想到MyBatis直接執行sql實現起來會這么的容易。

insert,delete,update方法的創建更容易,因為他們的返回值都是int,所以處理起來更簡單,有興趣的可以查看SqlMapper的源碼。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對VeVb武林網的支持。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产日韩欧美在线视频观看| 成人女保姆的销魂服务| 久久影院免费观看| 国产精品美女视频网站| 亚洲欧美在线免费| 亚洲欧美制服中文字幕| 国产精品丝袜久久久久久高清| 日本精品久久久久影院| 亚洲日本成人女熟在线观看| 亚洲天堂网站在线观看视频| 97精品国产97久久久久久春色| 亚洲精品成人久久久| 国产精品激情av电影在线观看| 4p变态网欧美系列| 中文字幕精品视频| 亚洲欧美日韩综合| 久久亚洲精品毛片| 成人a视频在线观看| 久久久久久久久电影| 国产精品扒开腿做爽爽爽视频| 日韩av片免费在线观看| 国产日韩精品一区二区| 中文字幕欧美日韩va免费视频| 国产精品久久久久久一区二区| 国产成人精品a视频一区www| 日韩免费在线观看视频| 亚洲欧美日韩网| 国产欧美日韩中文字幕| 久久人人爽亚洲精品天堂| 欧美日韩另类在线| 欧美激情一区二区久久久| 国产精品亚洲精品| 亚洲在线免费看| 57pao国产精品一区| 欧美在线播放视频| 国产精品免费电影| 久久99精品久久久久久噜噜| 欧美另类高清videos| 亚洲色图av在线| 国产精品成人国产乱一区| 最近2019年好看中文字幕视频| 久久久久久久久综合| 国产69精品久久久久久| 欧美最近摘花xxxx摘花| 久久久久久成人| 亚洲欧美成人精品| 高清一区二区三区日本久| 欧美成人免费va影院高清| 国产一区二区欧美日韩| 色噜噜国产精品视频一区二区| 中文字幕亚洲欧美日韩高清| 国产精品日韩电影| 亚洲美女黄色片| 亚洲成人中文字幕| 国产精品一区二区久久久久| 国模吧一区二区三区| 久久中文字幕国产| 欧美在线视频观看免费网站| 国产成人免费av| 午夜精品久久久久久久久久久久久| 久久久久久久香蕉网| 日韩欧美极品在线观看| 亚洲色图13p| 97视频网站入口| 欧美在线一级va免费观看| 亚洲欧美精品在线| 青青青国产精品一区二区| 国产精品看片资源| 91精品国产成人www| 亚洲自拍偷拍色图| 国产成人a亚洲精品| 国产成人黄色av| 高清日韩电视剧大全免费播放在线观看| 欧美性猛交xxxx免费看久久久| 日韩有码视频在线| 亚洲欧美自拍一区| 亚洲一区二区三区香蕉| 日韩欧美在线视频免费观看| 日韩av片永久免费网站| 欧美人与物videos| 日韩免费看的电影电视剧大全| 操日韩av在线电影| 久久久国产视频91| 亚洲欧美中文日韩在线v日本| 伊人久久精品视频| 欧美日韩免费在线| 久久久久成人精品| 国产精品久在线观看| 精品视频9999| 在线免费看av不卡| 亚洲一区二区三区久久| 中文字幕av一区二区三区谷原希美| 日韩av男人的天堂| 国产一区二中文字幕在线看| 久久99精品视频一区97| 久久av红桃一区二区小说| 一区二区亚洲欧洲国产日韩| 热久久免费国产视频| 91免费版网站入口| 国产精品免费视频xxxx| 在线日韩日本国产亚洲| 97国产精品视频人人做人人爱| 欧美激情第1页| 欧美人与性动交| 亚洲日韩欧美视频一区| 欧美中文在线字幕| 中文字幕无线精品亚洲乱码一区| 亚洲视频999| 国产欧美一区二区| 国产精品第七影院| 日韩精品福利在线| 亚洲精品久久久一区二区三区| 91香蕉电影院| 亚洲国产成人精品女人久久久| 亚洲精品在线不卡| 国产精品av网站| 欧美高清无遮挡| 国产日韩欧美视频在线| 亚洲激情视频在线播放| 久久国产一区二区三区| 亚洲网在线观看| 成人免费xxxxx在线观看| 91精品国产91久久久久久吃药| 国产午夜精品免费一区二区三区| 国产成人一区二区三区电影| 亚洲欧美中文日韩在线| 日韩精品在线看| 中文在线不卡视频| 91影院在线免费观看视频| 欧美国产乱视频| xxx成人少妇69| 亚洲精品欧美一区二区三区| 97视频免费在线观看| 久久久久久久久久久人体| 97在线观看视频| 在线观看国产精品日韩av| 国产精品极品尤物在线观看| 国产一区二区三区网站| 日韩国产精品视频| 欧美成人小视频| 日韩久久精品电影| 日韩**中文字幕毛片| 2019中文字幕在线免费观看| 麻豆乱码国产一区二区三区| 成人免费福利在线| 国产日韩精品在线播放| 成人自拍性视频| 欧洲美女7788成人免费视频| 成人淫片在线看| 国产精品美女呻吟| 91网在线免费观看| 日韩欧美综合在线视频| 国产精品jizz在线观看麻豆| 97色在线观看免费视频| 91精品久久久久久久久久久久久久| 亚洲娇小xxxx欧美娇小| 国产精品久久久久福利| 在线成人中文字幕| 国产在线观看精品| 国产精品第2页| 日韩动漫免费观看电视剧高清| 欧美日韩一区二区免费在线观看| 国产精品中文字幕久久久| 久久影院模特热|