历史就是一面镜子
回顾自己开发的历程,见证了时代变迁史记,下面我针对java连接数据库的方式说起
0 原生jdbc
先普及下jdbc,怕新入行的人早已沉浸在包装库和框架中,甚至都没用过原生jdbc。
Java数据库连接,全称是Java Database Connectivity,简称JDBC,是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。JDBC也是Sun Microsystems的商标。我们通常说的JDBC是面向关系型数据库的。百科这样解释的Java数据库连接。
开发人员要做的几个步骤:
开发步骤:
1、注册驱动.,告知JVM使用的是哪一个数据库的驱动
2、获得连接.,使用JDBC中的类,完成对MySQL数据库的连接
3、获得语句执行平台,通过连接对象获取对SQL语句的执行者对象
4、执行sql语句,使用执行者对象,向数据库执行SQL语句 获取到数据库的执行后的结果
5、处理结果
6、释放资源.
注意写代码之前,要导入数据库驱动包,连接不同厂商的数据库要用不同的驱动包
对应的驱动包
新建项目,普通的java项目就行,导入第三方jar太简单了,自行百度
示例代码如下:
查询结果
恩早期开发就是这么过来,只是自己封装成了JDBC工具,于具体的业务开发人员要写大量的SQL语句,调用时这样的
看上去此种开发模式也很好,只要规模不大,此方式还很好,瓶颈在于数据库连接,现在也不是问题了,社会在进步,池化技术出现了。
池化简单点说就是预先连接好一定数量的连接,等需要时随意从中选择一个进行操作。略了,当时主要用的tomcat自带的池化技术,此时获取数据库连接的代码就变成了这样核心伪代码(tomcat要做些配置):
普及下JNDIhttps://baike.baidu.com/item/JNDI/3792442?fr=aladdin,现在也难见到了,很多框架越来越傻瓜式了
1. hibernate来了
Hibernate是一种ORM框架,全称为 Object_Relative DateBase-Mapping,在Java对象与关系数据库之间建立某种映射,以实现直接存取Java对象。
想不明白为啥没有mybatis发展的好,看来拉拢技术人员搞社区还是很重要的。
很遗憾,没有保留以前的老项目,没有自己的电脑,也没有申请github。
看了下网上已有很多教程了:https://www.w3cschool.cn/hibernate/skzl1idz.html,就不多说什么,重点关注架构、缓存、事务和拦截器。重点代码
2. mybatis也来了,来的更猛
用的时间稍微长久些,没办法,谁让它势头发展的好,也有大厂强烈支持。
mybatis简介https://baike.baidu.com/item/MyBatis/2824918?fr=aladdin,算是hibernate的竞争者
我看网上也有了类似教程,MyBatis 教程 https://www.w3cschool.cn/mybatis/、
重点也是关注架构、缓存和事务
简单demo如下:
配置文件三个如下
mybatis-config.xml
myBatisMapper.xml文件内容
数据库配置mysql.properties
执行测试代码效果:
注意配置型的文件不能放错位置,要么就改加载属性文件的代码,记得导入数据库驱动包和mybatis.jar
缓存分两种,一级缓存和二级缓存。
一级缓存的几种情况:
第一种情况:同个session进行两次相同查询
结论:MyBatis只进行1次数据库查询。
第二种情况:同个session进行两次不同的查询
结论:MyBatis进行两次数据库查询。
第三种:不同session,进行相同查询。
结论:MyBatis进行两次数据库查询。
第四种情况:同个session,查询之后更新数据,再次查询相同的语句
直接下结论了:更新操作之后缓存会被清除
二级缓存
之所以称之为“二级缓存”,是相对于“一级缓存”而言的。既然有了一级缓存,那么为什么要提供二级缓存呢?我们知道,在一级缓存中,不同session进行相同SQL查询的时候,是查询两次数据库的。显然这是一种浪费,既然SQL查询相同,就没有必要再次查库了,直接利用缓存数据即可,这种思想就是MyBatis二级缓存的初衷。
另外,Spring和MyBatis整合时,每次查询之后都要进行关闭sqlsession,关闭之后数据被清空。所以MyBatis和Spring整合之后,一级缓存是没有意义的。如果开启二级缓存,关闭sqlsession后,会把该sqlsession一级缓存中的数据添加到mapper namespace的二级缓存中。这样,缓存在sqlsession关闭之后依然存在。
默认情况下,MyBatis只启用了本地的会话缓存,它仅仅对一个会话中的数据进行缓存,见: MyBatis一级缓存介绍 。要启用全局的二级缓存,只需要在SQL映射文件中添加一行:
<cache/>
二级缓存是Mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。
上面这个简单语句的效果如下:
映射语句文件中的所有 select 语句的结果将会被缓存。
映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。
缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来清除不需要的缓存。
缓存不会定时进行刷新(也就是说,没有刷新间隔)。
缓存会保存列表或对象的1024个引用。
缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。
这些属性可以通过 cache 元素的属性来修改。比如:
这个更高级的配置创建了一个 FIFO 缓存,每隔 60 秒刷新,最多可以存储结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此对它们进行修改可能会在不同线程中的调用者产生冲突。
可用的清除策略有:
LRU – 最近最少使用:移除最长时间不被使用的对象。
FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
SOFT – 软引用:基于垃圾回收器状态和软引用规则移除对象。
WEAK – 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象。
默认的清除策略是 LRU。
flushInterval(刷新间隔)属性可以被设置为任意的正整数,设置的值应该是一个以毫秒为单位的合理时间量。 默认情况是不设置,也就是没有刷新间隔,缓存仅仅会在调用语句时刷新。
size(引用数目)属性可以被设置为任意正整数,要注意欲缓存对象的大小和运行环境中可用的内存资源。默认值是 1024。
readOnly(只读)属性可以被设置为 true 或 false。只读的缓存会给所有调用者返回缓存对象的相同实例。 因此这些对象不能被修改。这就提供了可观的性能提升。而可读写的缓存会(通过序列化)返回缓存对象的拷贝。 速度上会慢一些,但是更安全,因此默认值是 false。
提示:二级缓存是事务性的。这意味着,当 SqlSession 完成并提交时,或是完成并回滚,但没有执行 flushCache=true 的 insert/delete/update 语句时,缓存会获得更新。
框架前几部分都是属性文件解析,构造工厂,生产产品做真正的事
记一次使用mybatis使用出现的排序问题: ${}和 #{}的区别
由于开始时排序字段,特别是分页查询时,传的参数有第几页,每页几条记录,排序字段,是动态设置的,有时从前端传来,按某些个字段排序
就是这个sortOrder
大致就这样了,每个人都可以接着扩展开发。框架性迭代总是这样,xml到json,sql写在xml文件里到如今通过注解实现(spring也是如此,早期都是xml大量配置,如今也转换到注解配置),框架越来越包装了,愿每个码农都把基础学好,再学框架,不要一上来就mybatis,据说新码农都没写过原生servlet,更别提开发了。。。
总结:
自己早年封装的jdbc组件,简单易用,适合小规模化开发,主要当时技术受限,大量数据库连接没处理好,没有池化和缓存策略,且对码农的sql功底很强,其实面向SQL编程
hibernate,个人觉得一个很不错得到orm框架,脱离了部分sql,只是没推广好
mybatis ,从架构上来说和hibernate雷同,生态圈建立的好,也有大厂光环。
汇总一句话:再好的orm,也脱离不了最最最基本的JDBC,劝扎进框架圈里的人,务必打好基础,框架各有千秋,没有最好,只要合适!!!
参考:
0. Develop Java applications with Oracle Database https://www.oracle.com/database/technologies/appdev/jdbc.html
2. JNDI数据库连接池配置 https://www.iteye.com/blog/xiaoliang330-978823
4. Java Mybatis框架入门教程 http://c.biancheng.net/mybatis/