国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

Java的MyBatis框架中對(duì)數(shù)據(jù)庫進(jìn)行動(dòng)態(tài)SQL查詢的教程

2019-11-26 14:27:27
字體:
供稿:網(wǎng)友

其實(shí)MyBatis具有的一個(gè)強(qiáng)大的特性之一通常是它的動(dòng)態(tài) SQL 能力。 如果你有使用 JDBC 或其他 相似框架的經(jīng)驗(yàn),你就明白要?jiǎng)討B(tài)的串聯(lián) SQL 字符串在一起是十分糾結(jié)的,確保不能忘了空格或在列表的最后省略逗號(hào)。Mybatis中的動(dòng)態(tài) SQL 可以徹底處理這種痛苦。對(duì)于動(dòng)態(tài)SQL,最通俗簡(jiǎn)單的方法就是我們自己在硬編碼的時(shí)候賦予各種動(dòng)態(tài)行為的判斷,而在Mybatis中,用一種強(qiáng)大的動(dòng)態(tài) SQL 語 言來改進(jìn)這種情形,這種語言可以被用在任意映射的 SQL 語句中。動(dòng)態(tài) SQL 元素和使用 JSTL 或其他相似的基于 XML 的文本處理器相似。MyBatis 采用功能強(qiáng)大的基于 OGNL 的表達(dá)式來消除其他元素。
我們常用的幾個(gè)節(jié)點(diǎn)元素有if,choose(when, otherwise),trim(where, if),foreach。真正使用下來我感覺有點(diǎn)像XSLT(文章后面會(huì)順帶提一下~)的用法。
(1)if 的用法

在ViisitMapper的分頁配置中,如果pageIndex>-1 and pageSize>-1的時(shí)候就加入相應(yīng)的分頁SQL,否則就不添加(默認(rèn)取全部),如下:

<select id="getListByPagenate" parameterType="PagenateArgs"  resultType="Visitor">  select * from (  <include refid="getListSql" /> <include refid="orderBySql"/>  ) t <!-- #{}表示參數(shù)化輸出,${}表示直接輸出不進(jìn)行任何轉(zhuǎn)義操作,自己進(jìn)行轉(zhuǎn)移 -->  <if test="pageStart>-1 and pageSize>-1">    limit #{pageStart}, #{pageSize}  </if></select><sql id="getListSql">  select * from Visitor where  status>0</sql><sql id="orderBySql">  order by ${orderFieldStr} ${orderDirectionStr}</sql>

  因?yàn)槲覀兊膮?shù)pageIndex與pageSize都是int值所以可以這樣直接判斷,如果是對(duì)象實(shí)例我們可以利用null判斷來進(jìn)行一些動(dòng)態(tài)邏輯的控制,具體實(shí)際開發(fā)中就要看業(yè)務(wù)需求了。這里我認(rèn)為要注意的是別十分順手的吧and寫成&&,這個(gè)在配置中不會(huì)被識(shí)別~。

(2)choose (when, otherwise)的用法

  choose when 主要在多個(gè)條件的情況下只滿足其中一個(gè)條件的應(yīng)用場(chǎng)景中使用,例如這里就構(gòu)建一個(gè)query條件,分別傳遞id,name與createTime。假設(shè)我們查詢Visitor表時(shí),如果VisitorId有值則,使用Id查詢,如果VisitorName有值則采用VisitName查詢,如下,還是在david.mybatis.demo.IVisitorOperation接口類中添加List<Visitor> getListChooseWhenDemo(BasicQueryArgs args)方法。在VisitorMapper中添加相應(yīng)的的select節(jié)點(diǎn)配置:

package david.mybatis.demo;import java.util.List;import david.mybatis.model.BasicQueryArgs;import david.mybatis.model.PagenateArgs;import david.mybatis.model.Visitor;import david.mybatis.model.VisitorWithRn;public interface IVisitorOperation {  /*   * 添加訪問者   */  public int add(Visitor visitor);    /*   * 刪除訪問者   */  public int delete(int id);    /*   * 更新訪問者   */  public int update(Visitor visitor);    /*   * 查詢?cè)L問者   */  public Visitor query(int id);    /*   * 查詢List   */  public List<Visitor> getList();    /*   * 分頁查詢List   */  public List<Visitor> getListByPagenate(PagenateArgs args);    /*   * 分頁查詢List(包含Rownum)   */  public List<VisitorWithRn> getListByPagenateWithRn(PagenateArgs args);    /*   * 基礎(chǔ)查詢   */  public Visitor basicQuery(int id);    /*   * 動(dòng)態(tài)條件查詢(choose,when)實(shí)例   */  public List<Visitor> getListChooseWhenDemo(BasicQueryArgs args);    /*   * 動(dòng)態(tài)條件查詢(where,if)實(shí)例   */  public List<Visitor> getListWhereDemo(BasicQueryArgs args);    /*   * 動(dòng)態(tài)查詢(foreach)實(shí)例   */  public List<Visitor> getListForeachDemo(List<Integer> ids);  }
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="david.mybatis.demo.IVisitorOperation">    <resultMap type="Visitor" id="visitorRs">    <id column="Id" property="id" />    <result column="Name" property="name" />    <result column="Email" property="email" />    <result column="Status" property="status" />    <result column="CreateTime" property="createTime" />  </resultMap>  <sql id="getListSqlConditions">    select * from Visitor  </sql>  <!-- 滿足其中一個(gè)條件時(shí)候用choose when操作 -->  <select id="getListChooseWhenDemo" resultMap="visitorRs"    parameterType="BasicQueryArgs">    <include refid="getListSqlConditions" />    <where>      <if test="queryStatus>0">        status=#{queryStatus}      </if>      <choose>        <when test="queryId!=0">          and id=#{queryId}        </when>        <when test="queryName!=null">          and name like #{queryName}        </when>        <otherwise>          and createTime>= #{queryTime}        </otherwise>      </choose>    </where>  </select></mapper>

(3)where if (trim)的用法

where關(guān)鍵詞的好處是在于,如果有相應(yīng)的過濾條件的話,它知道在適當(dāng)?shù)臅r(shí)候插入where關(guān)鍵詞。而且它也知道在何時(shí)該去掉相應(yīng)的AND與OR的連接符,主要應(yīng)對(duì)如下情景

<select id="findActiveBlogLike"   resultType="Blog"> SELECT * FROM BLOG WHERE <if test="state != null">  state = #{state} </if> <if test="title != null">  AND title like #{title} </if> <if test="author != null and author.name != null">  AND author_name like #{author.name} </if></select>

不會(huì)因?yàn)樗袟l件不滿足變?yōu)?/p>

<select id="findActiveBlogLike"   resultType="Blog"> SELECT * FROM BLOG WHERE</select>

或者因?yàn)闆]有滿足第一個(gè)條件,單單滿足后面的條件變成

<select id="findActiveBlogLike"   resultType="Blog">  SELECT * FROM BLOG  WHERE  AND title like ‘someTitle'</select>

所以針對(duì)這種我們可以在建立choose when條件示例,同樣在IVisitorOperation接口類中加入相應(yīng)的方法public List<Visitor> getListWhereDemo(BasicQueryArgs args),把VisitorMapper配置文件中的相對(duì)應(yīng)配置加上去如下:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="david.mybatis.demo.IVisitorOperation">    <sql id="getListSqlConditions">    select * from Visitor  </sql>  <!-- 滿足條件的都加上去操作 -->  <select id="getListWhereDemo" resultMap="visitorRs"    parameterType="BasicQueryArgs">    <include refid="getListSqlConditions" />        <where>       <if test="queryStatus>0">         status>0       </if>       <if test="queryId>0">         and id=#{queryId}       </if>       <if test="queryName!=null">         and name like=#{queryName}       </if>       <if test="queryTime!=null">         and createTime>=#{queryTime}       </if>    </where>    <!--    <trim prefix="WHERE" prefixOverrides="AND |OR ">      <if test="queryStatus>0">        status>0      </if>      <if test="queryId>0">        and id=#{queryId}      </if>      <if test="queryName!=null">        and name like=#{queryName}      </if>      <if test="queryTime!=null">        and createTime>=#{queryTime}      </if>    </trim>    -->  </select></mapper>

(4)foreach的用法

在常用的動(dòng)態(tài)SQL中我們有個(gè)業(yè)務(wù)場(chǎng)景是要where id in 一大串的ID,像這種情況我們就可以用到foreach啦,不必自己辛辛苦苦去拼接Id字符串啦。同樣的步驟還是在IVisitorOperation接口類中加入相應(yīng)的方法public List<Visitor> getListForeachDemo(List<Integer> ids),然后再對(duì)應(yīng)的Mapper文件中配置上相應(yīng)的節(jié)點(diǎn)元素信息,如下:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="david.mybatis.demo.IVisitorOperation">    <sql id="getListSqlConditions">    select * from Visitor  </sql>  <!-- Foreach循環(huán)條件 -->  <select id="getListForeachDemo" resultMap="visitorRs">    <include refid="getListSqlConditions"/>    where status>0 and id in     <foreach collection="list" item="item" index="index" open="(" separator="," close=")">      ${item}    </foreach>  </select></mapper>

最后你只需要在DemoRun中建立相應(yīng)的測(cè)試方法,Mybatis里面的動(dòng)態(tài)SQL也就完成啦,下面測(cè)試用的DemoRun方法

/*   * 動(dòng)態(tài)查詢foreach實(shí)例   */  public static void getListForeachDemo(List<Integer> ids) {    SqlSession session = MybatisUtils.getSqlSession();    IVisitorOperation vOperation = session.getMapper(IVisitorOperation.class);    List<Visitor> ls = vOperation.getListForeachDemo(ids);    for (Visitor visitor : ls) {      System.out.println(visitor);    }  }    /*   * 動(dòng)態(tài)查詢where if實(shí)例   */  public static void getListWhereCondition(int id, String name, Date createTime) {    name = name == "" ? null : name;    SqlSession session = MybatisUtils.getSqlSession();    BasicQueryArgs args = new BasicQueryArgs(id, name, createTime);    IVisitorOperation vOperation = session.getMapper(IVisitorOperation.class);    List<Visitor> ls = vOperation.getListWhereDemo(args);    if (ls.size() == 0)      System.out.println("查無匹配!");    else {      for (Visitor visitor : ls) {        System.out.println(visitor);      }    }  }  /*   * 動(dòng)態(tài)查詢choose when實(shí)例   */  public static void getListChooseWhenDemo(int id, String name, Date createTime) {    name = name == "" ? null : name;    SqlSession session = MybatisUtils.getSqlSession();    BasicQueryArgs args = new BasicQueryArgs(id, name, createTime);    IVisitorOperation vOperation = session.getMapper(IVisitorOperation.class);    List<Visitor> ls = vOperation.getListChooseWhenDemo(args);    if (ls.size() == 0)      System.out.println("查無匹配!");    else {      for (Visitor visitor : ls) {        System.out.println(visitor);      }    }  }

201646151131782.png (795×440)   
PS:關(guān)于OGNL
OGNL 是 Object-Graph Navigation Language 的縮寫,從語言角度來說:它是一個(gè)功能強(qiáng)大的表達(dá)式語言,用來獲取和設(shè)置 java 對(duì)象的屬性 , 它旨在提供一個(gè)更高抽象度語法來對(duì) java 對(duì)象圖進(jìn)行導(dǎo)航,OGNL 在許多的地方都有應(yīng)用,例如:
作為 GUI 元素(textfield,combobox, 等)到模型對(duì)象的綁定語言。
數(shù)據(jù)庫表到 Swing 的 TableModel 的數(shù)據(jù)源語言。
web 組件和后臺(tái) Model 對(duì)象的綁定語言 (WebOGNL,Tapestry,WebWork,WebObjects) 。
作為 Jakarata Commons BeanUtils 或者 JSTL 的表達(dá)式語言的一個(gè)更具表達(dá)力的替代語言。
另外,java 中很多可以做的事情,也可以使用 OGNL 來完成,例如:列表映射和選擇。 對(duì)于開發(fā)者來說,使用 OGNL,可以用簡(jiǎn)潔的語法來完成對(duì) java 對(duì)象的導(dǎo)航。通常來說: 通過一個(gè)“路徑”來完成對(duì)象信息的導(dǎo)航,這個(gè)“路徑”可以是到 java bean 的某個(gè)屬性,或者集合中的某個(gè)索引的對(duì)象,等等,而不是直接使用 get 或者 set 方法來完成。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 湄潭县| 土默特左旗| 肃南| 嘉禾县| 安丘市| 黄浦区| 即墨市| 贞丰县| 石林| 南城县| 溧水县| 阳山县| 桃源县| 西华县| 龙门县| 疏附县| 江川县| 全南县| 玉溪市| 肥东县| 昌吉市| 湖北省| 额济纳旗| 汝州市| 湘潭县| 秦安县| 牡丹江市| 高青县| 尚志市| 河西区| 巴林左旗| 常熟市| 呼图壁县| 宣威市| 阳新县| 台湾省| 定州市| 临安市| 通城县| 泰和县| 庆云县|