使用MyBatis实现条件查询

1.SQL映射文件:

MyBatis真正的强大之处就在于SQL映射语句,MyBatis专注于SQL,对于开发人员来说也是极大限度的进行SQL调优,以保证性能。下面是SQL映射文件的几个顶级元素的配置:

  1.mapper:映射文件的根节点,只有一个属性namespace(命名空间),作用如下:

    (1)用于区分不同的mapper,全局唯一。

    (2)绑定DAO接口,即面向接口编程,当绑定一个接口,就不用写此接口的实现类,会通过接口的完全限定名找到对应的mapper配置来执行SQL语句,所以,namespace的命名必须要写接口的完全限定名。

  2.cache:配置给定命名空间的缓存。

  3.cache-ref:从其他命名空间引用缓存配置。

  4.resultMap:用来描述数据库结果集和对象的对应关系。

  5.sql:可以重用的SQL块,也可以被其他语句引用。

  6.insert:映射插入语句。

  7.update:更新映射语句。

  8.delete:删除映射语句。

  9.select:映射查询语句。

2.使用select完成单条件查询

  <select id = "GetUserByName" resultType = "User" parameterType = "string">

    select * from user where name like concat('%',#{name},'%')    //按照姓名模糊查询。

  </select>

这是一个id为GetUserByName的映射语句,参数类型为string,返回类型为User。

#{参数名}:告诉MyBatis生成的PreparedStatement参数,相对于JDBC,改参数被标识为‘?’。

  id:命名空间的唯一标识符,可以被用来引用这条语句。

  parameterType:表示查询语句传入参数的类型和完全限定名或别名。支持基础数据类型和复杂数据类型。上述实例中传入的参数是一个别名,代表String。

                 别名与Java类型映射

别名       映射的类型     别名     映射的类型    
string   String double Double
byte Byte float Float
long  Long boolean Boolean
short Short date Date
int Integer map Map
integer Integer hashmap HashMap
arraylist ArrayList list List

  resultType:查询语句返回结果类型的完全限定名或别名。别名使用方式和parameterType是一样的。

2.使用select完成多条件查询

  使用复杂数据类型,把条件参数封装为对象、Map进行入参。

  不管什么类型的参数,或者多少个参数,都可以封装为一个Map进行入参,通过Map的key进行获取传入的值。

     <select id="GetUserByNameAndRoleId" resultType="User"
parameterType="map">
select * from smbms_user where userName like
CONCAT('%',#{userName},'%')
and userRole = #{userRole}
</select>

3.使用resultMap完成查询结果的展现

resultMap:做自定义映射,实体类属性名和数据库列名不一致的情况下,并且可以指定要显示的列,使用灵活 应用广泛。

   <resultMap type="User" id="userMap">
  <id column="id" property="id"/>
  <result column="userName" property="Name"/> //字段名和属性名不一致的情况下。
  </resultMap>

属性和子节点:

   id:唯一标识,此id值用于select元素resultMap属性的引用。

     type:标识该resultMap的映射结果类型。

     result子节点:标识一些简单属性,其中column属性代表数据库的字段名,property代表查询出来的字段名映射到pojo类的某个属性。   

     id子节点:与result子节点作用一样,一般表示数据库的主键列。

-------------------------------------------------------------------------------------------------------

resultType和resultMap的对比如下 :

1.resultType:直接表示返回类型, 包括基本数据类型和复杂数据类型。

2.resultMap:外部resultMap定义的引用,通过对应的外部resultMap的id,表示结果映射到哪个resultMap上,一般用于字段名和属性名不一致的情况,或者需要做复杂的联合查询以便自由控制映射结果。

3.两者的关联

当进行查询时,查询出来的每个字段都会放在一个Map里,当查询元素返回属性是resultType的时候,会将键值对取出赋所指定的属性。其实MyBatis的每个查询映射的返回类型都是resultMap,只是当我们使用resultType的时候,会自动把对应的值赋给所指定的对象属性,当使用resultMap时候,因为map不是很好的表示领域,我们就进一步的转化为对应的实体对象。resultMap主要作用于复杂的联合查询上。

注意:resultType和resultMap本质是一样的,都是Map数据结构,但是二者不能同时存在。

4.resultMap的自动映射级别:默认级别为PARTIAL,也可以在settings更改值。

1   <settings>
<!-- 设置resultMap的自动映射级别为NONE(禁止自动匹配) -->
<setting name = "autoMappingBehavior" value = "NONE">
  </settings>

4.使用MyBatis实现增删改操作

  1.使用insert完成增加操作

<insert id="add" parameterType="User">
  INSERT INTO user(userName,userCode) VALUES(#{userName},#{userCode})
</insert>

  2.使用update完成修改操作

    <update id="update" parameterType="User">
UPDATE user SET userName= #{userName},userCode= #{userCode} WHERE id = #{id}
</update>

  3.使用delete完成删除操作

<delete id="User" parameterType="integer">
delete from user
where id = #{id}
</delete>

  元素中的属性:

    id:与select元素id一样,命名空间的唯一标识符。

    parameterType:传入参数的类型的完全限定名或者别名。

对于增删改操作的注意事项:

(1)该类型的操作本身默认返回执行SQL影响的行数,所以DAO层的接口方法返回值一般为int类型,最好不要boolean类型。

(2)insert、update、delete元素中均没有resultType属性,只有查询操作需要对返回结果类型(resultType/resultMap)进行相应的指定。

5.使用@param注解实现多参数入参

   使用注解用来传入多个参数,相当于给该参数重命名,在SQL映射文件中需要使用#{注解名称}来传入参数。 

    public user GetUserByIdAndName(@Param("id") Integer id,@Param("Name") String Name);

当参数为基础类型时,无论是多参数还是单参数,都使用@param注解进行参数的传递为好!

使用resultMap实现高级结果映射

1.association:

  映射到JavaBean的某个复杂的”数据类型”属性,仅处理一对一的关联关系。

  <resultMap type="SMS_USER" id="userMap">
<id column="id" property="id" />
<result column="userName" property="userName" />
<result column="phone" property="phone" />
<association property="role" javaType="SMS_Role">
<id column="id" property="id" />
<result column="roleName" property="roleName" />
</association>
</resultMap>

  association的属性节点:

    property:映射数据库列的实体对象属性名。

    javaType:完整的java类名和限定名。propert所映射的属性的类型。

    子元素:id:一般为映射主键,可以提高性能。

        result:

          column:映射的数据库的字段名。

          property:映射的数据列对应的实体对象属性。
2.collection:

  映射到JavaBean的某个复杂的”数据类型”属性,这个属性是一个集合列表,处理一对多的关联关系。

    <resultMap type="SMS_USER" id="userMapAddress">
<id column="id" property="id"/>
<result column="userName" property="userName"/>
<collection property="lists" ofType="SMS_Address">
       <id column = "id" property = "id">
<result column="addressDesc" property="addressDesc"/>
</collection>
</resultMap>

  ofType:完整的java类名和限定名。propert所映射的属性的类型。

  其余和association基本一致。

MyBatis缓存

1.一级缓存:基于PerpetualCache(MyBatis自带)的HashMap本地缓存。作用域在Session域内,当session flush或者close之后,该缓存被清空。

2.二级缓存:global Cache,超出session范围之外,可以被所有SqlSession共享。开启它只需在MyBatis的核心配置文件 settings 设置即可。

  补充:一级缓存缓存的是SQL语句,二级缓存缓存的是结果对象。

3.二级缓存配置:

  (1)开启二级缓存;

<settings>
<setting name="cacheEnabled" value = "true"/>
<settings>

  (2)mapper文件中设置缓存,默认是没有开启缓存的。作用域是针对namespace而言的,只在namespace内的查询才能共享这个cache。

  (3)对个别查询进行缓存,单独设置cache:

<select id = "getUser" resultType = "User" useCache = "true">
...........
</select>

补充:对MyBatis的缓存了解就可以了,对结果集做缓存并不是MyBatis所擅长的,而且性能也不是很好,它专心做的应该是SQL映射。

------------------------------------------------------------------------------------------------------------------------------------

动态SQL

一、使用动态SQL完成多条件查询。

动态SQL基于OGNL的表达式,我们可以方便的在SQL语句中实现某些逻辑,用于实现动态SQL元素如下:

  if:利用if实现简单的条件选择。

  choose(when,otherwise):相当于java中的switch语句,通常与when和otherwise搭配。

  set:解决动态更新语句。

  trim:灵活的去除多余的关键字。

  foreach:迭代一个集合,通常用于in条件。

二、if+where实现多条件查询

    <select id="ShowUser" parameterType="Map" resultType="SMS_USER">
select * from smbms_user
<where>
<if test="userRole != null and userRole != 0">
userRole = #{userRole}
</if>
<if test="userName != null and userName != ''">
and userName like CONCAT('%',#{userName},'%')
</if>
</where>
</select>

where元素可以智能的处理and 和 or 的多余问题, 不需担心多余关键字导致语法错误。

if元素的test用于判断表达式是否符合,符合则继续拼接SQL语句。

三、if+trim+foreach实现多条件查询

 1  <select id="listsByInAndGender" resultType="SMS_USER">
  select * from smbms_user
<trim prefix="where" prefixOverrides="and | or">
<if test="userIds!=null">
id in
<foreach collection="userIds" item="ids" open="(" close=")" separator=",">
#{ids}
</foreach>
</if>
<if test="gender != null and gender != 0">
and gender = #{gender}
</if>
</trim>
14  </select>

(1)trim的属性:

  prefix:前缀: 作用是通过自动识别是否有返回值后,在trim包含的内容上加上前缀,如上述示例的where。

  suffix:后缀: 作用是在trim包含的内容上加上后缀。

  prefixOverrides: 对于trim包含内容的首部进行指定内容,(如上述示例的 and | or) 的忽略(去余);

  suffixOverrides: 对于trim包含内容的首位部进行指定内容的忽略。

(2)foreach的属性:

  item:表示集合中每一个元素进行迭代时的别名。

  index: 指定一个名称,表示在迭代的过程中,每次迭代到的位置。

  open:表示该语句以什么开始(既然是in条件语句,必然是 ' ( ' 开始)

  separator: 表示每次进行迭代的时候以什么符号作为分隔符(既然是in条件语句,必然是 ' , ' 分隔)

  close: 表示该语句以什么结束(既然是in条件语句,必然是 ' ) ' 结束)

  collection:最关键,并且最容易出错的属性。需注意,该属性必须指定,不同情况下,该属性值是不同的,主要有三种情况:

    若传入的参数是单参数且类型为一个List的时候,属性值为list;

    若传入的参数是单参数且类型为一个数组的时候,属性值为array;

    若传入的参数为多参数时,就需要封装为一个map集合进行处理。属性值为Map的key;

使用set更新操作,类似于上述示例使用方法:

     <update id="UpdateUser" parameterType="SMS_USER">
update smbms_user
<trim prefix="set" suffixOverrides="," suffix="where id = #{id}">
<if test="userName != null and userName != ''">
userName = #{userName},
</if>
<if test="gender != null and gender != 0">
gender = #{gender},
</if>
<if test="address != null and address != ''">
address = #{address},
</if>
</trim>
</update>

三、choose(when、otherwise)

     <select id="QueryAllByChoose" resultType="SMS_provider">
select * from smbms_provider where 1 = 1
<choose>
<when test="proCode != null and proCode != ''">
and proCode like CONCAT('%',#{proCode},'%')
</when>
<when test="proName != null and proName != ''">
and proName like CONCAT('%',#{proName},'%')
</when>
<when test="proContact != null and proContact != ''">
and proContact like CONCAT('%',#{proContact},'%')
</when>
<otherwise>
and YEAR(creationDate) = 2016
</otherwise>
</choose>
</select>

  when元素:当test属性中的条件满足时,就会输出when元素中的内容,并且当when中一旦有条件满足时,就会跳出choose,所以只有一个条件会被输出。

  otherwise元素:当when中的所有条件都不满足时,则会输出此元素的内容。

四、MyBatis实现分页功能

  1.使用聚合函数获得总记录数-

  2.实现分页通过limit(起始位置,页面显示量)

补充:起始位置的下标  = (当前页码 - 1 ) * 页面显示量

       <!-- 多条件筛选分页 -->
<select id="UserPage" parameterType="map" resultType="SMS_USER">
select * from smbms_user
<trim prefix="where" prefixOverrides="and | or">
<if test="userName != null and userName != ''">
userName like concat('%',#{userName},'%')
</if>
<if test="userRole != null and userRole != 0">
and userRole = #{userRole}
</if>
</trim>
limit #{startRow},#{pageSize}
</select>

MyBatis框架之SQL映射和动态SQL的更多相关文章

  1. 小峰mybatis(5)mybatis使用注解配置sql映射器--动态sql

    一.使用注解配置映射器 动态sql: 用的并不是很多,了解下: Student.java 实体bean: package com.cy.model; public class Student{ pri ...

  2. MyBatis基础入门《十七》动态SQL

    MyBatis基础入门<十七>动态SQL 描述: >> 完成多条件查询等逻辑实现 >> 用于实现动态SQL的元素主要有: > if > trim > ...

  3. .Net程序员学用Oracle系列(28):PLSQL 之SQL分类和动态SQL

    1.SQL 语句分类 1.1.分类方法及类型 1.2.数据定义语言 1.3.数据操纵语言 1.4.其它语句 2.动态 SQL 理论 2.1.动态 SQL 的用途 2.2.动态 SQL 的语法 2.3. ...

  4. PL/SQL开发中动态SQL的使用方法

    一般的PL/SQL程序设计中,在DML和事务控制的语句中可以直接使用SQL,但是DDL语句及系统控制语句却不能在PL/SQL中直接使用,要想实现在PL/SQL中使用DDL语句及系统控制语句,可以通过使 ...

  5. 数据库系统学习(十)-嵌入式SQL语言之动态SQL

    第十讲 嵌入式SQL语言之动态SQL 静态SQL 区别变量和属性:高级语言向嵌入式SQL传递变量的方法 动态SQL 动态构造SQL语句是应用程序员必须掌握的重要手段 SQL语句的动态构造示例 根据界面 ...

  6. (转)MyBatis框架的学习(四)——Mapper.xml文件中的输入和输出映射以及动态sql

    http://blog.csdn.net/yerenyuan_pku/article/details/71893689 前面对MyBatis框架的学习中,我们对Mapper.xml映射文件多少有些了解 ...

  7. Java数据持久层框架 MyBatis之API学习七(动态 SQL详解)

    对于MyBatis的学习而言,最好去MyBatis的官方文档:http://www.mybatis.org/mybatis-3/zh/index.html 对于语言的学习而言,马上上手去编程,多多练习 ...

  8. (转)Mybatis高级映射、动态SQL及获得自增主键

    原文:http://www.cnblogs.com/edwinchen/p/4105278.html?utm_source=tuicool&utm_medium=referral 一.动态SQ ...

  9. Mybatis高级映射、动态SQL及获得自增主键

    一.动态SQL 相信大家在用mybatis操作数据库时时都会碰到一个问题,假如现在我们有一个关于作者的list authorList,需要根据authorList里已有的作者信息在数据库中查询相应作者 ...

随机推荐

  1. Windows RabbitMQ 安装

    操作系统 Win10  企业版 目标: 在win10上安装RabbitMQ 安装步骤 1.安装RabbitMQ需要先安装Erlang语言开发包,下载地址:http://www.erlang.org/d ...

  2. 瑞芯微RK3399宣布系统开源,进入百余种行业市场!

    集微网消息,2月24日瑞芯微官方突然宣布, Rockchip RK3399Linux系统开源!作为Rockchip旗舰级芯片,RK3399具有高性能.高扩展.全能型应用特性. 这一重磅消息立马刷爆朋友 ...

  3. KmdKit4D 0.01正式版发布了(0.02版已放出)(Delphi做驱动)

    此版本较0.01预览版已经有了脱胎换骨的变化,主要表现在以下几个方面:    1.对程序的结构进行了调整,将原来的ntutils.dcu分成fcall.dcu.halfcall.dcu和macros. ...

  4. Memory Ordering (注意Cache带来的副作用,每个CPU都有自己的Cache,内存读写不再一定需要真的作内存访问)

    Memory Ordering   Background 很久很久很久以前,CPU忠厚老实,一条一条指令的执行我们给它的程序,规规矩矩的进行计算和内存的存取. 很久很久以前, CPU学会了Out-Of ...

  5. 预编译加速编译(precompiled_header),指定临时文件生成目录,使项目文件夹更干净(MOC_DIR,RCC_DIR, UI_DIR, OBJECTS_DIR),#pragma execution_character_set("UTF-8")"这个命令是在编译时产生作用的,而不是运行时

    预编译加速编译 QT也可以像VS那样使用预编译头文件来加速编译器的编译速度.首先在.pro文件中加入: CONFIG += precompiled_header 然后定义需要预编译的头文件: PREC ...

  6. Webapi实现websocket实时通讯

    应用场景:前端页面发起一个websocket请求与后端进行实时通讯.后端监听某端口获取数据,将监听到的数据加工处理,通过websocket发送到前端. 这里只提供后台的处理方案仅供参考. 1.后端监听 ...

  7. Hexo+NexT(一):在Windows下安装Hexo+NexT及搭建博客

    阅读本篇之前,假定读者已经有了Node.js的基础,如需要补充Node.js知识的,请自行百度. Hexo是在Node.js框架下的一个项目,利用Node.js提供的强大功能,完成从Markdown到 ...

  8. 解决安装Oracle本地可以访问客户端不能访问

    现象:本地需要修改监听为localhost -->win+r--> sqlplus system/123@xxdb 可以登陆,远程客户端不能登陆:需要将监听修改为IP地址,重启监听:远程可 ...

  9. Django之forms组件进阶

    Django Form表单组件   Form介绍 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来. 与此同时我们在好多场景下都需要 ...

  10. 支持向量机 (二): 软间隔 svm 与 核函数

    软间隔最大化(线性不可分类svm) 上一篇求解出来的间隔被称为 "硬间隔(hard margin)",其可以将所有样本点划分正确且都在间隔边界之外,即所有样本点都满足 \(y_{i ...