众所周知数据库连接的过程,但是最近面试的人(菜面菜),都说用的SSM框架,但是我问了一下,mybatis是怎么连接上mysql的,基本上都会说:配置好的,直接用了,今天我来抛砖引玉一下,欢迎拍砖!

什么是JDBC?

Java语言访问数据库的一种规范,是一套API。JDBC (Java Database Connectivity) API,即Java数据库编程接口,是一组标准的Java语言中的接口和类,使用这些接口和类,Java客户端程序可以访问各种不同类型的数据库。JDBC规范采用接口和实现分离的思想设计了Java数据库编程的框架。接口包含在java.sql及javax.sql包中,其中java.sql属于JavaSE,javax.sql属于JavaEE。为了使客户端程序独立于特定的数据库驱动程序,JDBC规范建议开发者使用基于接口的编程方式,即尽量使应用仅依赖java.sql及javax.sql中的接口和类。

JAVA使用JDBC访问数据库的步骤:

1.得到数据库驱动程序

2.创建数据库连接

3.执行SQL语句

4.得到结果集

5.对结果集做相应的处理(增,删,改,查)

6.关闭资源:这里释放的是DB中的资源

mysql的驱动包提供了java.sql.Driver这个SPI的实现,实现类是com.mysql.jdbc.Driver,在mysql-connector-java-5.1.6.jar中,我们可以看到有一个META-INF/services目录,目录下有一个文件名为java.sql.Driver的文件,其中的内容是com.mysql.jdbc.Driver。
在运行DriverManager.getDriver并传入参数“com.mysql.jdbc.Driver”时,DriverManager会从mysql-connector-java-5.1.6.jar中找到com.mysql.jdbc.Driver并实例化返回一个com.mysql.jdbc.Driver的实例。而SPI(Service Provider Interface)是指一些提供给你继承、扩展,完成自定义功能的类、接口或者方法。

       SPI是一种回调的思想,回调是指我们在使用api时,我们可以向API传入一个类或者方法,API在合适的时间调用类或者方法。SPI是在一些通用的标准中,为标准的实现产商提供的扩展点。标准在上层提供API,API内部使用了SPI,当API被客户使用时,会动态得从当前运行的classpath中寻找该SPI的实现,然后使用该SPI的实现来完成API的功能。
       SPI的实现方式是:提供实现的实现类打包成Jar文件,这个Jar文件里面必须有META-INF目录,其下又有services目录,其下有一个文本文件,文件名即为SPI接口的全名,文件的内容该jar包中提供的SPI接口的实现类名。
       大家看项目中Mybaits的jar包会发现:
  1. private class SqlSessionInterceptor implements InvocationHandler {
  2. @Override
  3. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  4. SqlSession sqlSession = getSqlSession(
  5. SqlSessionTemplate.this.sqlSessionFactory,
  6. SqlSessionTemplate.this.executorType,
  7. SqlSessionTemplate.this.exceptionTranslator);
  8. try {
  9. Object result = method.invoke(sqlSession, args);
  10. if (!isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) {
  11. // force commit even on non-dirty sessions because some databases require
  12. // a commit/rollback before calling close()
  13. sqlSession.commit(true);
  14. }
  15. return result;
  16. } catch (Throwable t) {
  17. Throwable unwrapped = unwrapThrowable(t);
  18. if (SqlSessionTemplate.this.exceptionTranslator != null && unwrapped instanceof PersistenceException) {
  19. // release the connection to avoid a deadlock if the translator is no loaded. See issue #22
  20. closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
  21. sqlSession = null;
  22. Throwable translated = SqlSessionTemplate.this.exceptionTranslator.translateExceptionIfPossible((PersistenceException) unwrapped);
  23. if (translated != null) {
  24. unwrapped = translated;
  25. }
  26. }
  27. throw unwrapped;
  28. } finally {
  29. if (sqlSession != null) {
  30. closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
  31. }
  32. }
  33. }
  34. }

sqlSessionTemplate.SqlSessionInterceptor源码,有没有一种很熟悉的感觉?至于getConnection自己去看;用过ElasticSearch和Redis的童鞋,细心的童鞋会发现连接字符串都大同小异,连接都是类似的,标准的连接方式,提高效率,有效控制连接;

ElasticSearch的连接字符串:

  1. protected SearchResponse getSearchResponse(String fieldName, String indexName) {
  2. client = null;
  3. SearchResponse response = null;
  4. try {
  5. getClient();
  6. MaxAggregationBuilder aggregation =
  7. AggregationBuilders
  8. .max("agg")
  9. .field(fieldName);
  10. SearchRequestBuilder request = client.prepareSearch(indexName).addAggregation(aggregation);
  11. response = request.execute().actionGet();
  12. } catch (Exception ex) {
  13. logger.error("getSearchResponse", ex);
  14. } finally {
  15. if (client != null) {
  16. client.close();
  17. }
  18. return response;
  19. }
  20. }

Jedis连接字符串:

  1. 执行命令如下:
  2. Jedis jedis = null;
  3. try {
  4. jedis = jedisPool.getResource();
  5. //具体的命令
  6. jedis.executeCommand()
  7. } catch (Exception e) {
  8. logger.error("op key {} error: " + e.getMessage(), key, e);
  9. } finally {
  10. //注意这里不是关闭连接,在JedisPool模式下,Jedis会被归还给资源池。
  11. if (jedis != null)
  12. jedis.close();
  13. }

拦截器的实现都是基于代理的设计模式实现的,简单的说就是要创造一个目标类的代理类,在代理类中执行目标类的方法并在方法之前执行拦截器代码,拦截器一般有登陆拦截器——验证会话信息,权限拦截器——验证权限信息,那么SqlSessionInterceptor是干什么的?

Mybatis拦截器设计的一个初衷就是为了供用户在某些时候可以实现自己的逻辑而不必去动Mybatis固有的逻辑。打个比方,对于Executor,Mybatis中有几种实现:BatchExecutor、ReuseExecutor、SimpleExecutor和CachingExecutor。
这个时候如果你觉得这几种实现对于Executor接口的query方法都不能满足你的要求,那怎么办呢?是要去改源码吗?当然不。我们可以建立一个Mybatis拦截器用于拦截Executor接口的query方法,在拦截之后实现自己的query方法逻辑,之后可以选择是否继续执行原来的query方法。允许你在已映射语句执行过程中的某一点进行拦截调用。有的用Mybatis拦截器统封装分页,有的用它实现读写分离等,如果读写分离还是建议配置多数据源;

spring整合mybatis之后,通过动态代理的方式,使用SqlSessionTemplate持有的sqlSessionProxy属性来代理执行sql操作,由spring管理的sqlSeesion在sql方法(增删改查等操作)执行完毕后就自行关闭了sqlSession,不需要我们对其进行手动关闭。

       愿你有情人终成眷属,愿你有个有趣的灵魂,愿你拍我一砖!

浅谈Mybatis连接原理的更多相关文章

  1. 浅谈html运行原理

    浅谈HTML运行原理,所谓的HTML简单的来说就是一个网页,虽然第一节就讲html原理可能大家会听不懂,就当是给一个初步印象把,至少大概知道一个网页的运行流程是怎样的,下面上一张图: 大致的一个htm ...

  2. 浅谈React工作原理

    浅谈React工作原理:https://www.cnblogs.com/yikuu/p/9660932.html 转自:https://cloud.tencent.com/info/63f656e0b ...

  3. 浅谈Mybatis持久化框架在Spring、SSM、SpringBoot整合的演进及简化过程

    前言 最近开始了SpringBoot相关知识的学习,作为为目前比较流行.用的比较广的Spring框架,是每一个Java学习者及从业者都会接触到一个知识点.作为Spring框架项目,肯定少不了与数据库持 ...

  4. 浅谈mybatis如何半自动化解耦

    在JAVA发展过程中,涌现出一系列的ORM框架,JPA,Hibernate,Mybatis和Spring jdbc,本系列,将来研究Mybatis. 通过研究mybatis源码,可将mybatis的大 ...

  5. 浅谈MyBatis缓存

    在谈论MyBatis的缓存之前,我们先说说它的延迟加载,所谓延迟加载, resultMap中的association和collection标签具有延迟加载的功能.延迟加载的意思是说,在关联查询时,利用 ...

  6. 浅谈P2P终结者原理及其突破

    P2P终结者按正常来说是个很好的网管软件,但是好多人却拿它来,恶意的限制他人的流量,使他人不能正常上网,下面我们就他的功能以及原理还有突破方法做个详细的介绍! 我们先来看看来自在网上PSP的资料:P2 ...

  7. 10分钟浅谈CSRF突破原理,Web安全的第一防线!

    CSRF攻击即跨站请求伪造(跨站点请求伪造),是一种对网站的恶意利用,听起来似乎与XSS跨站脚本攻击有点相似,但实际上彼此相差很大,XSS利用的是站点内的信任用户,而CSRF则是通过伪装来自受信任用户 ...

  8. 浅谈C++编译原理 ------ C++编译器与链接器工作原理

    原文:https://blog.csdn.net/zyh821351004/article/details/46425823 第一篇:      首先是预编译,这一步可以粗略的认为只做了一件事情,那就 ...

  9. 浅谈CC攻击原理与防范

    概念         CC攻击的原理就是攻击者控制某些主机不停地发大量数据包给对方服务器造成服务器资源耗尽,一直到宕机崩溃.CC主要是用来攻击页面的,每个人都有这样的体验:当一个网页访问的人数特别多的 ...

随机推荐

  1. python的语法小结

    break 与continue的区别: 1.break是直接中断全部循环 2.continue则是在只不执行此次所循环的东西,其它循环依旧执行,比方说只是跳过第4次循环,第5次循环照常进行. \n 表 ...

  2. 第五周助教工作总结——NWNU李泓毅

    第五周助教总结 注:因第四次实验安排两个标准时间完成,因此本周未提交完整作业. 本周心得: 第四次实验进行过半,八组同学都在实验课上进行了一次中期总结,并形成书面总结在微信群中讨论. 根据各组同学的中 ...

  3. Ubuntu 16.04上安装Global阅读源代码工具

    参照10年前写的文档 (Linux源码阅读工具lxr和glimpse的安装与配置),想重新搭建一个源代码阅读工具,发现源里面都没有相关的工具了. 然后看到有更简单的安装工具Global可以使用,所以果 ...

  4. C++标准库之string返回值研究

    先说结论(不一定适用所有环境): 1) GCC默认开启了返回值优化(RVO),除非编译时指定“-fno-elide-constructors”: 2) 现代C++编译器一般都支持返回值优化: 3) s ...

  5. Python Flask学习笔记之Hello World

    Python Flask学习笔记之Hello World 安装virtualenv,配置Flask开发环境 virtualenv 虚拟环境是Python解释器的一个私有副本,在这个环境中可以安装私有包 ...

  6. index.php入口文件至根目录

      登录|注册       咖啡如同生活的专栏 从不羡慕别人的优秀,因为相信自己也可以优秀. 闲下来时看看书,书本里的故事,总有你学到的人生.       目录视图 摘要视图 订阅 异步赠书:9月重磅 ...

  7. dva-counter

    dva实例Counter. import dva, { connect } from 'dva'; import { Router, Route } from 'dva/router'; import ...

  8. OOP随笔

    父类为普通类: 内部可声明虚方法(virtual),并包含代码实现,子类中可以重写(override),也可以不重写直接用. 父类为(不可实例化的)抽象类: 可声明虚方法,同上. 也可以声明抽象方法( ...

  9. Settings 参数记录

    DOWNLOAD_FAIL_ON_DATALOSS : 参数:TRUE.FALSE 如果设置为 True : scrapy.Request 有一个 errback 参数, 当 Request 请求出错 ...

  10. 关于oracle数据库的小知识

    --查询语句:select 列名/通配符/列别名/表达式 from 表名 (修饰/限制语句)select * from tab;select tname from tab;--指定的列select t ...