最近工作比较闲,维护一个政府机关的短信发送平台,大部分业务逻辑都在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. RESTClient 控件 从服务器获得数据集 REST

    用TRESTClient控件调用REST架构服务 RESTClient控件返回数据集 用到的控件 RESTClient RESTRequest RESTResponseDataSetAdapter p ...

  2. 面试题:对一个正整数n,算得到1需要的最少操作次数

    实现一个函数,对一个正整数n,算得到1需要的最少操作次数.操作规则为:如果n为偶数,将其除以2:如果n为奇数,可以加1或减1:一直处理下去.例子:func(7) = 4,可以证明最少需要4次运算n = ...

  3. APUE学习之---------------进程

    离职了,交接期也有足够的时间了,可以在好好的再看一下APUE,想想上次详细的看还是在两年之前,虽然中间也偶尔会翻出来看看,但是由于工作上交集相对比较少一直没有去细读一下.现在正好是一段空挡期可以好好看 ...

  4. Mysql5.6.24 zip解压缩版配置及修改默认编码方法

    win64位下载地址: http://dev.mysql.com/downloads/file.php?id=456319 下载完毕后解压 配置环境变量 在Path后加上mysql解压后bin文件夹所 ...

  5. poj 3026 Borg Maze bfs建图+最小生成树

    题目说从S开始,在S或者A的地方可以分裂前进. 想一想后发现就是求一颗最小生成树. 首先bfs预处理得到每两点之间的距离,我的程序用map做了一个映射,将每个点的坐标映射到1-n上,这样建图比较方便. ...

  6. 离线安装.NET 3.5小记

    最近为系统新增一个功能,写完以后进行部署,发现在IIS7上部署没有问题,但是IIS6上部署会出现未知情况,具体表现为取不到数据,估计是IIS6和IIS7直接的差异导致程序异常退出. 为了重现异常,在本 ...

  7. 实现JQuery_Accordion功能

    1. 添加AJAX引用 <script type="text/javascript" src="http://ajax.googleapis.com/ajax/li ...

  8. POJ 2250 Compromise(LCS)

    POJ 2250 Compromise(LCS)解题报告 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=87125#proble ...

  9. Eclipse安装反编译插件JD(Java Decompiler)

    JD安装说明:*****Eclipse 插件安装*****1. 在网上搜索并下载jdeclipse_update_site.zip2. Eclipse -> Install New Softwa ...

  10. java 自定义BufferedReader_readLine

    import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import ...