前言

接上文,这里只是出于强迫症,凭借着半年前的笔记来把之前没写完的文章写完,这里是最后一篇了。

前面自定义的持久层框架存在的问题

Dao层若使用实现类,会存在代码重复,整个操作的过程模版重复(加载配置文件、创建sqlSessionFactory、生产sqlSession)

解决思路

使用代理模式生成Dao层接口的代理实现类(去掉原Dao层的代理实现类)

代码实现

在IPersistence_test项目中添加Dao层及接口类:
 1 package com.hardy.dao;
2
3 import com.hardy.pojo.User;
4
5 import java.util.List;
6
7 public interface IUserDao {
8
9 // 查询所有用户
10 public List<User> findAll() throws Exception;
11
12 // 根据条件进行用户查询
13 public User findByCondition(User user) throws Exception;
14
15 }
在SqlSession接口类中添加getMapper接口:
 1 package com.hardy.sqlSession;
2
3 import java.util.List;
4
5 public interface SqlSession {
6
7 /* 查询所有:
8 根据statementId,找到Mapper.xml文件中对应的sql语句
9 Object...Parameter 表示支持传递多个参数值进行查询
10 */
11 public <E> List<E> selectList(String statementId, Object... Parameter) throws Exception;
12
13 // 根据条件查询单个
14 public <T> T selectOne(String statementId, Object... Parameter) throws Exception;
15
16 //为Dao接口生成代理实现类
17 public <T> T getMapper(Class<?> mapperClass);
18
19 }
在SqlSession的实现类中重写getMapper接口:
 1 package com.hardy.sqlSession;
2
3 import com.hardy.pojo.Configuration;
4 import com.hardy.pojo.MappedStatement;
5
6 import java.lang.reflect.*;
7 import java.lang.reflect.Proxy;
8 import java.sql.SQLException;
9 import java.util.List;
10
11 public class DefaultSqlSession implements SqlSession {
12
13 private Configuration configuration;
14
15 public DefaultSqlSession(Configuration configuration) {
16 this.configuration = configuration;
17 }
18
19 // 处理器对象
20 private Executor simpleExecutor = new SimpleExecutor();
21
22 @Override
23 public <E> List<E> selectList(String statementId, Object... params) throws Exception {
24 // 对SimpleExecutor里的query方法的调用 7
25 SimpleExecutor simpleExecutor = new SimpleExecutor();
26 MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementId);
27 List<Object> list = simpleExecutor.query(configuration, mappedStatement, params);
28
29 return (List<E>) list;
30 }
31
32 @Override
33 public <T> T selectOne(String statementId, Object... params) throws Exception {
34 List<Object> objects = selectList(statementId, params);
35 if (objects.size() == 1) {
36 return (T) objects.get(0);
37 } else {
38 throw new RuntimeException("查无此数据或查询结果过多");
39 }
40
41 }
42
43 @Override
44 public <T> T getMapper(Class<?> mapperClass) {
45 // 使用JDK动态代理来为Dao接口生成代理对象,并返回
46 Object proxyInstance = Proxy.newProxyInstance(DefaultSqlSession.class.getClassLoader(), new Class[]{mapperClass}, new InvocationHandler() {
47 @Override
48 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
49 // 底层都还是去执行JDBC代码
50 // 根据不同情况,来调用selctList或者selectOne
51 // 准备参数 1:statmentid :sql语句的唯一标识:namespace.id = 接口全限定名.方法名
52 String methodName = method.getName();
53 String className = method.getDeclaringClass().getName();
54
55 String statementId = className + "." + methodName;
56
57 // 准备参数2:params:args
58 // 获取被调用方法的返回值类型
59 Type genericReturnType = method.getGenericReturnType();
60 // 判断是否进行了 泛型类型参数化
61 if (genericReturnType instanceof ParameterizedType) {
62 List<Object> objects = selectList(statementId, args);
63 return objects;
64 }
65
66 return selectOne(statementId, args);
67 }
68 });
69
70 return (T) proxyInstance;
71 }
72
73 public void close() throws SQLException {
74 simpleExecutor.close();
75 }
76
77 }
修改测试类:
 1 package com.hardy.test;
2
3 import com.hardy.dao.IUserDao;
4 import com.hardy.io.Resources;
5 import com.hardy.pojo.User;
6 import com.hardy.sqlSession.SqlSession;
7 import com.hardy.sqlSession.SqlSessionFactory;
8 import com.hardy.sqlSession.SqlSessionFactoryBuilder;
9 import org.junit.Test;
10
11 import java.io.InputStream;
12 import java.util.List;
13
14 public class IPersistenceTest {
15
16 @Test
17 public void test() throws Exception {
18 InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
19 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().builder(resourceAsStream);
20 SqlSession sqlSession = sqlSessionFactory.openSession();
21
22 System.out.println("自定义持久层框架,GO!");
23 // 调用
24 // User user = new User();
25 // user.setId(1);
26 // user.setUsername("hardy");
27 // User user2 = sqlSession.selectOne("User.selectOne", user);
28 // System.out.println("查询单条记录:"+ user2);
29 //
30 // System.out.println("-----------------------------------------");
31 //
32 // List<User> users = sqlSession.selectList("User.selectList");
33 // System.out.println("查询多条记录:");
34 // for (User user1 : users) {
35 // System.out.println(user1);
36 // }
37
38 IUserDao userDao = sqlSession.getMapper(IUserDao.class);
39
40 List<User> allUsers = userDao.findAll();
41 for (User user1 : allUsers) {
42 System.out.println(user1);
43 }
44
45 }
46 }
运行结果如下所示:

总结

这半年多来,经过工作中的磨练及空闲时间的自学,虽然我依旧是个菜鸟,但是开发能力还是比之前强了不少,回想半年多以前自己写这个系列文章的时候,对当中很多概念都不太清楚,现在倒是觉得很简单了。

之前是挺想一直坚持写下去的,不过由于那段时间项目太赶,工作强度比较大,导致学习积极性下降了很多。另一方面,也是因为自己的心态没有调整好,对于未来没有明确的目标。

我还算比较幸运,后面有机会换了一份比较好的工作,工作强度不那么大,这几个月自学的时间相当多,技术方面进步了不少。

可惜一直没有下定决心来好好写技术博客,新年新气象,正好最近自学也快告一段落了,是时候通过输出倒逼输入了,今年的目标之一就是坚持每周写一点博客,每月发布几篇。

也许我在很长的一段时间内都写不出什么好文章,但是 管它呢,自己喜欢就好,有个平台可以免费写点东西,顺便还能复习下自己学到的知识,这本身就是一种回报。

话虽如此,还是要精益求精,尽可能写多点有技术含量的东西,所以,要好好学习咯。

Mybatis学习之自定义持久层框架(七) 自定义持久层框架优化的更多相关文章

  1. 七、持久层框架(MyBatis)

    一.MyBatis学习 平时我们都用JDBC访问数据库,除了自己需要写SQL,还要操作Connection,Statement,ResultSet这些. 使用MyBatis,只需要自己提供SQL语句, ...

  2. Mybatis(一):手写一套持久层框架

    作者 : 潘潘 未来半年,有幸与导师们一起学习交流,趁这个机会,把所学所感记录下来. 「封面图」 自毕业以后,自己先创业后上班,浮沉了近8年,内心着实焦躁,虽一直是走科班路线,但在技术道路上却始终没静 ...

  3. Django框架(七)—— 模板层:变量、过滤器、标签、自定义标签和过滤器

    目录 模板层:变量.过滤器.标签.自定义标签和过滤器 一.模板层变量 1.语法 2.使用 二.模板层之过滤器 1.语法 2.常用过滤器 3.其他过滤器 三.模板值标签 1.for标签 2.if标签 3 ...

  4. MyBatis学习总结(七)——Mybatis缓存(转载)

      孤傲苍狼 只为成功找方法,不为失败找借口! MyBatis学习总结(七)--Mybatis缓存 一.MyBatis缓存介绍 正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的 ...

  5. 【转】MyBatis学习总结(七)——Mybatis缓存

    [转]MyBatis学习总结(七)——Mybatis缓存 一.MyBatis缓存介绍 正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的支持 一级缓存: 基于PerpetualC ...

  6. mybatis学习笔记之基础框架(2)

    mybatis学习笔记之基础框架(2) mybatis是一个持久层的框架,是apache下的顶级项目. mybatis让程序将主要精力放在sql上,通过mybatis提供的映射方式,自由灵活生成满足s ...

  7. MyBatis学习七:spring和MyBatis整合

    <\mybatis\day02\16mybatis和spring整合-sqlSessionFactory配置.avi;> MyBatis学习七:spring和MyBatis整合.逆向工程 ...

  8. 【MyBatis学习01】宏观上把握MyBatis框架

    今天开始学习mybatis框架,博客主要记录学习过程中的一些总结,如有错误之处,欢迎留言指正~先用mybatis的鸟鸟来镇个楼,咳咳~~ mybatis框架是一个持久层框架,是Apache下的顶级项目 ...

  9. Mybatis学习记录(七)----Mybatis查询缓存

    1. 什么是查询缓存 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存. 一级缓存是SqlSession级别的缓存.在操作数据库时需要构造 sql ...

  10. mybatis 学习笔记(三):mapper 代理开发 dao 层

    mybatis 学习笔记(三):mapper 代理开发 dao 层 优势 通过使用mapper 代理,我们可以不需要去编写具体的实现类(使用 getMapper() 方法自动生成),只需编写接口即可, ...

随机推荐

  1. 攻防世界 reverse easy_Maze

    easy_Maze 从题目可得知是简单的迷宫问题 int __cdecl main(int argc, const char **argv, const char **envp) { __int64 ...

  2. J. Cole 的 InnoDB 系列 - 1. 学习 InnoDB - 深入探索核心原理之旅

    原文地址:https://blog.jcole.us/2013/01/02/on-learning-innodb-a-journey-to-the-core/,本系列翻译会在其基础上扩展一些 MySQ ...

  3. vmstat-观察进程上线文切换

    vmstat 是一款指定采样周期和次数的功能性监测工具,我们可以看到,它不仅可以统计内存的使用情况,还可以观测到 CPU 的使用率.swap 的使用情况.但 vmstat 一般很少用来查看内存的使用情 ...

  4. 「HTML+CSS」--自定义加载动画【011】

    前言 Hello!小伙伴! 首先非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出- 哈哈 自我介绍一下 昵称:海轰 标签:程序猿一只|C++选手|学生 简介:因C语言结识编程,随后转入计算机 ...

  5. java面试-集合类不安全问题及解决方案

    一.List 1.代码演示 public class ArrayListNotSafeDemo { public static void main(String[] args) { List<S ...

  6. PBFT共识算法详解

    PBFT(Practical Byzantine Fault Tolerance,实用拜占庭容错) 一.概述 拜占庭将军问题最早是由 Leslie Lamport 在 1982 年发表的论文<T ...

  7. MindSpore函数拟合

    技术背景 在前面一篇博客中我们介绍过基于docker的mindspore编程环境配置,这里我们基于这个环境,使用mindspore来拟合一个线性的函数,演示一下mindspore的基本用法. 环境准备 ...

  8. 简单模拟实现javascript中的call、apply、bind方法

    目录 引子 隐式丢失 硬绑定 实现及原理分析 总体实现(纯净版/没有注释) 写在最后 引子 读完<你不知道的JavaScript--上卷>中关于this的介绍和深入的章节后,对于this的 ...

  9. python进阶(7)--文件与异常

    一.文件读取二.文件写入三.异常四.存储数据 ---------------------------------------分割线:正文-------------------------------- ...

  10. C语言-字符串函数的实现(五)之strstr

    C语言中的字符串函数有如下这些 获取字符串长度 strlen 长度不受限制的字符串函数 strcpy strcat strcmp 长度受限制的字符串函数 strncpy strncat strncmp ...