最近工作比较闲,维护一个政府机关的短信发送平台,大部分业务逻辑都在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. http://qt-project.org/wiki/Category:Developing_with_Qt::QtWebKit#ff7c0fcd6a31e735a61c001f75426961

    404: Not Found | Qt Project QtWebKit documentation http://dwz.cn/hr2013

  2. HDU1181【有向图的传递闭包】

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1181 题意很简单. 有用并查集做的.我这里用传递闭包做. 有向图的传递闭包采用Floyd思想,可以判断 ...

  3. Hierarchical Storage structure

    1.hierarchical storage structure      This notion of inserting a smaller, faster storage device (e.g ...

  4. 【翻译自mos文章】oracle支持在RDBMS HOME 下的 符号链接( Symbolic Links)吗?

    oracle支持在RDBMS HOME 下的 符号链接( Symbolic Links)吗? 參考原文: Does Oracle support Symbolic Links in the RDBMS ...

  5. BI商业智能项目中的若干风险要素

    BI商业智能项目应在 “业务驱动,总体规划,统一设计,分期实施” 的总体设计原则下分期实施,采取Agile BI方法论迭代开展,先确保核心功能满足客户需求,在总体规划下不断完善整个系统,以提高可交付性 ...

  6. 【转】windows上自动设置java环境变量的脚本

    转载:http://www.cnblogs.com/flowwind/p/4066146.html 近期打算学习安卓开发,于是乎要准备java开发环境,安装好jdk后,就要 设置java环境变量,ja ...

  7. A.归并排序

    归并排序 (求逆序数) 归并排序:递归+合并+排序 时间复杂度:O(n logn)    空间复杂度:O(n) 用途:1.排序  2.求逆序对数 Description In this problem ...

  8. debian下samba配置

    debian下samba配置  http://blog.chinaunix.net/uid-2282111-id-2113216.html 服务器端配置过程:1. apt-get install sa ...

  9. oracle去除字符串中间的空格

    update AC01 A set A.AAC003 = REGEXP_REPLACE(A.AAC003, '( ){1,}', '') WHERE A.AAC002 IN (SELECT AAC00 ...

  10. r语言之生成规则序列,规则序列函数及用法

    在生成序列时,“:”的优先级最高 (1)从1到20的整数序列: > 1:20 [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 (2) ...