最近工作比较闲,维护一个政府机关的短信发送平台,大部分业务逻辑都在Oracle数据库上,但自己明明应聘的是Java开发啊!!!整天写存储过程的我还是有一颗写高级语言的心啊!!!好吧!!!先找个数据库方面的框架学起来吧!

  手头项目比较老,还在用ibatis,就找了它的后继者Mybatis3来学习(3.3.0 released,24 May 2015)。

  学习的期望是:

  1. 理解Mybatis相比JDBC最大的优点。
  2. 自己动手搭建Mybatis框架。

  从这几个部分理解:

  1. Mybatis与ibatis的不同
  2. XML配置
  3. XML映射文件
  4. 动态SQL

  没耐心的可以直接跳到最后看总结。

  找来官方文档(还好有中文的)就读起来。

每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为中心的。我们可以从 SqlSessionFactory 中获取 SqlSession ,SqlSession 完全包含了面向数据库执行 SQL 命令所需的所有方法。

  我认为 SqlSessionFactory 相当于 ibatis中的SqlMapClient ,因为后者的方法中也有一个openSession()。SqlSession 相当于ibatis中的 SqlMapSession。

  相比之下,Mybatis采用更清晰并且类型安全的方式来执行SQL映射。

 SqlSession session = sqlSessionFactory.openSession();
try {
BlogMapper mapper = session.getMapper(BlogMapper.class);
Blog blog = mapper.selectBlog(101);
} finally {
session.close();
}

更清晰安全的方式

  对于简单的增删改查,这只需要在Java中添加注解(复杂的映射文档中说了最好还是在XML中定义)

 package org.mybatis.example;
public interface BlogMapper {
@Select("SELECT * FROM blog WHERE id = #{id}")
Blog selectBlog(int id);
}

通过@Java注解实现

  当然,在ibatis中通过XML定义SQL语句映射的方式也是支持的。

  XML映射文件是mybatis的重点。

 <select id="selectPerson" parameterType="int" resultType="hashmap">
SELECT * FROM PERSON WHERE ID = #{id}
</select>

SQL映射文件

  跟ibatis很像有木有~不同的是这里用#{parameter}来表示映射字段 而ibatis中是#patameter#。而在JDBC中,你需要像这样来映射字段,并且在得到结果集后一一手动映射到对象。这就是Mybatis框架可以节省代码的地方。

  在JDBC中是这样子的:

 String selectPerson = "SELECT * FROM PERSON WHERE ID=? and name = ? and age = ?";
PreparedStatement ps = conn.prepareStatement(selectPerson);
ps.setInt(1,id);
ps.setString(2,name);
ps.setInt(3,age);
ResultSet res = ps.executeQuery();
while(res.next()){
  Student stu = new Student();
  stu.setId(res.getInt(1));
  stu.setName(res.getString(2));
  stu.setAge(res.getInt(3));
}

JDBC代码示例

  而Mybatis中是这样子的:

 <typeAliases>
<typeAlias alias="stu" type="domain.Student"/>
</typeAliases>
<select id="selectStudent" resultType="stu">
select id, username, password
from users
where id = #{id}
</select>

Mybatis代码示例

  除去标签占去的代码行数,当映射对象的属性更多时,代码量差距会更加明显。

  select中可以设置属性,常用的就是id(命名空间中的唯一标识符,用来被引用)、parameterType(传入参数的完整包名或别名)、resultType(返回结果的完整报名或别名,不和resultMap同时使用)、resultMap(外部resultMap的命名引用,稍后会详细讲)、flushCache(清空缓存)、useCache(使用缓存)、timeout(等待数据库返回结果的最大时间)

  对于Oracle,一般在插入中都需要获得主键,可以使用<selectKey>标签来获得主键ID。

 <!--Mybatis中Oracle的主键使用方法 -->
<insert id="insertSMSInpojo" parameterType="SMSINPojo">
<selectKey keyProperty="id" resultType="int">
select s_sms_in.nextval from dual
</selectKey>
insert into sms_in(
msgContent,
mobile,
destNO,
linkId,
curTime
) values(
#msgContent#,
#mobile#,
#destNO#,
#linkId#,
#curTime#
)
</insert>

Oracle主键使用

  对于参数映射,Mybatis中提供了强大的resultMap来支持。对于简单的查询(列名与属性名一一对应),你可以使用hashmap或pojo类来实现

 <!-- In mybatis-config.xml file -->
<typeAlias type="com.someapp.model.User" alias="User"/> <!-- In SQL Mapping XML file -->
<select id="selectUsers" resultType="User">
select id, username, hashedPassword
from some_table
where id = #{id}
</select> or use this <select id="selectUsers" resultType="map">
select id, username, hashedPassword
from some_table
where id = #{id}
</select>

Hashmap pojo类实现

  如果列明没有精确匹配,可以通过 as 来设置别名

 <select id="selectUsers" resultType="User">
select
user_id as "id",
user_name as "userName",
hashed_password as "hashedPassword"
from some_table
where id = #{id}
</select>

  或是通过更强大的resultMap来解决,因为实现了列名和属性名分离,更易于在不同语句中重用

 <resultMap id="userResultMap" type="User">
<id property="id" column="user_id" />
<result property="username" column="user_name"/>
<result property="password" column="hashed_password"/>
</resultMap> <select id="selectUsers" resultMap="userResultMap">
select user_id, user_name, hashed_password
from some_table
where id = #{id}
</select>

ResultMap用法

  

  而且不仅是代码量的差距,我也相信你一定维护过像这样 逗号,拼接 的代码:

 public void insertIntoHddx(TbSmsSync tbsyncpojo, SmsTaskPojo smstask, int num, String optionList) {
String hddxSql = "insert into sms_hddx values(";
hddxSql += tbsyncpojo.getTaskId() + ",";
hddxSql += "'" + smstask.getTaskName() + "',";
hddxSql += "'" + tbsyncpojo.getMsgContent() + "',";
hddxSql += "0 ,";
hddxSql += "to_date('" + smstask.getSendTime() + "','yyyy-mm-dd hh24:mi:ss') ,";
hddxSql += num + ")";
String[] items = optionList.split(";");
for (String item : items) {
String[] itemIdAndName = item.split(",");
String itemId = itemIdAndName[0];
String itemName = itemIdAndName[1];
String searchItemSql = "insert into sms_hddx_option values(";
searchItemSql += "'" + itemId + "',";
searchItemSql += "'" + itemName + "',";
searchItemSql += "0,";
searchItemSql += tbsyncpojo.getTaskId() + ")";
JdbcTemplate template = dbTemplate.getJdbcTemplate();
template.execute(searchItemSql);
}
JdbcTemplate template = dbTemplate.getJdbcTemplate();
template.execute(hddxSql);
}

逗号,拼接

  或是这样 #动态字段映射# 的代码

 public PageInfo showTasks(SearchSMS searchSMS, int page) {
String sql = "select id from SMS_TASK sms_task where id = ? "
}
if (StringUtils.isNotBlank(searchSMS.getEndtime())) {
sql += "and createtime < to_date('" + searchSMS.getEndtime() + "','yyyy-mm-dd') + 1 ";
}
if (StringUtils.isNotBlank(searchSMS.getSendContent())) {
sql += "and id in (select TASKID from SMS_SYNC where TASKID=sms_task.id and msgcontent like '%" + searchSMS.getSendContent() + "%')";
}
if (StringUtils.isNotBlank(searchSMS.getSendPhone())) {
sql += "and id in (select TASKID from SMS_SYNC where TASKID=sms_task.id and mobile like '%" + searchSMS.getSendPhone() + "%')";
}

#动态字段映射#

  你一定感受过为了一个逗号而抓狂的经历,拼接的时候提醒自己一定不能忘了添加前后的空格和删除句末的逗号。

  幸运的是,通过动态SQL这样的问题在Mybatis中不复存在。通过<where>来智能识别语句前后的and/or,<set>来识别语句前后的逗号,或使用<trim>来自定义实现。

  通过<if test>来判断字段是否为空,<choose><when><otherwise>来实现类似switch……case的效果,<foreach>来实现集合的遍历,这里介绍了动态SQL。

   总结:Mybatis框架优越之处在于使用XML映射文件替代了JDBC中手工设置属性,降低SQL代码耦合性,将动态SQL与其他Java代码分离,使得代码看起来更加整洁并有利于重用;提供缓存、自动映射功能,并通过一系列设置合理的默认值来简化开发者的工作。

  

Mybatis3 框架理解的更多相关文章

  1. ssm框架理解

    SSM框架理解 最近两星期一直在学JavaEE的MVC框架,因为之前学校开的JavaEE课程就一直学的吊儿郎当的,所以现在真正需要掌握就非常手忙脚乱,在此记录下这段时间学习的感悟,如有错误,希望大牛毫 ...

  2. SSM框架理解(转)

    SSM框架理解 最近两星期一直在学JavaEE的MVC框架,因为之前学校开的JavaEE课程就一直学的吊儿郎当的,所以现在真正需要掌握就非常手忙脚乱,在此记录下这段时间学习的感悟,如有错误,希望大牛毫 ...

  3. mybatis中两种取值方式?谈谈Spring框架理解?

    1.mybatis中两种取值方式? 回答:Mybatis中取值方式有几种?各自区别是什么? Mybatis取值方式就是说在Mapper文件中获取service传过来的值的方法,总共有两种方式,通过 $ ...

  4. Flask 框架理解(一)

    Flask 框架理解(一) web 服务器 , web 框架 以及 WSGI 这里说的 web 服务器特指纯粹的 python HTTP 服务器(比如 Gunicorn,而不是 Apache,Ngin ...

  5. 遵循统一的机器学习框架理解高斯混合模型(GMM)

    遵循统一的机器学习框架理解高斯混合模型(GMM) 一.前言 我的博客仅记录我的观点和思考过程.欢迎大家指出我思考的盲点,更希望大家能有自己的理解. 本文参考了网络上诸多资料,特别是B站UPshuhua ...

  6. 遵循统一的机器学习框架理解SVM

    遵循统一的机器学习框架理解SVM 一.前言 我的博客仅记录我的观点和思考过程.欢迎大家指出我思考的盲点,更希望大家能有自己的理解. 本文参考了李宏毅教授讲解SVM的课程和李航大大的统计学习方法. 二. ...

  7. Web框架理解

    目录 1.web框架理解     2.http工作原理     3.通过函数实现浏览器和服务端通信案例     4.服务器程序和引用程序理解     5.jinja2渲染模板案例     6.Djan ...

  8. MVVM框架理解

    MVC框架 将整个前端页面分成View,Controller,Modal,视图上发生变化,通过Controller(控件)将响应传入到Model(数据源),由数据源改变View上面的数据. 整个过程看 ...

  9. Linux图像系统框架-理解X11与Qt的层次结构

    转:http://blog.csdn.net/kjfureone/article/details/52848550 1. 前言 图形子系统是linux系统中比较复杂的子系统之一:对下,它要管理形态各异 ...

随机推荐

  1. 关于COOKIE使用过程为NULL

    关于COOKIE使用过程中的一个小问题在程序中要用到COOKIE,网站website/login/login.aspx传值userID到 website/web/tab/web.aspx中的FRAME ...

  2. Convert Sorted List to Binary Search Tree ------C++ 递归创建平衡二叉查找树

    有序链表 0->1->2->3->4->5 转换为一个二叉排序树.我们在此创建一个平衡二叉排序树 1.先找链表到中间的节点 2.中间节点的val创建一个新的树节点Tree ...

  3. Flex 按钮添加图标

    第一种是在Flex应用中创建一个变量,利用[Bindable]和[Embed] ,在代码中以参数形式传入制定图标(icon)的路径,然后利用类似icon="{Icon}"的代码嵌入 ...

  4. 九款让WordPress成为赚钱利器的广告插件

    Blog有了很不错的流量后,看到别人博客挂的广告挣$,是否也有挂广告的冲动,但是,修改wordpress模版去让人不厌其烦,布局.样式都的重新修改一下,为了不那么麻烦,笔者整理的几款wordpress ...

  5. PE框架学习之道:PE框架——style的配置

    1.在style.xml中定义style     <style id="NumberStyle"> <setting> <param name=&qu ...

  6. Js动态设置Img大小

    function ResizePic() {        $('img').each(function () {            var maxWidth = 450; // 图片最大宽度   ...

  7. javascript技术难点之this、new、apply和call详解

    讲解this指针的原理是个很复杂的问题,如果我们从javascript里this的实现机制来说明this,很多朋友可能会越来越糊涂,因此本篇打算换一个思路从应用的角度来讲解this指针,从这个角度理解 ...

  8. BZOJ 2015: [Usaco2010 Feb]Chocolate Giving( 最短路 )

    裸最短路.. ------------------------------------------------------------------------------------ #include ...

  9. js的初始化

    在项目中遇到了类似于这样的js, myinit.js文件: var wyl_01 = { tip : function(msg){ alert('i am a tip,msg:'+msg); }, t ...

  10. eclipse没有New Java Class的解决办法

    配置之前的截图: 配置步骤: