任务一:自定义持久层框架
1. JDBC回顾及问题分析
JDBC问题分析:
2.持久层框架思路分析
使用端:(项目)引入自定义持久层框架的jar包
提供两部分配置信息:数据库配置信息、SQL配置信息(SQL语句、参数类型、返回值类型)
sqlMapConfig.xml:存放数据库配置信息
mapper.xml:存放sql配置信息
自定义框架层本身:(工程)本质就是对JDBC代码进行封装
(1)加载配置文件:根据配置文件路径,加载配置文件成字节输入流,存储在内存中
创建Resource类,方法:InputStream getResourceAsStream(String path)
(2)创建两个JavaBean(容器对象),存放的就是配置文件解析出来的内容
Configuration:核心配置类,存放sqlMapConfig.xml解析出来的内容
MapperStatement:映射配置类,存放mapper.xml解析出来的内容
(3)解析配置文件:dom4j
创建类:SqlSessionFactoryBuilder包含方法build(InputStream in)主要做两件事:
第一: 使用dom4j解析配置文件,将解析出来的内容封装到容器对象中
第二 创建sqlSessionFactory对象,生产SqlSession,这里用到了工厂模式,降低程序间的耦合
(4)创建SqlSessionFactory接口及实现类DefaultSqlSessionFactory,方法openSession()用以生产sqlSession
(5)创建SqlSession接口及实现类DefaultSession,定义对数据库的CRUD操作(selectList、selectOne、update……)
(6)创建Executor接口及实现类SimpleExecutor实现类,query(Configuration,MapperStatement,MapperStatement,Object... params)方法,执 行的就是JDBC代码
3.IPersistence_Test编写
IPersistence_Test可以认为是使用端,首先完成使用端编写
两类配置文件:
sqlMapConfig.xml : 写数据库连接相关的配置信息
XXXMapper.xml : (比如UserMapper.xml) 写特定模块(比如用户模块)的语句信息
XXXMapper.xml中主要完成以下功能:
1.配置真正需要在MySql里面执行的sql语句
2.实现特定语句的定位,也就是需要给sql一个特定标识,即statementId
3.指定返回结果的封装类型
4.指定传入参数的类型
如图,xml配置如下,namespace和id组成唯一标识
sqlMapConfig.xml如下:
为了Resource加载xml文件时只加载一次,就需要把mapper.xml也存放进来,因此需要mapper.xml的全路径
4.Resource类定义
Resources类里面定义一个方法,目的是将配置文件加载成字节输入流,存储在内存中
5.容器对象定义
容器对象:MapperStatement和Configuration,这两个容器对象存放的就是配置文件解析出来的内容
MapperStatement作用是从xxxMapper里面读取内容,所以xxxMapper的各个属性都需要被存储在MapperStatement对应的类属性
Configuration作用是存放的就是sqlMapConfig的内容,其实就是数据库配置信息
6.解析核心配置文件sqlMapConfig以及映射配置文件mapper.xml
解析配置文件:
创建类:SqlSessionFactoryBuilder包含方法build(InputStream in)主要做两件事:
(1) 使用dom4j解析配置文件,将解析出来的内容封装到对象Configuration中,这里会自定义一个XMLconfigBuilder类,用于解析封装
(2) 创建sqlSessionFactory对象,生产SqlSession,即会话对象(增删改查都封装在这里),这里用到了工厂模式,降低程序耦合
7.会话对象sqlSession类定义以及会话对象sqlSession方法定义
sqlSessionFactory 接口及D efaultSqlSessionFactory 实现类
sqlSession 接口及 DefaultSqlSession 实现类,如图,以selectList(),首先初始化Executor对象,然后获取Comfiguration里面存的 xxxMapper.xml转换后的MapperStatement,最后执行执行Executor的query方法
8.查询对象query方法定义
Query方法一共需要六步
1 注册驱动,获取连接
2 getBoundSql获取sql语句,然后转换sql语句,此时需要配置标记解析器来对占位符的解析处理工作,这里直接用了从Mybatis拿的代码为工具类使用
3 获取预处理对象:preparedStatement
4 设置参数
5 执行sql
6 封装返回结果集
9.getMapper方法实现
由于Dao层加载配置文件、获取SqlSessionFactory、生产sqlSession对象存在代码重复.且statementId有硬编码的问题,可以不要Dao的实 现 类,使用代理模式实现Dao层接口的代理实现类
tips:由于invoke方法中是没有办法获取statementId的,但是可以通过接口全限定名.方法名即namespace.id,因此xxxMapper.xml文件的规范 要遵守,namespace要和接口全限定名一致,方法名也要和接口方法名一致
10.大体流程如下图