Mybatis 框架使用的最核心内容(二):mapper.xml中常用的标签详解
2016-05-17 10:07
716 查看
接上篇,对Mybatis的特点和映射管理介绍,本篇将详解介绍mapper.xml中的常用标签和它们各自的功能及使用方式
一、SQL语句标签:
parameterType="" >>>表示该sql语句中需要传入的参数, 类型要与对应的接口方法的类型一致【可选】
resultMap=“ ”>>> 定义出参,调用已定义的<resultMap>映射管理器的id值
resultType=“ ”>>>定义出参,匹配普通java类型或自定义的pojo【出参类型若不指定,将为语句类型默认类型,如<insert>语句返回值为int】
p.s: 至于为何<insert><delete><update> 语句的返回值类型为什么是int,有过JDBC操作经验的朋友可能会有印象,增删改操作实际上返回的是操作的条数。而Mybatis框架本身是基于JDBC的,所以此处也沿袭这种返回值类型。
传参和取值:mapper.xml 的灵活性还体现在SQL执行语句可以传参,参数类型通过parameterType= “” 定义
取值方式1:#{value jdbcType = valuetype}:jdbcType 表示该属性的数据类型在数据库中对应的类型,如 #{user jdbcType=varchar} 等价于 String username;
取值方式2:${value } : 这种方式不建议大量使用,可能会发送sql注入而导致安全性问题。一般该取值方式可用在非经常变化的值上,如orderby ${columnName};
二、sql
4000
片段标签<sql>:通过该标签可定义能复用的sql语句片段,在执行sql语句标签中直接引用即可。这样既可以提高编码效率,还能有效简化代码,提高可读性
需要配置的属性:id="" >>>表示需要改sql语句片段的唯一标识
引用:通过<include refid="" />标签引用,refid="" 中的值指向需要引用的<sql>中的id=“”属性
三、映射管理器resultMap:映射管理器,是Mybatis中最强大的工具,使用其可以进行实体类之间的关系,并管理结果和实体类间的映射关系
需要配置的属性:<resultMap id=" " type=" "></resutlMap> id=" ">>>表示这个映射管理器的唯一标识,外部通过该值引用; type = " ">>> 表示需要映射的实体类;
需要配置的参数:<id column = " " property= " " /> <id>标签指的是:结果集中结果唯一的列【column】 和 实体属性【property】的映射关系,注意:<id>标签管理的列未必是主键列,需要根据具体需求指定;
<result column= " " property=" " /> <result>标签指的是:结果集中普通列【column】 和 实体属性【property】的映射关系;
需要维护的关系:所谓关系维护是值在主表查询时将其关联子表的结果也查询出来
1)一对一关系<assocation property = " " javaType=" "> property = “ ” 被维护实体在宿主实体中的属性名,javaType = " " 被维护实体的类型
Orderitem.java
Orderitemmapper.xml
2)一对多关系的维护<collection property=" " ofType=" "> property = “ ” 被维护实体在宿主实体中的属性名 ,ofType=“ ”是被维护方在宿主类中集合泛型限定类型
【由于在一对多关系中,多的一放是以List形式存在,因此ofType的值取用Lsit<?> 的泛型对象类型】
OrderTable.java
3)在resultMap 中需要注意两点:
3.1)关联关系的维护可以根据实体类之间的实际情况进行嵌套维护
3.2)关于出现重复列名的处理:在实际操作过程中,查询到的结果可能会出现相同的列名,这样会对映射到实体属性带来影响甚至出现报错,那么对待这个问题可以通过对列取别名的方式处理
四:常用的动态语句标签:通过动态sql标签可以进行条件判断,条件遍历等操作从而满足结果的需要
<where> : 使用其可以代替sql语句中的where关键字,一般防止在条件查询的最外层
<if >:条件判断标签,配置属性test=" 条件字符串 ",判断是否满足条件,满足则执行,不满足则跳过
<set>:常用于<update>更新语句中,替代 sql中的“set”关键字,特别是在联合<if>进行判断是,可以有效方式当某个参数为空或者不合法是错误的更新到数据库中
<choose><when></when><otherwise></otherwise></choose> 标签组:也是一个用于条件判断的标签组,和<if>的不同之处在于条件从<choose>进入,去匹配<when>中的添加,一旦匹配马上结束;若到找不到匹配项,将执行<other>中的语句;可以理解为<if>是 && 关系 <choose>是 || 关系
<foreach>标签:该标签的作用是遍历集合类型的条件
属性:collection=“array” / collection = “list” ----->是数组类型,还是集合类型
item=“ productId ”------> 参数名
open="(" separator="," close=")" ------>开始符号,分隔符号,结束符号
index=“ ” ---->结束下标位置,不配置该参数时,默认为全部遍历
一、SQL语句标签:
<!--查询语句--> <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.String" > select </select> <!--插入语句--> <insert id="insert" parameterType="pojo.OrderTable" > insert into ordertable (order_id, cid, address, create_date, orderitem_id) values (#{orderId,jdbcType=VARCHAR}, #{cid,jdbcType=VARCHAR}, #{address,jdbcType=VARCHAR}, #{createDate,jdbcType=TIMESTAMP}, #{orderitemId,jdbcType=VARCHAR}) </insert> <!--删除语句--> <delete id="deleteByPrimaryKey" parameterType="java.lang.String" > delete from ordertable where order_id = #{orderId,jdbcType=VARCHAR} </delete> <!--修改语句--> <update id="updateByPrimaryKey" parameterType="pojo.OrderTable" > update ordertable set cid = #{cid,jdbcType=VARCHAR}, address = #{address,jdbcType=VARCHAR}, create_date = #{createDate,jdbcType=TIMESTAMP}, orderitem_id = #{orderitemId,jdbcType=VARCHAR} where order_id = #{orderId,jdbcType=VARCHAR} </update>需要配置的属性:id="xxxx" >>> 表示此段sql执行语句的唯一标识,也是接口的方法名称【必须一致才能找到】
parameterType="" >>>表示该sql语句中需要传入的参数, 类型要与对应的接口方法的类型一致【可选】
resultMap=“ ”>>> 定义出参,调用已定义的<resultMap>映射管理器的id值
resultType=“ ”>>>定义出参,匹配普通java类型或自定义的pojo【出参类型若不指定,将为语句类型默认类型,如<insert>语句返回值为int】
p.s: 至于为何<insert><delete><update> 语句的返回值类型为什么是int,有过JDBC操作经验的朋友可能会有印象,增删改操作实际上返回的是操作的条数。而Mybatis框架本身是基于JDBC的,所以此处也沿袭这种返回值类型。
传参和取值:mapper.xml 的灵活性还体现在SQL执行语句可以传参,参数类型通过parameterType= “” 定义
取值方式1:#{value jdbcType = valuetype}:jdbcType 表示该属性的数据类型在数据库中对应的类型,如 #{user jdbcType=varchar} 等价于 String username;
取值方式2:${value } : 这种方式不建议大量使用,可能会发送sql注入而导致安全性问题。一般该取值方式可用在非经常变化的值上,如orderby ${columnName};
二、sql
4000
片段标签<sql>:通过该标签可定义能复用的sql语句片段,在执行sql语句标签中直接引用即可。这样既可以提高编码效率,还能有效简化代码,提高可读性
需要配置的属性:id="" >>>表示需要改sql语句片段的唯一标识
引用:通过<include refid="" />标签引用,refid="" 中的值指向需要引用的<sql>中的id=“”属性
<!--定义sql片段--> <sql id="orderAndItem"> o.order_id,o.cid,o.address,o.create_date,o.orderitem_id,i.orderitem_id,i.product_id,i.count </sql> <select id="findOrderAndItemsByOid" parameterType="java.lang.String" resultMap="BaseResultMap"> select <!--引用sql片段--> <include refid="orderAndItem" /> from ordertable o join orderitem i on o.orderitem_id = i.orderitem_id where o.order_id = #{orderId} </select>
三、映射管理器resultMap:映射管理器,是Mybatis中最强大的工具,使用其可以进行实体类之间的关系,并管理结果和实体类间的映射关系
需要配置的属性:<resultMap id=" " type=" "></resutlMap> id=" ">>>表示这个映射管理器的唯一标识,外部通过该值引用; type = " ">>> 表示需要映射的实体类;
需要配置的参数:<id column = " " property= " " /> <id>标签指的是:结果集中结果唯一的列【column】 和 实体属性【property】的映射关系,注意:<id>标签管理的列未必是主键列,需要根据具体需求指定;
<result column= " " property=" " /> <result>标签指的是:结果集中普通列【column】 和 实体属性【property】的映射关系;
需要维护的关系:所谓关系维护是值在主表查询时将其关联子表的结果也查询出来
1)一对一关系<assocation property = " " javaType=" "> property = “ ” 被维护实体在宿主实体中的属性名,javaType = " " 被维护实体的类型
Orderitem.java
package pojo; public class Orderitem { private String orderitemId; private String productId; private Integer count; private Product product;从上方代码段可以看出:Product 对象在 Orderitem 实体中以 product 属性存在
Orderitemmapper.xml
<resultMap id="BaseResultMap" type="pojo.Orderitem" > <id column="orderitem_id" property="orderitemId" jdbcType="VARCHAR" /> <result column="product_id" property="productId" jdbcType="VARCHAR" /> <result column="count" property="count" jdbcType="INTEGER" /> <!-- 通过association 维护 一对一关系 --> <association property="product" javaType="pojo.Product"> <id column="product_id" property="productId"/> <result column="product_factroy" property="productFactroy"/> <result column="product_store" property="productStore"/> <result column="product_descript" property="productDescript"/> </association> </resultMap>通过xml的配置可以看出,在resultMap映射管理器中,通过<association> 进行了维护,也就是在查询Orderitem对象时,可以把关联的Product对象的信息也查询出来
2)一对多关系的维护<collection property=" " ofType=" "> property = “ ” 被维护实体在宿主实体中的属性名 ,ofType=“ ”是被维护方在宿主类中集合泛型限定类型
【由于在一对多关系中,多的一放是以List形式存在,因此ofType的值取用Lsit<?> 的泛型对象类型】
OrderTable.java
public class OrderTable { private String orderId; private String cid; private String address; private Date createDate; private String orderitemId; private List<Orderitem> orderitemList ;
}OrderTableMapper.xml;
<resultMap id="BaseResultMap" type="pojo.OrderTable" > <!-- WARNING - @mbggenerated This element is automatically generated by MyBatis Generator, do not modify. This element was generated on Fri May 06 15:49:42 CST 2016. --> <id column="order_id" property="orderId" jdbcType="VARCHAR" /> <result column="cid" property="cid" jdbcType="VARCHAR" /> <result column="address" property="address" jdbcType="VARCHAR" /> <result column="create_date" property="createDate" jdbcType="TIMESTAMP" /> <result column="orderitem_id" property="orderitemId" jdbcType="VARCHAR" /> <!--维护一对多的关系 --> <collection property="orderitemList" ofType="pojo.Orderitem"> <id column="orderitem_id" property="orderitemId"/> <result column="product_id" property="productId"/> <result column="count" property="count"/> </collection> </resultMap>
3)在resultMap 中需要注意两点:
3.1)关联关系的维护可以根据实体类之间的实际情况进行嵌套维护
<resultMap id="BaseResultMap" type="pojo.OrderTable" > <id column="order_id" property="orderId" jdbcType="VARCHAR" /> <result column="cid" property="cid" jdbcType="VARCHAR" /> <result column="address" property="address" jdbcType="VARCHAR" /> <result column="create_date" property="createDate" jdbcType="TIMESTAMP" /> <result column="orderitem_id" property="orderitemId" jdbcType="VARCHAR" /> <!--维护一对多的关系 --> <collection property="orderitemList" ofType="pojo.Orderitem"> <id column="orderitem_id" property="orderitemId"/> <result column="product_id" property="productId"/> <result column="count" property="count"/> <span style="white-space:pre"> </span><!--嵌套一对一关系--> <association property="customer" javaType="pojo.Customer"> <id column="cid" property="cid"/> <result column="cname" property="cname"/> </association> </collection> </resultMap>【读者只用参考上方代码段的写法,实体关系仅为笔者举例没有必然的逻辑联系】
3.2)关于出现重复列名的处理:在实际操作过程中,查询到的结果可能会出现相同的列名,这样会对映射到实体属性带来影响甚至出现报错,那么对待这个问题可以通过对列取别名的方式处理
四:常用的动态语句标签:通过动态sql标签可以进行条件判断,条件遍历等操作从而满足结果的需要
<where> : 使用其可以代替sql语句中的where关键字,一般防止在条件查询的最外层
<if >:条件判断标签,配置属性test=" 条件字符串 ",判断是否满足条件,满足则执行,不满足则跳过
<select id="findOrderItemDetail" parameterType="pojo.Orderitem" resultMap="BaseResultMap"> select orderitem.orderitem_id,product.* from orderitem,product <where> <if test="orderitemId!=null and orderitemId!=''"> and orderitem.orderitem_id = #{orderitemId} </if> <if test="productId!=null and productId!=''"> and orderitem.product_id = #{productId} </if> <if test="count!=null"> and orderitem.count = #{count} </if> </where> </select>
<set>:常用于<update>更新语句中,替代 sql中的“set”关键字,特别是在联合<if>进行判断是,可以有效方式当某个参数为空或者不合法是错误的更新到数据库中
<update id="updateByPrimaryKeySelective" parameterType="pojo.Orderitem" > update orderitem <set > <if test="productId != null" > product_id = #{productId,jdbcType=VARCHAR}, </if> <if test="count != null" > count = #{count,jdbcType=INTEGER}, </if> </set> where orderitem_id = #{orderitemId,jdbcType=VARCHAR} </update>
<choose><when></when><otherwise></otherwise></choose> 标签组:也是一个用于条件判断的标签组,和<if>的不同之处在于条件从<choose>进入,去匹配<when>中的添加,一旦匹配马上结束;若到找不到匹配项,将执行<other>中的语句;可以理解为<if>是 && 关系 <choose>是 || 关系
<!-- 查询学生list,like姓名、或=性别、或=生日、或=班级,使用choose --> <select id="getStudentListChooseEntity" parameterType="StudentEntity" resultMap="studentResultMap"> SELECT * from STUDENT_TBL ST <where> <choose> <when test="studentName!=null and studentName!='' "> ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%') </when> <when test="studentSex!= null and studentSex!= '' "> AND ST.STUDENT_SEX = #{studentSex} </when> <when test="studentBirthday!=null"> AND ST.STUDENT_BIRTHDAY = #{studentBirthday} </when> <when test="classEntity!=null and classEntity.classID !=null and classEntity.classID!='' "> AND ST.CLASS_ID = #{classEntity.classID} </when> <otherwise> </otherwise> </choose> </where> </select>【注:以上代码段转载自:http://blog.csdn.net/zenson_g/article/details/10137665】
<foreach>标签:该标签的作用是遍历集合类型的条件
属性:collection=“array” / collection = “list” ----->是数组类型,还是集合类型
item=“ productId ”------> 参数名
open="(" separator="," close=")" ------>开始符号,分隔符号,结束符号
index=“ ” ---->结束下标位置,不配置该参数时,默认为全部遍历
<delete id="deleteByPriKeys" parameterType="java.lang.String"> delete from product where product_Id in <foreach collection="list" item="productId" open="(" separator="," close=")"> #{productId,jdbcType = VARCHAR} </foreach> </delete>
相关文章推荐
- Android调用系统相机和相册
- Google Play In-app Billing错误问题
- AndroidStudio JNI 开发哪些事儿
- android 基础 单例模式,懒汉式,饿汉式
- Qt56 App提交中文字符串到Spring MVC App乱码
- iOS获取通讯录联系人信息
- Android L Settings改动介绍
- ios app上架AppStore注意事项及流程
- Android Studio配置
- android编译命令分析
- Unity3D 鼠标以及触屏移动、缩放控制器(相机)
- android帧动画
- Android View 绘制过程
- Android 动画详解
- Android高级开发之性能优化典范
- Android学习笔记-Activity生命周期
- Android 彻底征服 ListView 二 具有弹性的ListView
- Android Studio:Failed to resolve :junit junit 4.2.2
- Android的Fragment中onActivityResult不被调用的解决方案
- DCloud H5与Android Native的交互--5+ SDK插件开发