讲解mybaits的标签语法
前言:mybatis作为一个持久层的java框架,高度封装了jdbc原始代码,它拥有比Hiberante更便捷、更直接的sql语法和sql灵活配置的特性,比如简单的一个自动映射对象就大大减少了我们的代码,想起以前的时候,jdbc查询出来的数据,通过遍历ResultSet,然后再一个个的set进预置好的对象里,真的是大大减少了重复没有意义的代码。毫无疑问,myabits已经跻身于持久层框架的第一位,目前公司开发的项目大多摒弃Hiberanate,大势所趋为mybaits。今天我们就来聚焦myabits中的mapper文件,看一看平时我们所写的sql基本必不可少的mapper文件(如果不是用注解的话)。
假设现在我们有一张表:名字叫做roles,用来记录用户的角色,其中有role_id,,role_no,role_name,role_desc等字段
还有一个Bean,类名为Roles,有String role_id,String role_no,String role_name,String role_desc等字段用于映射数据库的表字段。
本篇博客的目录:
前言
一:常见的crud标签
二:一些重要辅助标签
三:总结
一:常见的crud标签
1.1:<select>
这个标签相信熟悉sql的一眼就看出来了,mybatis封装了我们最常用的查询语句中的标签,比如我们要查询roles表里的数据,在mapper.xml文件里。直接如下写:
<select id="queryroles" resultType="list>select * from roles</select>
注:其中的id要与接口中的方法名保持一致,myabits通过动态代理的方式把mapper.xml中的配置标签中的id与接口中的方法进行发射匹配,如果不一致,在web程序中启动的时候会报错
reusltType指明了这个sql返回的对象类型,这里指明它是一个list,如果在接口中有对象的list对象,那么它会把查询出来的数据自动映射到这个对象中:
list<Roles> queryroles;
1.2:<update>
望文生义,也不难理解这个标签是进行update操作,在update标签里的sql,mybaits都会识别为更新操作,比如下面的sql
<update id="updateRoleName" parameterType="map">update roles set role_name='admin' where role_id=#{role_id}</update>
这就相当于我们平时的update操作,其中#{id}是取传入的id把它放进sql中进行查询,parameterType指明了它的参数类型是map,这里的 role_id就会从map中去取它以id作为键的对应值,然后把值放入这个sql中执行
1.3:<insert>
简介:i这个标签就是对应sql中的插入数据的操作,一般用于创建新记录的时候使用:
<insert id="createRole" parameterType="map" >insert into roles (role_id,role_name,role_desc)vlaues(#{role_id},#{role_name,#{role_desc}})</insert>
上面的insert就是给roles表里插入了一条数据,其中参数的值全部从传入的参数map里面取,这也很好理解,不再赘述。
1.4:<delete>
简介:该标签用于表明里面的sql用于删除记录:
<delete id="removeRoleById" parameterType="map">delete from roles where role_id='#{role_id}'</delete>
栗子中的就是个删除的sql,用于我们把传入的id找到的一条记录删除
二:辅助语法标签
2.1:<if>
解释:if标签的含义和我们平时编程中的if一样,后面跟上具体的条件都是用于判断不同的条件。不过它并不是if="";它的固定格式为<if test="">,test中的内容是具体的条件.
现在我们需要根据role_name去查找具体的role角色,但是传入的role_name可能为空,比如我们在做一个筛选查询的时候,我们不知道传入的这个role_name条件是否为空为null(假如用户不选就是null),这时候if的作用就出来了:
<select if="searchRoleByName" parareType="string">select role_id,role_no,role_desc from roles where
<if test="role_name !=null and role_name!='' ">role_name like contact('%',#{role_name},'%')</if>
</select>
这样就会在role_name非空非null的情况下,才会进入这个sql执行。否则就会出现select role_id,role_no,role_desc from roles where role_name like '%%';
此sql就会报sql语法错误。
ps:在实际编程中,if对传入的参数的判断非空非null基本是必须要做的,这样会提升程序的伸缩性和容错性。
不过再往下思考一点,加上这个标签以后,如果role_name=null,就会出现select role_id,role_no,role_desc from roles where 。这样的sql,肯定也是错误的,一般我们的作为是拼接一个绝对成立条件,比如1=1,不过这种方式还是有点多余,我们再往下看,mybaits提供了其他标签可以有效的杜绝这个问题。
2.2:choose/when/otherWise标签
解释:在实际的编程环境中,可能我们会遇见这样的场景,比如我们要用几个条件去执行查询操作,条件具有优先级的,我们希望程序以最优先的方式去执行查询。比如在执行查询roles表的时候,我们最希望以id去查询,因为id是唯一的。但是id有可能有null,此时我们希望用role_no去查询,但是role_no可能是null,这个时候我们就只能用role_name去进行模糊匹配了,在这中情况下,就要借用choose/when/otheWise了,它有点类似于java编程中的switch/case
<select id="getRoles" paramterType="map">select * from role where 1=1 <choose>
<when test="role_id !=null and role_id !=''">and role_id=#{role_id}</when>
<when test="role_no!=null and role_no!=''"> and role_no=#{role_no}</when>
<when test="role_name!=null and role_name!=''">
<otherWise>and role_desc is not null</otherWise></choose></select>
上面的sql实现了一种前后优先级的判断(这里的优先级主要体现在when标签里的sql顺序上面),chose标签里的when只会进行一次判断,如果遇到符合条件的,下面的将不会再执行。
2.3:where
在2.1中,我们提到了where 1=1 的用法,这种方式还是有点冗余,为了杜绝这种情况,myabits提供了where标签使用,where是比较智能的,如果where标签会自动判断在if条件不符合的情况下,它将不会插入where子句。在if条件很多的时候,它也知道该不该去除前面的and或or(如果自己不放心,可以用2.4中的trim标签)
<select if="findRoles">select * from roles<where><if test="role_id!=null and role_name!=''"> and role_id=#{role_id}</if><if test="role_no!=null
and role_no!=''">and role_no=''</if></where></select>
上面的sql,即使在role_id为null为空的情况下,也不会出现where and这种情况,或者再role_id和role_test均为null的情况下,出现where 后面跟空的情况
2.4:trim
解释:trim在平时的开发中很常见,String.trim()它的含义表示去除字符串的前后端的空格,而在mybaits中它用于去除我们在判断条件中一些多余的元素,比如and\逗号等preifx和preifxOverride是常见的和它搭配在一起的元素,第一个表示要添加的前缀,后面的表示要去除的元素(只有在trim中的if判断条件不成立的情况下才会去除)
<select id="findRoles">select * from roles
<trime preifx="where" preifxOverride="and">
<if test="role_id!='' and role_id!=null">and role_id=#{role_id}</if></trim></select>
这其中会对if条件进行判断,如果不符合条件就会去除preifxOverride中指定的元素and,并且不会加前缀where.避免出现where后面为空的情况
2.5:set
解释:通常我们在进行update操作的时候,有时候面对的业务需求是修改几列,并不是全部修改。我们知道在sql中的标准语法是这样:update table set fileld1='newfileld1', fileld2='newfileld12, fileld3='newfileld3' where ...(field表示要修改的字段,...表示筛选的条件)。可是在这里会有一个问题就是字段的非空非null判断时的逗号问题,当然在学习了trim的用法以后,比如我们要更新角色表中的name和desc字段你可以这样写:
<update id="updateRole" parameterType="com.wyq.Roles">update roles <trim prefix="set" prefixOverride=",">
<if test="role_name!=null and role_name!=''">role_name=#{role_name},</if> <if test="role_desc !=null and role_desc!=''">role_desc=#{role_desc}</if>
</trim>where role_id=#{role_id}
这样写完全可以,但是稍显冗余,我们可以用更简单 的set标签来进行代替。换成set以后的写法如下:
<update id="updateRole" parameterType="com.wyq.Roles">update roles<set>
<if test="role_name!=null and role_name!=''">role_name=#{role_name},</if><if test="role_desc !=null and role_desc!=''">role_desc=#{role_desc}</if>
</set>where role_id=#{role_id}
set标签会自动处理多余的逗号,我们完全不用担心它在if条件不成立的时候造成的用法错误,这样写是不是简便了很多,试想起当初的jdbc,一个个的非空非null判断,多么无聊和枯燥。
2.6:foreach
foreach在编程中是用于循环遍历一个集合,这个集合一般是list/set。在myabits中,有时候我们会传入一个参数,而对这个参数我们遍历其中的元素就需要用到foreach标签,它一般用在in的语法中,比如我们要查询roles表中的id在(006-008)之间的数据,那么可以采用下面的写法:
<select>
select * from roles where role_id in <foreach item="roleid" index="ix" collection="idlist" open="(",sperator=",",close=")">#{roleid}
</foreach>
</select>
这里就是对idList这个list进行了遍历操作,其中item是指集合中的每项值,我们把它设为roleid,而index就是集合的索引,相当于for(int i=0;i<idlist.size;i++)中的i。open相当于在每个元素前后要添加的开始符号,而close是要添加的结束符号。sperator表示对每个元素进行的分割符号,而在foreach标签里面的内容(#括号里的内容)要保持和item中的内容一致。这样如果传入的idList是(006,007,008)最后的sql就是这样的:
select * from roles where role_id in (006,007,008);
2.7:bind
关于bind,它的最适用的场景就是模糊查询。在mysql中,进行模糊查询的时候,使用的%,而在oracle中模糊查询用的却是"||",这就形成了数据库的语法不统一。我最近的一个项目,boss就决定把mysql
改为oracle,想想这其中得有多少工作量。有没有一种方法,让它既适用于mysql,又适用于oracle,消除数据库之间的差异呢?答案就是bind标签
<select id="getRolesByName" parameterType="com.wyq.Roles">
<bind name="likePattern" value="'%'+_parameter.getRoleName()+'%'"></bind>
select * from roles where role_name like #{likePattern}</select>
bind标签有两个属性,一个是name也就是要绑定的条件的方法,value就是具体的值,_parametType是一个固定的写法,表示传入的参数。而再调用它的getRoleName()获取它的role_name作为参数传递到like这个语法中。在下面的sql中通过#号引用这个bind绑定的值,就可以把它的值代入sql。
2.8:include
解释:这个标签翻译过来就是包含,引用一些元素.比如说我们要查询一段数据,这个数据我们可以用sql标签引起来,然后给它一个id,在include标签里通过refid可以调用该id进行引用。比如我们要查询roles表里的role_id,role_name,role_no,可以这样做:
<sql id="role_colums">role_id,role_no,role_name</sql> <select id="findRoles">select <include refid="role_colums"> from Roles<select>
上面定义了id="role_colums"这个sql标签,然后再下面的sql中通过include标签里的refid来引用该标签,这样在实际的mybatis解析的时候,就会把查询的内容去找相应的id,再取出其中的内容,放在sql中执行。这样做的好处就是可以复用,其它地方想使用可以直接引用,提高了复用率。
三:总结
本篇博文主要介绍了mybaits的常用的一些标签,充分使用标签可以有效的减少代码的判断,提高程序的灵活性和容错性,在平时的开发过程中,多理解它的用法,
可以写出更加便捷的sql,高效的完成我们的程序开发工作。本篇博客介绍的标签还不够全,如果以后看到新的标签,博主一定会及时更新,感谢阅读,希望我们的
编程能力愈来愈高效。