首先要了解以下内容:
1_Mybatis涉及到的类
- 实体类 : 配置信息 (Configuration.java), SQL语句信息(Mapper,java)
- 核心类: SqlSessionFactoryBuilder ; SqlSessionFactory; SqlSession(接口) ;DefaultSqlSession(实现类)
- 工具类: 用于解析配置文件(包含SQL和mybatis核心配置文件)的 XMLConfigBuilder.java , 执行器的类,专门用于执行SQL语句 . Excutor.java
2_然后再了解这些类主要是干什么的,以及每个类都是如何实现的,涉及到了哪些设计模式
- 核心类
2.1_SqlSessionFactoryBuilder.java 构建者模式:包含创建SqlSessionFactory的方法,这个方法解析了以流的形式进来的配置文件信息
2.2_SqlSessionFactory.java 工厂模式:用于创建DefaultSqlSession对象,并把配置信息传递下去
2.3_SqlSession.java 一个接口 , 具体实现需要DefaultSqlSession.java
2.4_DefaultSqlSession.java 利用动态代理(代理模式)获取一个动态代理对象,从而实现dao层接口的方法的调用
/**
* 创建dao接口的实现类(动态代理对象
* Proxy.newProxyInstance(classloader,interfaces,invocatioHandler)
* 创建userDao的动态代理对象
* 参数 : 接口的字节码对象
*/
public <T> T getMapper(Class clazz) throws Exception {
MapperProxyFactory factory = new MapperProxyFactory(this);
return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class[] {clazz}, factory);
}
为了方便查看,把invocationhandler接口实现,单独写成一个实现类(MapperProxyFactory.java),具体代码如下
/**
* 定义增强的业务逻辑:
* 完成数据库操作
*
*/
public class MapperProxyFactory implements InvocationHandler {
private DefaultSqlSession sqlSession;
public MapperProxyFactory(DefaultSqlSession sqlSession) {
this.sqlSession = sqlSession;
}
/**
* 使用基于动态代理的mybaits
* 约定
* 1.namespace = 当接口的全限定类名
* 2.id = 当前执行的方法名称
*
*
* invoke : 定义增强的业务逻辑代码
* proxy: 动态代理对象的引用
* method: 当前执行的方法对象
* args: 当前执行方法的所有参数
*
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//当前接口的全限定类名
String namespace = proxy.getClass().getGenericInterfaces()[0].getTypeName();
//当前执行的方法名称
String id = method.getName();
//唯一标识
String mapperId = namespace+"."+id;
//查询
return sqlSession.selectList(mapperId);
}
- 实体类
2.5_Configuration.java (数据库配置信息)
/**
* 核心配置类
* 1.数据库配置信息
* username,password,url,driver
* 2.sql对象的map集合
* key:唯一标识(namespace.id)
* value:sql对象(Mapper)
*
*/
public class Configuration {
private String username;
private String password;
private String url;
private String driver;
/**
* mapper的map集合<String,Mapper>
*
*/
private Map<String,Mapper> mappers;
//get & set方法略
}
2.6_SQL实体类Mapper.java(SQL语句信息:namespace+StatementId)
/**
* 是sql语句的实体类
* sql语句:String
* 返回值类型(实体类的全限定类名):String
*/
public class Mapper {
private String querySql; //sql语句
private String resultType; //返回值类型
//get set 方法略
- 工具类
2.7_Executor.java SQL执行器(执行器的类,专门用于执行SQL语句) 入excuteQuery和excuteUpdate
2.8_XMLConfigBuilder.java 负责解析配置文件(主要是dom4j在起作用)//加载mybatis的配置文件 //对sql的map集合赋值 //解析sq的配置文件
了解了以上哪些内容就知道了mybatis的流程以及为什么下一步是那么做了
3_现在说下mybatis的流程
3.1_首先加载配置文件,通过Resource.getresourceStream("mybatis核心配置文件名.xml").得到一个输入流.
3.2_然后需要把配置信息交给sqlsession , 但是需要sqlsession需要sqlsessionfactory来生产,而sqlsessionfactory需要sqlsessionfactorybuilder来生产,所以需要new一个sqlsessionfactorybuilder.
3.3_得到sqlsession后就可以获取动态代理对象(代理的是usermapper接口)
3.4_获得代理对象后就可以执行具体的数据库操作,并获取结果集
3.5_释放资源(关流,关SqlSession)
代码如下:
try {
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
// 创建ssfb
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
// 创建ssf
SqlSessionFactory factory = builder.build(is);
// 创建ss
SqlSession session = factory.openSession();
// 创建代理对象,获得mapper
UserMapper mapper = session.getMapper(UserMapper.class);
// 执行mapper具体方法
List<User> list = mapper.findAll();
// 对获取到的结果集进行处理遍历
for (User user : list) {
System.out.println(user);
}
session.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
4_总结
其实关于设计模式需要更深入理解,还有一些小疑问比如defaultsqlsession中mapper的调用是为什么要那么做的