mybatis使用小贴士

分享了以下tips:

一、事务管理
二、xml配置sql代码段
三、#和$的区别
四、注意对<、>做转义
五、依据字符串是否为空,动态组织sql语句
六、使用自定义的类型转换器
七、resultMap的复用


一、事务管理

用户执行一个动作,后台需依次更新多个表,如果其中有一个更新失败,则要回滚之前的更新。这种情况,就是事务回滚。
要支持事务操作,需要:

1、确保数据库表的类型是InnoDB,而不是MyISAM

(MyISAM不支持事务,这是一个坑,之前总结过 http://blog.csdn.net/lizeyang/article/details/9280253)

2、所有更新操作完成后,再执行commit

例如:
SqlSession session = getSqlSession();
int sqlResult = session.insert("insert a table", po);
int sqlResult = session.update("update b table", po);
//这时,前面的insert和update还没真正执行
session.commit();
//commit后,db才真正更新
session.close();

 

二、xml配置sql代码段

mybatis需要通过xml配置每次db操作的sql语句。如果多个sql语句中,包含了相同的sql语段,怎么办呢?复制粘贴?这显然不是一个好习惯。建议配置代码段,然后每个sql直接引用这个代码段。
语法:

1、在xml中先用<sql>这个标签,包装代码段,配置id

     <sql id="getFeedBackList_fragment">
from t_comment where refer_type = #{type} and
refer_id = #{referId} 
     </sql>

2、在需要这个代码段的地方,通过<include refid="id"/>语句,引入这个sql

例如
<select id='getFeedBackList' parameterType='map' resultMap='feeback'>
select id
<include refid="getFeedBackList_fragment"/>
order by
create_time desc
</select>


三、#和$的区别

当sql中有一些参数,需要调用时动态传入时,就需要在sql中写变量,调用时再传入变量。mybatis中,#和$,都是变量的修饰符。一般推荐用#。
#相当于jdbc中,对prepareStatement做set参数的操作,而$则相当于拼接了sql语句,再执行statament。prepareStatement、statament的区别,具体可以在网上搜下,这里就不赘述了。

四、注意对<、>做转义

其实,写xml文件,都得注意这个问题,要将>转义成 &gt; 要将<转义成&lt;  。我们在写sql时,经常要用到<、>来筛选sql结果,更要牢记这个注意项。

五、依据字符串是否为空,动态组织sql语句

mabatis xml配置sql,对字符串的处理能力不够强大,对于判空这样常见的需求,还是得通过para!= null and para != ''来完成,没有相关的内建函数。
<if test="para!= null and para != '' ">sql语句</if>

六、使用自定义的类型转换器

假设有一个字段,数据库字段类型,是timestamp,当赋值到javabean时,希望变成对应的long值。怎么做呢?最原生态的一种选择,赋值给bean时,就是timestamp类型,之后再重新遍历数据,改成long值。这种做法,显然很搓,增加了业务逻辑的代码量,不利于转化逻辑复用。
其实,mybatis本身就支持自定义类型转换器,可以很好地支持这种需求。这里主要想告诉你,mybatis是有这种能力的,更详细的内容,可以再看官方教程。这里简单贴下我的示例。

1、configuration xml文件配置

<configuration>
 ……

<typeHandlers>
<typeHandler handler="test.TimeTypeHandler"
javaType="Long" jdbcType="TIME" />
</typeHandlers>
……
</configuration>

2、自定义类型转换器

上面的handle为test.TimeTypeHandler,因此工程中,要写对应的test.TimeTypeHandler.java。转换逻辑,就在这个java文件中
package test;
public class TimeTypeHandler implements TypeHandler<Long>
{
private final String TIME_TYPE = "yyyy-MM-dd HH:mm:ss";

public long strToLongTime(String dateStr)
{
if (null == dateStr)
return 0L;

SimpleDateFormat sdf = new SimpleDateFormat(TIME_TYPE);
Date date = new Date();
try
{
date = sdf.parse(dateStr);
}
catch (ParseException e)
{
e.printStackTrace();
}
if (date == null)
return 0L;

System.out.println(date);
return date.getTime();
}

public Long getResult(ResultSet arg0, String arg1) throws SQLException
{
String datestr = arg0.getString(arg1);
return strToLongTime(datestr);
}

public Long getResult(ResultSet arg0, int arg1) throws SQLException
{
String datestr = arg0.getString(arg1);
return strToLongTime(datestr);
}

public Long getResult(CallableStatement arg0, int arg1) throws SQLException
{
String datestr = arg0.getString(arg1);
return strToLongTime(datestr);
}

public void setParameter(PreparedStatement arg0, int arg1, Long arg2, JdbcType arg3) throws SQLException
{
if (arg2 == null)
{
arg2 = 0L;
}

Date date = new Date(arg2);
SimpleDateFormat sdf = new SimpleDateFormat(TIME_TYPE);
String datetime = sdf.format(date);
arg0.setString(arg1, datetime);
}

}

 

3、mapper xml配置

<mapper namespace="xxxx">
……
     //这里定义了ExpDownloadPo这个sql查询结果,要映射到java bean :test.ExpDownloadPo
<resultMap id="ExpDownloadPo"  type="test.ExpDownloadPo">
<id property="id" column="id" />
               //first_download_time这个数据,在赋值到firstDownloadTime时,要转转换,从jdbc的time型,转换成javaType的long型,具体怎么转换,因为前面第一点,定义了<typeHandlers><typeHandler handler="test.TimeTypeHandler" javaType="Long" jdbcType="TIME" /></typeHandlers>,因此会自动使用test.TimeTypeHandler这个转换器

<result property="firstDownloadTime" column="first_download_time" javaType="Long" jdbcType="TIME"/>
<result property="lastDownloadTime" column="last_download_time" javaType="Long" jdbcType="TIME"/>
</resultMap>
……
</mapper >

 



七、resultMap的复用

我们一般会定义多个mapper.xml文件,将不同的功能,放到不同的xml中。如果mapper文件A需要使用mapper文件B中所定义的resultmap时,是可以直接使用的,请勿在文件B中重复定义resultmap。
具体使用方法是:
例如mapper A的namespace是com.blog.test,其中定义的resultmapid是testbean,那么,在文件B中,如果要用到这个resultmap,则用它的全名即可,也就是com.blog.test.testbean(namespace+resultmapid)

mapper文件A

<mapper namespace="com.blog.test">
……
<resultMap id="testbean"  ></resultMap>
</mapper>

mapper文件B

<mapper namespace="B">
<select id="mysql" parameterType="map" resultMap="com.blog.test.testbean">
</mapper>

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值