分析JDBC操作问题
1 | public static void main(String[] args) { |
JDBC问题总结
原始jdbc开发存在的问题如下
- 数据库连接创建、释放频繁造成系统资源浪费,从而影响系统性能
- sql语句在代码中硬编译,造成代码不易维护,实际应用中sql变化的可能性较大,sql变动需要改变java代码。
- 使用preparedStatement向占有位符号传参数存在硬编码,因sql语句的where条件不一定,可能多也可能少,修改sql还要修改代码,系统不易维护。
- 对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成pojo对象解析比较方便。
问题解决思路
- 使用数据库连接池初始化连接资源
- 将sql语句抽取到xml配置文件中
- 使用反射、内省等底层技术,自动将实体与表进行属性与字段的自动映射
自定义框架设计
使用端
提供核心配置文件
sqlMapConfig.xml:存放数据源信息,引入mapper.xml
Mapper.xml:sql语句的配置文件信息
框架端
读取配置文件
读取完成后以流的形式存在,我们不能将读取的配置信息以流的形式存放到内存中,不好操作,可以创建javaBean来存储
(1)Configuration:存放数据库基本信息、Map<唯一标识, Mapper>唯一标识:namespace+”.”+id
(2)MappedStatement:sql语句、statement类型、输入参数java类型、输出参数java类型
解析配置文件
创建sqlSessionFactoryBuilder类
方法:sqlSessionFactory build():
第一:使用dom4j解析配置文件,将解析出来的内容封装到Configuration和MappedStatement中
第二:创建SqlSessionFactory的实现类DefaultSqlSession
创建SqlSessionFactory
方法:openSession():获取sqlSession接口的实现类实例对象
创建SqlSession接口及实现类:主要封装crud方法
方法:selectList(String statementId,Object Param);查询所有
selectOne(String statementId,Object Param);查询单个
具体实现:封装JDBC完成对数据库的查询操作
涉及到的设计模式
Builder构建者设计模式、工厂模式、代理模式
自定义框架实现
在使用端项目中创建配置文件
创建sqlMapConfig.xml
1 | <configuration> |
mapper.xml
1 | <mapper namespace="User"> |
User实体
1 | public class User { |
再创建一个Maven子工程并且导入需要用到的依赖坐标
1 | <dependencies> |
Configuration
1 | public class Configuration { |
MappedStatement
1 | public class MappedStatement { |
Resources
1 | public class MappedStatement { |
SqlSessionFactoryBuilder
1 | public class SqlSessionFactoryBuilder { |
XMLConfigerBuilder
1 | public class XMLConfigerBuilder { |
XMLMapperBuilder
1 | public class XMLMapperBuilder { |
sqlSessionFactory 接口及D efaultSqlSessionFactory 实现类
1 | public interface SqlSessionFactory { |
sqlSession 接口及 DefaultSqlSession 实现类
1 | public interface SqlSession { |
1 | public class DefaultSqlSession implements SqlSession { |
Executor
1 | public interface Executor { |
SimpleExecutor
1 | public class SimpleExecutor implements Executor { |
BoundSql
1 | public class BoundSql { |
自定义框架优化
通过上述我们的自定义框架,我们解决了JDBC操作数据库带来的一些问题:例如频繁创建释放数据库连接,硬编码,手动封装返回结果集等问题,但是现在我们继续来分析刚刚完成的自定义框架代码,有没有什么问题?
问题如下:
- dao的实现类中存在重复的代码,整个操作的过程模板重复(创建sqlsession,调用sqlsession方 法,关闭 sqlsession)
- dao的实现类中存在硬编码,调用sqlsession的方法时,参数statement的id硬编码解决:使用代理模式来创建接口的代理对象
1 |
|
在sqlSession中添加方法
1 | public interface SqlSession { |
实现类
1 |
|