MyBatis框架之SQL映射和动态SQL

使用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进行获取传入的值。

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

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

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

1<resultMap type="User" id="userMap">
2  <id column="id" property="id"/>
3   <result column="userName" property="Name"/> //字段名和属性名不一致的情况下。
4</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>
2    <!-- 设置resultMap的自动映射级别为NONE(禁止自动匹配) -->
3    <setting name = "autoMappingBehavior" value = "NONE">
4</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的某个复杂的”数据类型”属性,仅处理一对一的关联关系。

association的属性节点:

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

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

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

    result:

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

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

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

    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实现多条件查询

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

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

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

(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更新操作,类似于上述示例使用方法:

三、choose(when、otherwise)

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

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

四、MyBatis实现分页功能

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

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

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,099评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,473评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,229评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,570评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,427评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,335评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,737评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,392评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,693评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,730评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,512评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,349评论 3 314
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,750评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,017评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,290评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,706评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,904评论 2 335

推荐阅读更多精彩内容

  • 1. 简介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的...
    笨鸟慢飞阅读 5,403评论 0 4
  • Java数据持久化之mybatis 一. mybatis简介 1.1 原始的JDBC操作: Java 通过 Jav...
    小Q逛逛阅读 4,887评论 0 16
  • 0 “曾经沧海难为水,除却巫山不是云。”因为韦从的早逝,让暮年的多情才子元稹写着这流传千古的句子。兴许没有陪到最后...
    红木娄阅读 481评论 0 3
  • 我们对一些事物致以歉意 情书,分岔的路口,一座幽静的花园 我们之间,隔着许多意义模糊的词语,比如说 “灰色”“在哪...
    我是不是蝎大人阅读 210评论 0 2
  • 人生,总有一些事要自己做,总有一些路要自己走。生命这段旅程,来的时候一个人来,走的时候一个人走,什么也带不来,什么...
    a放下a阅读 250评论 0 1