您的位置:首页 > 数据库

mybatis使用汇总

2014-12-01 16:26 225 查看
mybatis是一个简单的轻量级框架,偶尔一段时间不用,对其使用又感觉非常生疏了,顾在此总结归纳,以便日后查阅。

1.ognl表达式

if
choose(when,otherwise)
trim
where
set
foreach

<if>标签

<if>标签就是简单的条件判断,利用if语句我们可以实现某些简单的条件选择。

<select id="dynamicIfTest" parameterType="Blog" resultType="Blog">
select * from t_blog where 1 = 1
<if test="title != null">
and title = #{title}
</if>
<if test="content != null">
and content = #{content}
</if>
<if test="owner != null">
and owner = #{owner}
</if>
</select>

在xml中可以调用java方法:
如:
<if test="title != null and title.equals('')">
and title = #{title}
</if>

可改写为:
<if test= "@com.tx.core.util.OgnlUtils@isNotEmpty(title)">
and title = #{title}
</if>

"@com.tx.core.util.OgnlUtils@isNotEmpty(title)"  调用java方法判断title是否为空或空字符。

<choose>标签

<choose>标签的作用就相当于JAVA中的switch语句,基本上跟JSTL中的choose的作用和用法是一样的,通常都是与when和otherwise搭配的。
<select id="dynamicChooseTest" parameterType="Blog" resultType="Blog">
select * from t_blog where 1 = 1
<choose>
<when test="title != null">
and title = #{title}
</when>
<when test="content != null">
and content = #{content}
</when>
<otherwise>
and owner = "owner1"
</otherwise>
</choose>
</select>

<set>标签

<set>标签是用来赋值的,如果包含的语句是以逗号结束的话将会把该逗号忽略,如果set包含的内容为空的话则会出错。有了set元素我们就可以动态的更新那些修改了的字段。
<update id="dynamicSetTest" parameterType="Blog">
update t_blog
<set>
<if test="title != null">
title = #{title},
</if>
<if test="content != null">
content = #{content},
</if>
<if test="owner != null">
owner = #{owner}
</if>
</set>
where id = #{id}
</update>

举例:
如果owner == null,则输出的语句为:       
update  t_blog  set  title = #{title},content = #{content},  where id = #{id}   

此时程序会报错
而使用了<set>标签 ,mybatis会自动优化为:
update t_blog  set  title = #{title},content = #{content}  where id = #{id}



<where>标签

<where>标签是用来控制条件的,如果包含的语句是以and 或 or 开头的话mybatis会将开头的and 或or忽略.
<select id="dynamicWhereTest" parameterType="Blog" resultType="Blog">
select * from t_blog
<where>
<if test="title != null">
title = #{title}
</if>
<if test="content != null">
and content = #{content}
</if>
<if test="owner != null">
and owner = #{owner}
</if>
</where>
</select>

举例:
如果title == null的话,输出语句为:      
select * from t_blog where and content = #{content} and owner = #{owner}

 此时程序会报错
而使用了<where>标签的话,mybatis会自动优化为:
select * from t_blog where content = #{content} and owner = #{owner}

<trim>标签

<trim>标签trim是更灵活的去处多余关键字的标签,他可以实现where和set的效果,事实上trim标签有点类似于replace效果

<select id="select">
select b.* from sys_menu b
<trim prefix="Test" prefixOverrides="AND | OR">
<if test="name != null">
AND b.menu_name like #{name}
</if>
</trim>
</select>

该语句的输出为:
select b.* from sys_menu b Test b.menu_name like ''

此处将前缀AND替换成了Test
trim的属性与描述:

 属性
描述
prefix
前缀覆盖并增加其内容
suffix
后缀覆盖并增加其内容
prefixOverrides
前缀判断的条件
suffixOverrides
后缀判断的条件

<foreach>标签

<foreach>标签是遍历标签,用于遍历List,Array与Map,常用于批量操作。
<select id="dynamicForeachTest" resultType="Blog">
select * from t_blog where id in
<foreach collection="list" index="index" item="item"
open="(" separator="," close=")">
#{item}
</foreach>
</select>

其中传入参数为List类型(List类型的传入参数用"list"做Key)
如传入的List参数为:
List list = new ArrayList();
list.add(1);
list.add(2);

则输入打印的语句为:
select * from t_blog where id in(1,2)

<foreach>标签中属性与描述:

属性描述
item循环体中的具体对象。支持属性的点路径访问,如item.age,item.info.details。

具体说明:在list和数组中是其中的对象,在map中是value。

该参数为必选。
collection要做foreach的对象,作为入参时,List<?>对象默认用list代替作为键,数组对象有array代替作为键,Map对象用map代替作为键。

当然在作为入参时可以使用@Param("keyName")来设置键,设置keyName后,list,array,map将会失效。 除了入参这种情况外,还有一种作为参数对象的某个字段的时候。举个例子:

如果User有属性List ids。入参是User对象,那么这个collection = "ids"

如果User有属性Ids ids;其中Ids是个对象,Ids有个属性List id;入参是User对象,那么collection = "ids.id"

上面只是举例,具体collection等于什么,就看你想对那个元素做循环。

该参数为必选。
separator元素之间的分隔符,例如在in()的时候,separator=","会自动在元素中间用“,“隔开,避免手动输入逗号导致sql错误,如in(1,2,)这样,该参数可选。
openforeach代码的开始符号,一般是(和close=")"合用。常用在in(),values()时。该参数可选。
closeforeach代码的关闭符号,一般是)和open="("合用。常用在in(),values()时。该参数可选。
index在list和数组中,index是元素的序号,在map中,index是元素的key,该参数可选。

2.传值

 #{name}与${name}的区别:

#{name} 占位符,带类型,相当于预编译传递值。
${name}  原样输出,不带类型,可作为sql语句,一般用于动态查询表名,字段名;不建议用来做条件查询,因为容易被sql注入。

传递List、Array参数:

List类型以   list   做 key(collection的值) ,直接用   list   来访问。
Array类型以 array 做 key (collection的值),直接用 array 来访问。

List示列:

<select id="dynamicForeachTest" resultType="Blog">
select * from t_blog where id in
<foreach collection="list" index="index" item="item"
open="(" separator="," close=")">
#{item}
</foreach>
</select>


Array示例:

<select id="dynamicForeachTest" resultType="Blog">
select * from t_blog where id in
<foreach collection="array" index="index" item="item"
open="(" separator="," close=")">
#{item}
</foreach>
</select>


传递实体或Map:

通过 #{属性名} 直接访问属性.

Map:

<select id="selectTeacher" parameterType="java.util.Map"
resultType="com.myapp.domain.Teacher">
select * from Teacher where c_id=#{id} and sex=#{sex}
</select></span>


bean:

<select id="dynamicIfTest" parameterType="Blog" resultType="Blog">
select * from t_blog where 1 = 1
<if test="title != null">
and title = #{title}
</if>
<if test="content != null">
and content = #{content}
</if>
<if test="owner != null">
and owner = #{owner}
</if>
</select>


传递多个参数:

1.添加至Map中,作为Map传递。

2.MyBatis还提供了一个使用注解来参入多个参数的方式。这种方式需要在接口的参数上添加@Param注解:

java:

public List<Teacher> selectTeacher(@Param(value="id") String id,
@Param(value="sex") String sex);


XML:

<select id="selectTeacher"  resultType="com.myapp.domain.Teacher">
select * from Teacher where c_id=#{id} and sex=#{sex}
</select>

3.子查询

在<resultMap>标签中可以定义<collection>

<?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="com.myapp.mapper.UserMapper">
<select id="getUserList" resultMap="userdetailResult">
SELECT
u.id as user_id,
u.name as user_name,
u.create_date,
r.id as role_id,
r.name as role_name
FROM t_user u
LEFT JOIN t_user_role ur ON(u.id=ur.user_id)
LEFT JOIN t_role r ON(r.id=ur.role_id) where u.id=1
</select>
<resultMap id="userdetailResultNew"  type="User">
<id property="id"  column="user_id" />
<result property="name" column="user_name"/>
<result property="createDate" column="create_date"/>
<collection property="roles"  ofType="Role" javaType="ArrayList">
<id property="id"  column="role_id"/>
<result property="name"  column="role_name"/>
</collection>
</resultMap>
<resultMap id="roleResult" type="Role">
<id property="id"  column="role_id"/>
<result property="name"  column="role_name"/>
</resultMap>
<resultMap id="userdetailResult"  type="User">
<id property="id"  column="user_id" />
<result property="name" column="user_name"/>
<result property="createDate" column="create_date"/>
<collection property="roles"  ofType="Role" javaType="ArrayList" resultMap="roleResult"/>
</resultMap>
</mapper>

<collection property="Java属性名" ofType="另一Java类名"  column="关联主键ID(用于嵌套查询SQL语句传入参数,多个用逗号分开)" select="另一个select映射SQL的ID"/>

 

4.TypeHandler:自定义的类型转换器(转载)

为什么要用转化器:

有这样一个需求

有一个布尔型的字段需要保存到数据库中,但是数据库不支持布尔类型,因此采用一位字符(char(1))来存储这个布尔值,javabean中仍然采用boolean类型。

问题:

我们采用mybatis作为持久层框架,但是就有一个问题,数据库中使char型,而程序中是boolean型,如何实现数据类型自动转换?
解决办法

 

mybatis提供了对自定义的类型转换器(typeHandler)的支持,因此我们可以自己编写类型转换器来实现这一自动转换的功能。

实现步骤

第一步:编写自定义类型转换器

Java:

/**
*
*/
package test.atfm.persistence.mybatis.handler;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;

/**
* @author
* java中的boolean和jdbc中的char之间转换;true-Y;false-N
*/
public class BooleanTypeHandler implements TypeHandler {

/* (non-Javadoc)
* @see org.apache.ibatis.type.TypeHandler#getResult(java.sql.ResultSet, java.lang.String)
*/
@Override
public Object getResult(ResultSet arg0, String arg1) throws SQLException {
String str = arg0.getString(arg1);
Boolean rt = Boolean.FALSE;
if (str.equalsIgnoreCase("Y")){
rt = Boolean.TRUE;
}
return rt;
}

/* (non-Javadoc)
* @see org.apache.ibatis.type.TypeHandler#getResult(java.sql.CallableStatement, int)
*/
@Override
public Object getResult(CallableStatement arg0, int arg1)
throws SQLException {
Boolean b = arg0.getBoolean(arg1);
return b == true ? "Y" : "N";
}

/* (non-Javadoc)
* @see org.apache.ibatis.type.TypeHandler#setParameter(java.sql.PreparedStatement, int, java.lang.Object, org.apache.ibatis.type.JdbcType)
*/
@Override
public void setParameter(PreparedStatement arg0, int arg1, Object arg2,
JdbcType arg3) throws SQLException {
Boolean b = (Boolean) arg2;
String value = (Boolean) b == true ? "Y" : "N";
arg0.setString(arg1, value);
}
}


第二步:注册类型转换器

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="db.properties"></properties>

<typeHandlers>
<typeHandler javaType="Boolean" jdbcType="varchar2"
handler="test.atfm.persistence.mybatis.handler.BooleanTypeHandler" />
</typeHandlers>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>
</configuration>


在 mybatis.xml 配置文件的<configuration> 标签中加入:

<typeHandlers>
<typeHandler javaType="Boolean" jdbcType="CHAR"
handler="test.atfm.persistence.mybatis.handler.BooleanTypeHandler" />
</typeHandlers>


属性及含义

javaTypejava类型,要转化的类型
jdbcType数据库类型,返回的类型
headler转化器的路径

第三步: 指定类型转换

<pre class="html" name="code"><?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">

<mapper namespace="test.atfm.persistence.mybatis.TestMapper">
<resultMap type="TestBean" id="TestBeanMap">
<id property="tname" column="tname" />
<result property="isCancel" column="iscancel" javaType="Boolean"
jdbcType="varchar2"/>
</resultMap>
<select id="selectTest" resultMap="TestBeanMap">
select * from t_test
</select>

<insert id="insertTest" parameterType="TestBean">
insert into
t_test
(
tname,
iscancel
)
values
(
#{tname},
#{isCancel jdbcType="varchar2" javaType="java.langBoolean"
handler="test.atfm.persistence.mybatis.handler.BooleanTypeHandler"}
)
</insert>
</mapper>

如有总结有误或有什么建议,欢迎指点批评,希望与大家一起交流、成长。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息