您的位置:首页 > 其它

模仿与学习MyBatis - 1.1 综述:MyBatis核心功能

2016-12-05 20:50 369 查看
本文收录于模仿与学习MyBatis系列

系列的开始

在本系列的一开始,我还不打算记录一个非常宏大的MyBatis世界的整体结构。原因很简单,包括我在内的大部分初学者,在刚接触这类框架前,都是一头雾水的。像我当初去请教一些前辈,“MyBatis要怎么学呢?”直接被一句“去把源码和官方文档看一遍”给堵了回来——那十几个大模块以及之间的交互,看了就让人厌烦了,我还不懂MyBatis是什么的情况下,又怎么能体会这些架构和功能的意义和精妙呢?我想这种回答是不够负责任的。

如果换作是我,以自己的学习经历来说,我觉得不妨从最关心、最基础的部分说起,比如:

一、 MyBatis拿来干什么?

MyBatis核心功能可以总结为:当我调用一个Java方法时,等于在指定的数据库,执行若干sql操作,并把执行结果转为一个Java类。 这段话可能有点绕 ,具体含义可以参考下面代码里写的:

public interface BookMapper {
@Select("select * from book where author=#{name}")
List<Book> findByName(String name);

@Delete("delete from book where author=#{name}")
int deleteByName(String name);
}

public void test(SqlSession session) {
BookMapper mapper = session.getMapper(BookMapper.class);
List<Book> book = mapper.findByName("test");
}


注意test(session)方法。我们在MyBatis框架中,直接从一个接口(注意这是一个接口不是类),生成了一个可用的对象mapper。并且当我们执行mapper的方法findByName(“Mark”)时,等同于在我们的数据库里执行了
select * from book where author=Mark
,把book表中author=Mark的书全部返回了出来,返回了一个List。(此处Book类里的成员变量需与数据库中的book一一对应)

二、怎么执行sql语句

当我们要执行sql语句的时候,在Java代码中到底做了什么呢?

首先需要连接到指定的数据库(得到Connection)

从连接中获取sql容器(得到Statement)

用此容器执行一条sql语句(得到ResultSet)

结果的ResultSet中可以取出表里的列名与对应的值。由于一共只有三个操作,就列一下代码吧:

Connection conn = getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);


三、Session又是什么

经常在使用框架时看到Session,那这个Session又是个什么东西呢?先看下图:



当我们通过数据库信息(DataSource)访问数据库,并从数据库取到一个连接(Connection)出来时,业务的执行还没有真正开始。我们需要使用这个连接,执行一系列的sql语句,希望回滚、提交等等。而且最最重要的是,通常数据库的返回值是这样的:



而实际上我想要的是一个这样的Java类:



那么谁来负责:使用连接,执行sql,执行事务,把结果转为Java类等工作呢?在常规的这类框架中,我们把这一系列操作,全部抽象到与一个类对应,这个类的开始就是一切的开始,这个类的结束就是这一切的结束。通常我们将这个类称为Session,一个Session仅拥有一个对应的数据库连接。

四、MyBatis中的Session

<T> T selectOne(String statement);
<T> T getMapper(Class<T> type);


虽然打开MyBatis的SqlSession接口,可以看到非常多方法,但归纳出来其实只有以上两种。一是可以直接代入sql执行,另一种用法如下:

public interface BookMapper {
@Select("select * from book where name=#{name}")
Book findByName(String name);
}

public void test(SqlSession session) {
// 在session中生成一个可用的类
BookMapper mapper = session.getMapper(BookMapper.class);
Book book = mapper.findByName("test");
}


可以看到,这里使用一个Session与一个Mapper.class,生成了一个可用的mapper对象,只要mapper对象执行方法,就对应的执行了方法上的注解内容。

它是怎样实现的呢?其实非常简单,生成mapper对象时,在它里面存了session值。这样在执行
mapper.findByName("xxx")
时,实际上调用的是
session.selectOne("select * from book where name=xxx")
,大体流程如下图:



我们可以发现,MyBatis的核心功能其实不难。无非就是动态代理和jdbc操作,在后续的文章里会逐个解释这些概念,但在下一篇中,先实现一个基本的Session类。

下一篇:模仿与学习MyBatis - 1.2 DataSource与Session
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: