最近工作比较闲,维护一个政府机关的短信发送平台,大部分业务逻辑都在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. MFC模式对话框与非模式对话框 消息处理顺序

    对话框有两种创建方式:DoModal和Creat. 其中DoModal创建的是模态的对话框,而Creat创建的是非模态的对话框下面总结下他们的不同. 对于模态的对话框,在该对话框被关闭前,用户将不能在 ...

  2. 从Xib文件加载UIView的5种方式

    在不同的Xib文件中最容易维护的是定义的视图,因此对于从Xib文件中加载UIView来说一个方便的流程是非常重要. 在过去的几年里我发现唯一易于管理创建和维护视图(或者任何界面元素,通常会更多)方式就 ...

  3. 为什么webview.loadUrl("javascript:function() ")不执行?

    这几天搞webview 但是常常有时候会出现webview.loadurl 没有反映的情况对现在的分析如下: 情况一:webview.loadurl 的加载是在另一个线程中执行必须要在webview加 ...

  4. xen虚拟机操作整理

    1,登陆物理机器 2,查看物理机建立虚拟机的列表 root:~ # xm li Name ID Mem VCPUs State Time(s) Domain-0 0 49450 8 r----- 52 ...

  5. input autocomplete 下拉提示+支持中文

    js 代码: $.getJSON("/Foreign/Getforeign_routeEndPoint", function (data) {            $(" ...

  6. Jenkins持续集成相关文章整理

    构建iOS持续集成平台(一)——自动化构建和依赖管理 构建iOS持续集成平台(二)——测试框架 构建iOS持续集成平台(三)——CI服务器与自动化部署 使用Jenkins搭建iOS开发的CI服务器 一 ...

  7. ACE6.2.0下载HTTP服务器文件

    #include "ace/Log_Msg.h" // ACE_DEBUG的宏定义在这里.#include "ace/OS.h"#include "a ...

  8. nvl与 is not null的区别等

    Oracle中: Select Aae140 From Ab07 Where Aab001 = Pi_Aab001 And Aae002 = Pi_Aae002 ) 1 nvl(aaz288,0)&g ...

  9. C语言回溯算法解决N皇后问题

    回溯算法的模型是 x++, not satisfy ? x-- : continue. 代码中x作列号,y[x]保存第x列上皇后放置的位置. #include<stdio.h> #incl ...

  10. Lake Counting(poj 2386)

    题目描述: Description Due to recent rains, water has pooled in various places in Farmer John's field, wh ...