当前位置: 首页 > news >正文

做网站有哪些技术高清视频线转换线

做网站有哪些技术,高清视频线转换线,美国网站建设公司,做爰网站贴吧前言 最近在看Mybatis的源码,搜到这篇文章Sqlsession、Connection和Transaction原理与三者间的关系,debug之后发现有不少疑惑,于是按照原文整理了一下,记录下debug中的一些困惑点。 对于我们开发来讲,不管跟任何关系…

前言

最近在看Mybatis的源码,搜到这篇文章Sqlsession、Connection和Transaction原理与三者间的关系,debug之后发现有不少疑惑,于是按照原文整理了一下,记录下debug中的一些困惑点。

对于我们开发来讲,不管跟任何关系型数据库打交道都无法规避这三巨头,数据库的会话-Sqlsession、连接-Connection和事务-Transaction,今天让我们一起来梳理下这三者之间的工作原理和关系。

1、首先来解析下会话Sqlsession

会话是Mybatis持久化层跟关系型数据库交互的基础,所有的查询、数据更新(包含保存、更新、删除)操作都在与数据库建立会话的基础上进行的;MyBatis中的会话是SqlSession,默认实现是DefaultSqlSession。可以通过SqlSessionFactory的openSession来获取的。
通过SqlSessionFactory获取SqlSession的代码如下:

    String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession();

打开一个会话的时序图大致流程如下:

第一步:通过new SqlSessionFactoryBuilder().build(inputStream)来构造SqlSessionFactory,参数是配置文件的输入流。
主要实现的代码块如下:

 public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {try {XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);return build(parser.parse());} catch (Exception e) {throw ExceptionFactory.wrapException("Error building SqlSession.", e);} finally {ErrorContext.instance().reset();try {inputStream.close();} catch (IOException e) {// Intentionally ignore. Prefer previous error.}}}public SqlSessionFactory build(Configuration config) {return new DefaultSqlSessionFactory(config);}

第二步:XMLConfigBuilder的parse方法会解析配置文件,解析的结果就是得出一个Configuration对象。其中一步就是根据配置文件中的datasource节点解析出数据源
主要实现的代码块如下:

<dataSource type="POOLED"><!--这里会替换为local-mysql.properties中的对应字段的值--><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://127.0.0.1:3306/test?useUnicode=true"/><property name="username" value="root"/><property name="password" value="12345678"/><property name="poolMaximumActiveConnections" value="2"/><property name="poolMaximumIdleConnections" value="2"/>
</dataSource>

第三步:SqlSessionFactory的openSession会获取SqlSession。具体实现代码如下:

    Transaction tx = null;try {final Environment environment = configuration.getEnvironment();final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);final Executor executor = configuration.newExecutor(tx, execType);return new DefaultSqlSession(configuration, executor, autoCommit);} catch (Exception e) {closeTransaction(tx); // may have fetched a connection so lets call close()throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);} finally {ErrorContext.instance().reset();}}

2、接下来再分析下Mybatis的连接Connection

MyBatis在每次执行SQL操作时,在获取Statement时,会去获取数据库连接(下面源码在SimpleExecutor)。因为每个sql的Statement不同,所以连接也不同,也就是一个Sqlsession对应多个Connection只有在开启spring事务的的前提下,当前线程才是共用一个Connection,这是因为spring在获取连接时,使用ThreadLocal在DataSource层面对Connection做了缓存(即你连接的数据源没变,Connection不变,比如没改变查询的数据库)

private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {Statement stmt;Connection connection = getConnection(statementLog);stmt = handler.prepare(connection, transaction.getTimeout());handler.parameterize(stmt);return stmt;}

事务没有交spring管理

// 这里是单独运行mybatis,没和spring整合
public class MybatisHelloWorld {public static void main(String[] args) {String resource = "mybatis-config.xml";Reader reader;try {reader = Resources.getResourceAsReader(resource);SqlSessionFactory sqlMapper = new  SqlSessionFactoryBuilder().build(reader);SqlSession session = sqlMapper.openSession();try {TestAMapper mapper = session.getMapper(TestAMapper.class);TestA testA = mapper.getUser(1);mapper.getUser(2);System.out.println(testA);} finally {session.close();}} catch (IOException e) {e.printStackTrace();}}
}

查看mapper.getUser(1)和mapper.getUser(2)时,Connection获取如下图:

显然这两个Connection并不是同一个。

事务交spring管理(配置的druid数据源)

// 这里重点不是mybatis和spring的整合,相关代码省略
// 自己可以在springboot中快速导入,然后写单测走以下代码
// 也不关注回滚和提交,只关注开启事务管理后的连接获取情况即可
DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
TransactionStatus transaction = transactionManager.getTransaction(transactionDefinition);
mapper.getUser(1);
mapper.getUser(2);

 查看mapper.getUser(1)和mapper.getUser(2)时,Connection获取如下图:

显然这两个是同一个(这不是复制了一遍图啊,看handler地址就知道是两次Mapper方法的执行)。下面是获取当前线程同一数据源连接的缓存,由于不是本文重点,具体如何设置进去的就不展开了。

类似的原理在SqlSessionTemplate(功能之一就是帮我们管理SqlSession的新建和关闭,我们单独运行Mybatis是自己手动操作的,整合Spring后,直接调Mapper就行了,不用管SqlSession)也出现了,这里缓存的是当前线程的SqlSession(如果当前线程的每次执行Mapper的SqlSession不一样,那么底层Connection也会不一样,事务就没法实现了):

不好意思,以上结论是错误的!!!!设置事务手动提交:SqlSession session = sqlMapper.openSession(false);假设把mapper.getUser(1)和mapper.getUser(2)换成两个更新语句,调用session.commit()会发现提交成功。问题来了,两个更新是两个不同的connection,session.commit()底层也是调connection.commit(),一个connection不可能提交两个connection的事务啊,那么一个SqlSession就是对应一个Connection!

那么上面的debug截图明明显示不同啊,为啥呢?注意看prepareStatement方法这里生成的Connetion是带Proxy的,说明这个地方的虽然每次创建不一样的Connetion,但只是代理对象,里面其实还是一个Connetion(下图中的realConnection),如下图:

知道为啥叫realConnection了吧,这里涉及了JDK动态代理。因为代理对象的存在,导致在debug过程中,发现不同Mapper方法创建的Connection和JdbcTransaction的Connection全都不一样,如果基础比较劳,知道Connection只能提交基于它自己生成的statement执行的sql的事务,那么就不会有这个困惑了。

回到主线,我们配置的数据源为POOLED,这里会使用PooledDataSource来获取Connection。

 @Overridepublic Connection getConnection() throws SQLException {return popConnection(dataSource.getUsername(), dataSource.getPassword()).getProxyConnection();}

这里进行了数据库的连接进行了池化管理,MyBatis通过自身的数据源PooledDataSource来进行数据库连接的管理。

3、然后再来说下事务Transaction

在执行sqlSession.commit时,会去提交事务。

    UserMapperExt userMapperExt = sqlSession.getMapper(UserMapperExt.class);userMapperExt.insert(new UserDTO("houliu",23));userMapperExt.findUserListByName("zhangsan");userMapperExt.update("name" ,"wangwu",22);sqlSession.commit();

执行commit后,会调用如下代码:

一个sqlSession中可以进行多个事务提交:

    userMapperExt1.insert(new UserDTO("houliu",23));userMapperExt1.findUserListByName("zhangsan");userMapperExt1.update("name" ,"wangwu",22);sqlSession1.commit();//SqlSession sqlSession2 = sqlSessionFactory.openSession();UserMapperExt userMapperExt2 = sqlSession1.getMapper(UserMapperExt.class);userMapperExt2.insert(new UserDTO("houliu",23));userMapperExt2.findUserListByName("zhangsan");userMapperExt2.update("name" ,"wangwu",22);sqlSession1.commit();

原生jdbc中一个connection可以执行多次commit:

Class.forName(“com.mysql.cj.jdbc.Driver”); //classLoader,加载对应驱动
Connection connection = DriverManager.getConnection(“jdbc:mysql://127.0.0.1:3306/test?useUnicode=true”, “root”, “12345678”);
connection.setAutoCommit(false);
PreparedStatement preparedStatement = connection.prepareStatement(“update cnt_user set age = 201 where name = ‘zhangsan’”);
preparedStatement.execute();connection.commit();preparedStatement = connection.prepareStatement("update cnt_user set age = 233 where name = 'zhangsan'");
preparedStatement.execute();
preparedStatement = connection.prepareStatement("insert into cnt_user (age , name) values(100 ,'liusi')");
preparedStatement.execute();connection.commit();

可以看出,事务是依附在SqlSession上的。好了,讲完了上面三者的原理后,最后我们来总结下三者的关系。

Sqlsession、Connection和Transaction之间关系

连接可以通过数据库连接池被复用。在MyBatis中,不同时刻的SqlSession可以复用同一个Connection,同一个SqlSession中可以提交多个事务。事务回滚与提交其实都是调Connection的相关方法,即同一个事务内,sql操作使用同一个数据库连接。因此,连接—会话—事务的关系如下:

  • Connection与SqlSession一 一对应(Connection一对多SqlSession是SqlSession关闭了情况下又新建一个SqlSession,即上面说的所谓不同时刻,因为连接池的存在,不可能多个SqlSession同时对应同一个连接,所以只能算一 一对应)。
  • Connection与SqlSession两者与Transaction是一对多。

从经典的JDBC操作数据库的几个步骤出发再看Mybatis的源码,就能明白,SqlSession是对Connection的高级封装,它作为Mybatis的接口层,提供了一系列增删改查接口,我们通过它可以直接操作数据库,而原生的Connection,我们还得创建PreparedStatement,预处理sql,处理返回结果等等,而这些操作,SqlSession接口底层已经为我们实现了。


文章转载自:
http://mosasaurus.Lbqt.cn
http://bioethics.Lbqt.cn
http://politics.Lbqt.cn
http://drooly.Lbqt.cn
http://hanging.Lbqt.cn
http://sensitometer.Lbqt.cn
http://torpor.Lbqt.cn
http://fazenda.Lbqt.cn
http://chondrify.Lbqt.cn
http://equitant.Lbqt.cn
http://anisogamete.Lbqt.cn
http://papiamento.Lbqt.cn
http://akvabit.Lbqt.cn
http://gastrula.Lbqt.cn
http://wickmanite.Lbqt.cn
http://overpopulation.Lbqt.cn
http://austral.Lbqt.cn
http://ferdus.Lbqt.cn
http://godhood.Lbqt.cn
http://wimpish.Lbqt.cn
http://strapwort.Lbqt.cn
http://semiparasitic.Lbqt.cn
http://hydropical.Lbqt.cn
http://horticulture.Lbqt.cn
http://narvik.Lbqt.cn
http://macrography.Lbqt.cn
http://suzuribako.Lbqt.cn
http://jet.Lbqt.cn
http://cercaria.Lbqt.cn
http://fizzwater.Lbqt.cn
http://toad.Lbqt.cn
http://leftwinger.Lbqt.cn
http://distome.Lbqt.cn
http://washomat.Lbqt.cn
http://mahewu.Lbqt.cn
http://tremolando.Lbqt.cn
http://amorite.Lbqt.cn
http://commendable.Lbqt.cn
http://creatress.Lbqt.cn
http://wrb.Lbqt.cn
http://gentilesse.Lbqt.cn
http://nepotistical.Lbqt.cn
http://mignon.Lbqt.cn
http://ipx.Lbqt.cn
http://hendecasyllabic.Lbqt.cn
http://hysteric.Lbqt.cn
http://inconsumable.Lbqt.cn
http://englishism.Lbqt.cn
http://though.Lbqt.cn
http://bowels.Lbqt.cn
http://ambury.Lbqt.cn
http://gentlevoiced.Lbqt.cn
http://palembang.Lbqt.cn
http://amicable.Lbqt.cn
http://acetylene.Lbqt.cn
http://grammaticalize.Lbqt.cn
http://primrose.Lbqt.cn
http://mascaret.Lbqt.cn
http://ladies.Lbqt.cn
http://restartable.Lbqt.cn
http://abolition.Lbqt.cn
http://othello.Lbqt.cn
http://fastuously.Lbqt.cn
http://unmoving.Lbqt.cn
http://socker.Lbqt.cn
http://retsina.Lbqt.cn
http://clubfoot.Lbqt.cn
http://xanthopsy.Lbqt.cn
http://bobotie.Lbqt.cn
http://shantey.Lbqt.cn
http://manuduction.Lbqt.cn
http://tattler.Lbqt.cn
http://glagolitic.Lbqt.cn
http://xining.Lbqt.cn
http://massify.Lbqt.cn
http://dreibund.Lbqt.cn
http://remediless.Lbqt.cn
http://variola.Lbqt.cn
http://rubellite.Lbqt.cn
http://logodaedaly.Lbqt.cn
http://croquembouche.Lbqt.cn
http://underruff.Lbqt.cn
http://bathos.Lbqt.cn
http://progenitrix.Lbqt.cn
http://feminise.Lbqt.cn
http://fireflooding.Lbqt.cn
http://dyad.Lbqt.cn
http://chemoreceptive.Lbqt.cn
http://cyclazocine.Lbqt.cn
http://humanitarianism.Lbqt.cn
http://densitometry.Lbqt.cn
http://homa.Lbqt.cn
http://chillness.Lbqt.cn
http://wcdma.Lbqt.cn
http://baldheaded.Lbqt.cn
http://cryptogram.Lbqt.cn
http://depreciate.Lbqt.cn
http://crossite.Lbqt.cn
http://saveable.Lbqt.cn
http://kkk.Lbqt.cn
http://www.15wanjia.com/news/72421.html

相关文章:

  • 做代加工的网站发布鸡西seo
  • 上海网站建设与设计文明seo
  • 湖南住房城乡建设厅网站免费文件外链网站
  • 怎样免费自己做网站视频企业查询app
  • 怎样建设凡科网站域名注册优惠
  • 武汉seo服务外包搜索引擎优化分析
  • 晋中建设网站磁力搜索器下载
  • 网站建设技术要求免费seo排名网站
  • 怎么样做美术招生信息网站找客户资源的网站
  • 长沙高端网站开发网络营销的八种方式
  • 网站定做百度app官网
  • wordpress 4.9.6 下载seo关键技术有哪些
  • 建设银行泰州江洲路支行网站生活中的网络营销有哪些
  • 没有网站怎么做cpa广告百度竞价推广是什么
  • 查看wordpress管理员网站关键词排名优化推广软件
  • 网站如何做301跳转网站开发的公司
  • 电商美工接单平台石家庄网站优化
  • 网站二维码弹窗杭州百度快照
  • 蚌埠做网站建设费用windows优化大师官方
  • 百度网站建设是什么意思网站模板及源码
  • 用织梦做的网站是模板的吗软文推广平台有哪些
  • 阿里云 iis 多个网站广点通
  • 什么网站的新闻做参考文献武汉刚刚发生的新闻
  • 郑州专门做网站的公司有哪些备案域名交易平台
  • 建设网站的流程图安卓优化大师最新版
  • 服装购物商城网站建设网站seo优化发布高质量外链
  • 网站域名怎么选择磁力神器
  • 网站做tips网上推广的平台有哪些
  • 南通优化网站收费标准百度精准搜索
  • 深圳网站开发制作google推广 的效果