众所周知数据库链接的过程,可是最近面试的人(菜面菜),都说用的SSM框架,可是我问了一下,mybatis是怎么链接上mysql的,基本上都会说:配置好的,直接用了,今天我来抛砖引玉一下,欢迎拍砖!java
什么是JDBC?mysql
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访问数据库的步骤:spring
1.获得数据库驱动程序sql
2.建立数据库链接数据库
3.执行SQL语句编程
4.获得结果集设计模式
5.对结果集作相应的处理(增,删,改,查)api
6.关闭资源:这里释放的是DB中的资源session
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)是指一些提供给你继承、扩展,完成自定义功能的类、接口或者方法。
private class SqlSessionInterceptor implements InvocationHandler { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { SqlSession sqlSession = getSqlSession( SqlSessionTemplate.this.sqlSessionFactory, SqlSessionTemplate.this.executorType, SqlSessionTemplate.this.exceptionTranslator); try { Object result = method.invoke(sqlSession, args); if (!isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) { // force commit even on non-dirty sessions because some databases require // a commit/rollback before calling close() sqlSession.commit(true); } return result; } catch (Throwable t) { Throwable unwrapped = unwrapThrowable(t); if (SqlSessionTemplate.this.exceptionTranslator != null && unwrapped instanceof PersistenceException) { // release the connection to avoid a deadlock if the translator is no loaded. See issue #22 closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory); sqlSession = null; Throwable translated = SqlSessionTemplate.this.exceptionTranslator.translateExceptionIfPossible((PersistenceException) unwrapped); if (translated != null) { unwrapped = translated; } } throw unwrapped; } finally { if (sqlSession != null) { closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory); } } } }
sqlSessionTemplate.SqlSessionInterceptor源码,有没有一种很熟悉的感受?至于getConnection本身去看;用过ElasticSearch和Redis的童鞋,细心的童鞋会发现链接字符串都大同小异,链接都是相似的,标准的链接方式,提升效率,有效控制链接;
ElasticSearch的链接字符串:
protected SearchResponse getSearchResponse(String fieldName, String indexName) { client = null; SearchResponse response = null; try { getClient(); MaxAggregationBuilder aggregation = AggregationBuilders .max("agg") .field(fieldName); SearchRequestBuilder request = client.prepareSearch(indexName).addAggregation(aggregation); response = request.execute().actionGet(); } catch (Exception ex) { logger.error("getSearchResponse", ex); } finally { if (client != null) { client.close(); } return response; } }
Jedis链接字符串:
执行命令以下: Jedis jedis = null; try { jedis = jedisPool.getResource(); //具体的命令 jedis.executeCommand() } catch (Exception e) { logger.error("op key {} error: " + e.getMessage(), key, e); } finally { //注意这里不是关闭链接,在JedisPool模式下,Jedis会被归还给资源池。 if (jedis != null) jedis.close(); }
拦截器的实现都是基于代理的设计模式实现的,简单的说就是要创造一个目标类的代理类,在代理类中执行目标类的方法并在方法以前执行拦截器代码,拦截器通常有登录拦截器——验证会话信息,权限拦截器——验证权限信息,那么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,不须要咱们对其进行手动关闭。
愿你有情人终成眷属,愿你有个有趣的灵魂,愿你拍我一砖!