程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> MyBatis 履行靜態 SQL語句詳解

MyBatis 履行靜態 SQL語句詳解

編輯:關於JAVA

MyBatis 履行靜態 SQL語句詳解。本站提示廣大學習愛好者:(MyBatis 履行靜態 SQL語句詳解)文章只能為提供參考,不一定能成為您想要的結果。以下是MyBatis 履行靜態 SQL語句詳解正文


年夜家根本上都曉得若何應用 MyBatis 履行隨意率性 SQL,應用辦法很簡略,例如在一個 XXMapper.xml 中:

<select id="executeSql" resultType="map">
${_parameter}
</select>

你可以以下挪用:

sqlSession.selectList("executeSql", "select * from sysuser where enabled = 1");

或許你可以在 XXMapper.java 接口中界說以下辦法:

List<Map> executeSql(String sql);

然後應用接口挪用辦法:

xxMapper.executeSql("select * from sysuser where enabled = 1");

下面這些內容能夠都邑,上面在此基本上再龐雜一點。

假設像下面SQL中的enabled = 1我想應用參數方法傳值,也就是寫成 enabled = #{enabled},假如你沒有碰到過相似這類需求,能夠不明確為何要這麼寫,舉個例子,要完成一種靜態查詢,可以在前台經由過程設置裝備擺設 SQL,供給一些查詢前提就可以完成一個查詢的功效(為了平安,這些設置裝備擺設確定是開辟或許實行做的,弗成能讓用戶直接操作數據庫)。

針對這個功效,應用 MyBatis 完成起來相當輕易。設置裝備擺設 SQL 確定要履行,用下面講的這類方法確定可以履行 SQL,若何供給參數呢?參數就是enabled = #{enabled}中的#{enabled}部門。假如再多一些前提,一個設置裝備擺設好的 SQL 以下:

select * from sysuser 
where enabled = #{enabled} 
and userName like concat('%',#{userName},'%')

這類情形下,該怎樣用 MyBatis 完成呢?

起首 XML 中修正以下:

<select id="executeSql" resultType="map">
${sql}
</select>

接口中的辦法修正為:

List<Map> executeSql(Map map);

然後挪用辦法:

Map map = new HashMap();
//這裡的 sql 對應 XML 中的 ${sql}
map.put("sql", "select * from sysuser "
+ " where enabled = #{enabled} "
+ " and userName like concat('%',#{userName},'%')");
//#{enabled}
map.put("enabled", 1);
//#{userName}
map.put("userName", "admin");
//接口方法挪用
List<Map> list = xxMapper.executeSql(map);
//sqlSession方法挪用
sqlSession.selectList("executeSql", map);

有了這個SQL以後,便可以將 enabled 和 userName 作為前提供給給用戶。這兩個前提明顯是必填的。假如是可選的,那該怎樣寫?

或許有人想到了是否是可以用 MyBatis 中的靜態 SQL,應用<if>標簽等等?

再答復這個成績前,我們先看處置靜態 SQL 的 DynamicSqlSource 中的代碼:

@Override 
public BoundSql getBoundSql(Object parameterObject) {
DynamicContext context = new DynamicContext(configuration, parameterObject);
rootSqlNode.apply(context);
SqlSourceBuilder sqlSourceParser = new SqlSourceBuilder(configuration);
Class < ?>parameterType = 
parameterObject == null ? Object.class: parameterObject.getClass();
SqlSource sqlSource = sqlSourceParser.parse(context.getSql(), 
parameterType, context.getBindings());
BoundSql boundSql = sqlSource.getBoundSql(parameterObject);
for (Map.Entry < String, Object > entry: context.getBindings().entrySet()) {
boundSql.setAdditionalParameter(entry.getKey(), entry.getValue());
}
return boundSql;
}

MyBatis 處置靜態 SQL 時,一切靜態 SQL 的標簽都邑處置為 SqlNode (這裡的rootSqlNode)對象,包括${}的也會處置為 TextSqlNode 對象,在下面辦法的前兩行,就是 MyBatis 處置靜態 SQL 的處所。

是以假如我們在${sql} 中的內容包括嵌套的${}和<if>,<where>等標簽時,他們在 MyBatis 解析 XML 為 SqlNode 對象時,XML <select> 元素包括的內容只要${sql},只要${sql}會被解析,在運轉時這個參數字符串中能夠包括的${}和<if>,<where>等標簽,然則這都產生在 MyBatis 解析後,是以當這些內容作為字符串中的一部門湧現時,他們不會被特別處置,他們只是SQL中的一部門,只是原樣輸入(因為數據庫不認會報錯)沒法被處置,是以沒法經由過程 MyBatis 自帶的這類方法來寫靜態 SQL。

提醒

在下面的代碼中:

sqlSourceParser.parse(context.getSql(), parameterType, context.getBindings());

這一段代碼是處置靜態參數(#{})的這個處置在靜態 SQL 處置以後, 是以可以在 SQL 中應用這類類型的參數。

既然不克不及用 MyBatis 靜態 SQL 方法,該怎樣完成靜態 SQL 呢?

這裡供給一個簡略的思緒,在 SQL 中應用模板標志說話來完成靜態SQL(例如freemarker),在 SQL 交給 MyBatis 履行之前,應用模板對 SQL 停止處置生成終究履行的 SQL(須要防止處置#{}參數),將這個SQL交給 MyBatis 履行。

舉一個Freemarker模板的例子,依然以下面的SQL為基本:

select * from sysuser 
where 1 = 1
<#if enabled??>
enabled = #{enabled} 
</#if>
<#if userName?? && userName != ''>
and userName like concat('%',#{userName},'%')
</#if>

留意,這裡的<#if>是Freemarker的元素。在不斟酌SQL注入的情形下,下面的SQL還可以寫成:

select * from sysuser 
where 1 = 1
<#if enabled??>
enabled = #{enabled} 
</#if>
<#if userName?? && userName != ''>
and userName like '%${userName}%'
</#if>

差別就是'%${userName}%',由於 Freemarker 也會處置 ${userName},也會用現實的值來調換這裡的參數。

在後面挪用的代碼中,這裡修正以下:

//#{enabled}
map.put("enabled", 1);
//#{userName}
map.put("userName", "admin");
//這裡的 sql 對應 XML 中的 ${sql}
String sql = "下面兩個龐雜SQL中的一個";
//應用Freemarker處置sql
sql = processSqlByFreemarker(sql, map);
//將處置後的sql放到map中
map.put("sql", "select * from sysuser "
+ " where enabled = #{enabled} "
+ " and userName like concat('%',#{userName},'%')");
//履行辦法
List<Map> list = xxMapper.executeSql(map);

注:processSqlByFreemarker辦法就是依據map中的數據來處置sql字符串,完成方法可以本身搜刮。

到這裡,一個不是很龐雜的靜態SQL功效就完成了。

不曉得有無更貪婪的人,你會不會想,下面前往值都是List<Map>類型,能不克不及前往一個我指定的實體類呢?

例如在map中:

map.put("class", "tk.mybatis.model.SysUser");

能不克不及經由過程這類方法讓前往值釀成SysUser類型呢?因為這篇文章耗時曾經太長,這裡就供給一個計劃,不深刻。

你可使用攔阻器完成,獲得 MappedStatement 後,復制一份,然後修正 resultMaps中resultMap的type屬性為你指定的class類型就可以完成,說起來輕易,現實操作起來能有 PageHelper 分頁插件 1/10 閣下的任務量。

由於這篇是應媳婦請求所寫,所以假設媳婦有最初的這個需求,我就協助媳婦完成這個插件,然後再同享出來。

注:假如是靜態的update,insert,delete 語句,可以將下面的<select>改成update(不須要應用<delete>和<insert>),前往值用int,比 select 的情形輕易許多。

以上所述是小編給年夜家引見的MyBatis 履行靜態 SQL語句詳解,願望對年夜家有所贊助,假如年夜家有任何疑問請給我留言,小編會實時答復年夜家的。在此也異常感激年夜家對網站的支撐!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved