作为后台服务开发,在日常工作中我们天天都在跟数据库打交道,一直在进行各种CRUD操作,都会使用到数据库连接池。按照发展历程,业界知名的数据库连接池有以下几种:c3p0、DBCP、Tomcat JDBC Connection Pool、Druid 等,不过最近最火的是 HiKariCP。
HiKariCP 号称是业界跑得最快的数据库连接池,自从 SpringBoot 2.0 将其作为默认数据库连接池后,其发展势头锐不可当。那它为什么那么快呢?今天咱们就重点聊聊其中的原因。
一、什么是数据库连接池
在讲解HiKariCP之前,我们先简单介绍下什么是数据库连接池(Database Connection Pooling),以及为什么要有数据库连接池。
从根本上而言,数据库连接池和我们常用的线程池一样,都属于池化资源,它在程序初始化时创建一定数量的数据库连接对象并将其保存在一块内存区中。它允许应用程序重复使用一个现有的数据库连接,当需要执行 SQL 时,我们是直接从连接池中获取一个连接,而不是重新建立一个数据库连接,当 SQL 执行完,也并不是将数据库连接真的关掉,而是将其归还到数据库连接池中。我们可以通过配置连接池的参数来控制连接池中的初始连接数、最小连接、最大连接、最大空闲时间等参数,来保证访问数据库的数量在一定可控制的范围类,防止系统崩溃,同时保证用户良好的体验。数据库连接池示意图如下所示:
因此使用数据库连接池的核心作用,就是避免数据库连接频繁创建和销毁,节省系统开销。因为数据库连接是有限且代价昂贵,创建和释放数据库连接都非常耗时,频繁地进行这样的操作将占用大量的性能开销,进而导致网站的响应速度下降,甚至引起服务器崩溃。
二、常见数据库连接池对比分析
这里详细总结了常见数据库连接池的各项功能比较,我们重点分析下当前主流的阿里巴巴Druid与HikariCP,HikariCP在性能上是完全优于Druid连接池的。而Druid的性能稍微差点是由于锁机制的不同,并且Druid提供更丰富的功能,包括监控、sql拦截与解析等功能,两者的侧重点不一样,HikariCP追求极致的高性能。
下面是官网提供的性能对比图,在性能上面这五种数据库连接池的排序如下:HikariCP>druid>tomcat-jdbc>dbcp>c3p0:
三、HikariCP 数据库连接池简介
HikariCP 号称是史上性能最好的数据库连接池,SpringBoot 2.0将它设置为默认的数据源连接池。Hikari相比起其它连接池的性能高了非常多,那么,这是怎么做到的呢?通过查看HikariCP官网介绍,对于HikariCP所做优化总结如下:
1. 字节码精简 : 优化代码,编译后的字节码量极少,使得CPU缓存可以加载更多的程序代码;
HikariCP在优化并精简字节码上也下了功夫,使用第三方的Java字节码修改类库Javassist来生成委托实现动态代理.动态代理的实现在ProxyFactory类,速度更快,相比于JDK Proxy生成的字节码更少,精简了很多不必要的字节码。
2. 优化代理和拦截器: 减少代码,例如HikariCP的Statement proxy只有100行代码,只有BoneCP的十分之一;
3. 自定义数组类型(FastStatementList)代替ArrayList: 避免ArrayList每次get()都要进行range check,避免调用remove()时的从头到尾的扫描(由于连接的特点是后获取连接的先释放);
4. 自定义集合类型(ConcurrentBag): 提高并发读写的效率;
5. 其他针对BoneCP缺陷的优化 ,比如对于耗时超过一个CPU时间片的方法调用的研究。
当然作为一个数据库连接池,不能说快就会被消费者所推崇,它还具有非常好的健壮性及稳定性。HikariCP从15年推出以来,已经经受了广大应用市场的考验,并且成功地被SpringBoot2.0作为默认数据库连接池进行推广,在可靠性上面是值得信任的。其次借助于其代码量少,占用cpu和内存量小的优点,使得它的执行率非常高。最后,Spring配置HikariCP和druid基本没什么区别,迁移过来非常方便,这些都是为什么HikariCP目前如此受欢迎的原因。
字节码精简、优化代理和拦截器、自定义数组类型。
四、HikariCP 核心源码解析
4.1 FastList 是如何优化性能问题的
首先我们来看一下执行数据库操作规范化的操作步骤:
通过数据源获取一个数据库连接;
创建 Statement;
执行 SQL;
通过 ResultSet 获取 SQL 执行结果;
释放 ResultSet;
释放 Statement;
释放数据库连接。
当前所有数据库连接池都是严格地根据这个顺序来进行数据库操作的,为了防止最后的释放操作,各类数据库连接池都会把创建的 Statement 保存在数组 ArrayList 里,来保证当关闭连接的时候,可以依次将数组中的所有 Statement 关闭。HiKariCP 在处理这一步骤中,认为 ArrayList 的某些方法操作存在优化空间,因此对List接口的精简实现,针对List接口中核心的几个方法进行优化,其他部分与ArrayList基本一致 。
首先是get()方法,ArrayList每次调用get()方法时都会进行rangeCheck检查索引是否越界,FastList的实现中去除了这一检查,是因为数据库连接池满足索引的合法性,能保证不会越界,此时rangeCheck就属于无效的计算开销,所以不用每次都进行越界检查。省去频繁的无效操作,可以明显地减少性能消耗。
public T get(int index)
{
// ArrayList 在此多了范围检测 rangeCheck(index);
return elementData[index];
}
其次是remove方法,当通过 conn.createStatement() 创建一个 Statement 时,需要调用 ArrayList 的 add() 方法加入到 ArrayList 中,这个是没有问题的;但是当通过 stmt.close() 关闭 Statement 的时候,需要调用 ArrayList 的 remove() 方法来将其从 ArrayList 中删除,而ArrayList的remove(Object)方法是从头开始遍历数组,而FastList是从数组的尾部开始遍历,因此更为高效。假设一个 Connection 依次创建 6 个 Statement,分别是 S1、S2、S3、S4、S5、S6,而关闭 Statement 的顺序一般都是逆序的,从S6 到 S1,而 ArrayList 的 remove(Object o) 方法是顺序遍历查找,逆序删除而顺序查找,这样的查找效率就太慢了。因此FastList对其进行优化,改成了逆序查找。如下代码为FastList 实现的数据移除操作,相比于ArrayList的 remove()代码, FastList 去除了检查范围 和 从头到尾遍历检查元素的步骤,其性能更快。
public boolean remove(Object element)
{
// 删除操作使用逆序查找
for (int index = size - 1; index >= 0; index--) {
if (element == elementData[index]) {
final int numMoved = size - index - 1;
// 如果角标不是最后一个,复制一个新的数组结构
if (numMoved > 0) {
System.arraycopy(elementData, index + 1, elementData, index, numMoved);
}
//如果角标是最后面的 直接初始化为null
elementData[--size] = null;
return true;
}
}
return false;
}
通过上述源码分析,FastList 的优化点还是很简单的。相比ArrayList仅仅是去掉了rage检查,扩容优化等细节处,删除时数组从后往前遍历查找元素等微小的调整,从而追求性能极致。当然FastList 对于 ArrayList 的优化,我们不能说ArrayList不好。所谓定位不同、追求不同,ArrayList作为通用容器,更追求安全、稳定,操作前rangeCheck检查,对非法请求直接抛出异常,更符合 fail-fast(快速失败)机制,而FastList追求的是性能极致。
下面我们再来聊聊 HiKariCP 中的另外一个数据结构 ConcurrentBag,看看它又是如何提升性能的。
4.2 ConcurrentBag 实现原理分析
当前主流数据库连接池实现方式,大都用两个阻塞队列来实现。一个用于保存空闲数据库连接的队列 idle,另一个用于保存忙碌数据库连接的队列 busy;获取连接时将空闲的数据库连接从 idle 队列移动到 busy 队列,而关闭连接时将数据库连接从 busy 移动到 idle。这种方案将并发问题委托给了阻塞队列,实现简单,但是性能并不是很理想。因为 Java SDK 中的阻塞队列是用锁实现的,而高并发场景下锁的争用对性能影响很大。
HiKariCP 并没有使用 Java SDK 中的阻塞队列,而是自己实现了一个叫做 ConcurrentBag 的并发容器,在连接池(多线程数据交互)的实现上具有比LinkedBlockingQueue和LinkedTransferQueue更优越的性能。
ConcurrentBag 中最关键的属性有 4 个,分别是:用于存储所有的数据库连接的共享队列 sharedList、线程本地存储 threadList、等待数据库连接的线程数 waiters 以及分配数据库连接的工具 handoffQueue。其中,handoffQueue 用的是 Java SDK 提供的 SynchronousQueue,SynchronousQueue 主要用于线程之间传递数据。
// 存放共享元素,用于存储所有的数据库连接
private final CopyOnWriteArrayList sharedList;
// 在 ThreadLocal 缓存线程本地的数据库连接,避免线程争用
private final ThreadLocal> threadList;
// 等待数据库连接的线程数
private final AtomicInteger waiters;
// 接力队列,用来分配数据库连接
private final SynchronousQueue handoffQueue;
ConcurrentBag 保证了全部的资源均只能通过 add() 方法进行添加,当线程池创建了一个数据库连接时,通过调用 ConcurrentBag 的 add() 方法加入到 ConcurrentBag 中,并通过 remove() 方法进行移出。下面是 add() 方法和 remove() 方法的具体实现,添加时实现了将这个连接加入到共享队列 sharedList 中,如果此时有线程在等待数据库连接,那么就通过 handoffQueue 将这个连接分配给等待的线程。
public void add(final T bagEntry)
{
if (closed) {
LOGGER.info("ConcurrentBag has been closed, ignoring add()");
throw new IllegalStateException("ConcurrentBag has been closed, ignoring add()");
}
// 新添加的资源优先放入sharedList
sharedList.add(bagEntry);
// 当有等待资源的线程时,将资源交到等待线程 handoffQueue 后才返回
while (waiters.get() > 0 && bagEntry.getState() == STATE_NOT_IN_USE && !handoffQueue.offer(bagEntry)) {
yield();
}
}
public boolean remove(final T bagEntry)
{
// 如果资源正在使用且无法进行状态切换,则返回失败
if (!bagEntry.compareAndSet(STATE_IN_USE, STATE_REMOVED) && !bagEntry.compareAndSet(STATE_RESERVED, STATE_REMOVED) && !closed) {
LOGGER.warn("Attempt to remove an object from the bag that was not borrowed or reserved: {}", bagEntry);
return false;
}
// 从sharedList中移出
final boolean removed = sharedList.remove(bagEntry);
if (!removed && !closed) {
LOGGER.warn("Attempt to remove an object from the bag that does not exist: {}", bagEntry);
}
return removed;
}
同时ConcurrentBag通过提供的 borrow() 方法来获取一个空闲的数据库连接,并通过requite()方法进行资源回收,borrow() 的主要逻辑是:
查看线程本地存储 threadList 中是否有空闲连接,如果有,则返回一个空闲的连接;
如果线程本地存储中无空闲连接,则从共享队列 sharedList 中获取;
如果共享队列中也没有空闲的连接,则请求线程需要等待。
// 该方法会从连接池中获取连接, 如果没有连接可用, 会一直等待timeout超时
public T borrow(long timeout, final TimeUnit timeUnit) throws InterruptedException
{
// 首先查看线程本地资源threadList是否有空闲连接
final List list = threadList.get();
// 从后往前反向遍历是有好处的, 因为最后一次使用的连接, 空闲的可能性比较大, 之前的连接可能会被其他线程提前借走了
for (int i = list.size() - 1; i >= 0; i--) {
final Object entry = list.remove(i);
@SuppressWarnings("unchecked")
final T bagEntry = weakThreadLocals ? ((WeakReference) entry).get() : (T) entry;
// 线程本地存储中的连接也可以被窃取, 所以需要用CAS方法防止重复分配
if (bagEntry != null && bagEntry.compareAndSet(STATE_NOT_IN_USE, STATE_IN_USE)) {
return bagEntry;
}
}
// 当无可用本地化资源时,遍历全部资源,查看可用资源,并用CAS方法防止资源被重复分配
final int waiting = waiters.incrementAndGet();
try {
for (T bagEntry : sharedList) {
if (bagEntry.compareAndSet(STATE_NOT_IN_USE, STATE_IN_USE)) {
// 因为可能“抢走”了其他线程的资源,因此提醒包裹进行资源添加
if (waiting > 1) {
listener.addBagItem(waiting - 1);
}
return bagEntry;
}
}
listener.addBagItem(waiting);
timeout = timeUnit.toNanos(timeout);
do {
final long start = currentTime();
// 当现有全部资源都在使用中时,等待一个被释放的资源或者一个新资源
final T bagEntry = handoffQueue.poll(timeout, NANOSECONDS);
if (bagEntry == null || bagEntry.compareAndSet(STATE_NOT_IN_USE, STATE_IN_USE)) {
return bagEntry;
}
timeout -= elapsedNanos(start);
} while (timeout > 10_000);
return null;
}
finally {
waiters.decrementAndGet();
}
}
public void requite(final T bagEntry)
{
// 将资源状态转为未在使用
bagEntry.setState(STATE_NOT_IN_USE);
// 判断是否存在等待线程,若存在,则直接转手资源
for (int i = 0; waiters.get() > 0; i++) {
if (bagEntry.getState() != STATE_NOT_IN_USE || handoffQueue.offer(bagEntry)) {
return;
}
else if ((i & 0xff) == 0xff) {
parkNanos(MICROSECONDS.toNanos(10));
}
else {
yield();
}
}
// 否则,进行资源本地化处理
final List threadLocalList = threadList.get();
if (threadLocalList.size() < 50) {
threadLocalList.add(weakThreadLocals ? new WeakReference<>(bagEntry) : bagEntry);
}
}
borrow() 方法可以说是整个 HikariCP 中最核心的方法,它是我们从连接池中获取连接的时候最终会调用到的方法。需要注意的是 borrow() 方法只提供对象引用,不移除对象,因此使用时必须通过 requite() 方法进行放回,否则容易导致内存泄露。requite() 方法首先将数据库连接状态改为未使用,之后查看是否存在等待线程,如果有则分配给等待线程;否则将该数据库连接保存到线程本地存储里。
ConcurrentBag 实现采用了queue-stealing的机制获取元素:首先尝试从ThreadLocal中获取属于当前线程的元素来避免锁竞争,如果没有可用元素则再次从共享的CopyOnWriteArrayList中获取。此外,ThreadLocal和CopyOnWriteArrayList在ConcurrentBag中都是成员变量,线程间不共享,避免了伪共享(false sharing)的发生。同时因为线程本地存储中的连接是可以被其他线程窃取的,在共享队列中获取空闲连接,所以需要用 CAS 方法防止重复分配。
五、总结
Hikari 作为 SpringBoot2.0默认的连接池,目前在行业内使用范围非常广,对于大部分业务来说,都可以实现快速接入使用,做到高效连接。
参考资料
https://github.com/brettwooldridge/HikariCP
https://github.com/alibaba/druid
作者:vivo 游戏技术团队
你可能感兴趣的:(技术干货,数据库,SpringBoot,HikariCP,ThreadLocal)
python数据库操作sqlite_使用Python对SQLite数据库操作
weixin_39756235
SQLite是一种嵌入式数据库,它的数据库就是一个文件。由于SQLite本身是C写的,而且体积很小,所以,经常被集成到各种应用程序中,甚至在IOS和Android的APP中都可以集成。Python内置了SQLite3,所以,在Python中使用SQLite,不需要安装任何东西,直接使用。在使用SQLite前,我们先要搞清楚几个概念:表是数据库中存放关系数据的集合,一个数据库里面通常都包含多个表,比
计算机毕业设计之springcloud基于微服务架构的学习系统的设计与实现
bishe22是微
课程设计 spring cloud 微服务 后端 java
本文首先实现了基于微服务架构的学习系统的发展,随后依照传统的软件开发流程,最先为系统挑选适用的言语和软件开发平台,依据需求分析开展控制模块制做和数据库查询构造设计,随后依据系统整体功能模块的设计,制作系统的功能模块图、E-R图。随后,设计框架,依据设计的框架撰写编码,完成系统的每个功能模块。最终,对基本系统开展了检测,包含软件性能测试、单元测试和性能指标。测试结果表明,该系统能够实现所需的功能,运
如何使用 Python 连接 SQLite 数据库?
程序员黄同学
数据库 Python面试题 Python 数据库 python sqlite
SQLite是一种轻量级的嵌入式数据库,广泛应用于各种应用程序中。Python提供了内置的sqlite3模块,使得连接和操作SQLite数据库变得非常简单。下面我将详细介绍如何使用sqlite3模块来连接SQLite数据库,并提供一些实际开发中的建议和注意事项。1.使用sqlite3连接SQLite数据库sqlite3是Python标准库中的一个模块,无需额外安装即可使用。连接数据库下面是一个简单
基于springboot+mybatis+vue的学生成绩管理系统
Mae_strive
mybatis spring boot vue.js
文章目录一、数据库设计ER图二、系统功能三、技术栈四、项目主要功能演示五、部分源代码一、数据库设计学生(学号,姓名,专业,班级,性别,学分)老师(教师编号,姓名,学院)课程(课程号,课程名,学分,教师编号)成绩(学号,课程号,成绩)ER图二、系统功能1.管理员分配账号给学生、老师。2.学生、教师登录3.学生可查询自己的成绩,选课。4.教师可以给选择自己课程的学生打分。三、技术栈springboot
Mysql锁机制
LiuYuHani
mysql 数据库
全局锁全局锁是一种锁定机制,它可以对整个数据库或特定的资源进行锁定。全局锁:全局锁是一种锁定机制,可以锁定整个数据库或特定的资源。主要用于全库备份、大规模数据迁移等场景。全局锁会阻塞所有其他并发操作,影响数据库的并发性能行锁:行锁是针对单个数据行进行的锁定,主要用于InnoDB存储引擎。行锁可以最大程度地减少锁冲突,提高并发性和系统吞吐量。表锁:表锁是针对整张表进行的锁定,通常用于对表
vue3基于SpringBoot的航空散货调度系统
计算机专业码农一枚
spring boot 后端 java
目录功能和开发技术介绍具体实现截图开发核心技术介绍:技术创新点vue3和vue2的区别:核心代码部分展示非功能需求分析系统开发流程系统运行步骤软件测试源码获取功能和开发技术介绍本课题拟采用主流的MVC架构、开发工具idea、java语言编程、MySQL数据库技术、Vue.js技术和现代网络通讯技术来完成。1.前后端分离项目,前端使用vue3框架2.后端使用java编程语言的springboot框架
Springboot+Vue的前后端分离的相册管理系统
叁拾舞
java spring boot vue.js
相册名:wuPic注意注意:相册管理系统现已升级2.0版本。加入springshiro控制权限。更新内容如下:普通用户:查看图片(非私密图片)。上传图片。管理自己的图片。管理自己的相册。管理员:查看所有的图片(不包含隐私图片)。管理所有图片。管理所有相册。发布公告。游客:只能查看首页的图片。无法查看相册、管理相册以及上传图片。更新之后的代码我已经上传到资源,大家下载之后遇到任何问题可直接私信我。目
DataWhale wow-agent task 2: llama-index搭建电商数据库查询&课本问答agent
Meteora1024875
数据库 llama
创建demoagentllama-index默认调用OpenAI大模型,调用其他模型需要继承CustomLLM类自定义一个类。教程中还实现了一个流式输出的功能,即各大ai聊天平台上的打字机效果。这节课构建的agent暂且不需要记忆对话历史。llama-index库之于openai库的优势方便连接外部数据SQL数据库操作配置对话模型创建数据库对话引擎llama中的NLSQLTableQueryEng
Java基于SpringBoot+Vue的航空/集装箱散货调度系统(源码+文档+运行视频+讲解视频)
QQ177825331
java spring boot vue.js
所需该项目可以在最下面查看联系方式,为防止迷路可以收藏文章,以防后期找不到项目介绍Java基于SpringBoot+Vue的航空/集装箱散货调度系统(源码+文档+运行视频+讲解视频)系统实现截图技术栈介绍JDK版本:jdk1.8+编程语言:java框架支持:springboot数据库:mysql版本不限数据库工具:Navicat/SQLyog都可以前端:vue.js+ElementUI开发工具:I
2024年12月中国数据库排行榜:群雄竞逐显风采,GoldenDB摘探花
2024年末的墨天轮中国数据库排行榜如期发布。回顾整年,榜单持续波动:OceanBase与PolarDB交替登顶,前三甲的位置也不断迎来新晋挑战者。在最新一期的榜单中,GoldenDB凭借技术创新与市场积淀成功跃升前三,openGauss与TDSQL出现了位次调整,其他产品也在不断沉淀与创新中激发出新的动力。可以预见,随着技术的不断突破和市场需求的日益变化,2025年将迎来更加激烈的竞争与更多的创
高可用架构设计
小王爱编程啊
rocketmq java 开发语言
1.全链路服务保护方案-接入层防护:*使用Sentinel实现接口级限流,支持QPS、并发线程数等多维度限流*配置基于滑动时间窗口的热点参数限流策略*实现自适应限流算法,根据系统负载动态调整阈值-服务层防护:*实现基于RateLimiter的方法级限流*配置线程池隔离,避免服务间相互影响*使用Hystrix实现服务熔断,配置错误率阈值自动降级-数据层防护:*实现数据库连接池管理,配置最大连接数限制
Java垃圾分类回收系统web社区垃圾运输回收springboot/ssm代码编写
kirito学长-Java
java 开发语言
Java垃圾分类回收系统web校园社区垃圾运输回收管理springboot/ssm代码编写基于springboot(可改ssm)+html+vue项目开发语言:Java框架:springboot/可改ssm+vueJDK版本:JDK1.8(或11)服务器:tomcat数据库:mysql5.7(或8.0)数据库工具:Navicat/sqlyog开发软件:eclipse/idea依赖管理包:Maven
从架构到实现:关系型数据库设计技术分享
码农老起
数据库 数据库 架构 oracle
目录一.关系型数据库的基本架构:表、模式、数据库实例二.数据库范式:1NF、2NF、3NF及BCNF三.数据库设计的基本原则四.数据模型:ER模型(实体-关系模型)五.数据库约束:主键、外键、唯一约束、检查约束等总结关系型数据库(RDBMS)架构与设计:在现代信息系统中,关系型数据库(RDBMS)依然是最常用的数据存储技术之一。无论是中小型企业还是大型互联网公司,关系型数据库因其高度的结构化、灵活
名词(术语)了解--架构-MVCMVVMMVP
秋月霜风
架构
名词(术语)了解–架构-MVC/MVVM/MVPMVC模型(Model)负责应用程序的数据逻辑和业务规则维护数据的状态和完整性与数据库等持久化层交互不依赖于视图和控制器当数据发生变化时,通知相关的视图进行更新视图(View)负责数据的可视化展示将模型的数据呈现给用户接收用户的操作输入可以存在多个视图展示同一个模型的数据不直接处理业务逻辑控制器(Controller)作为模型和视图之间的中介处理用户
2025基于苹果CMS影视站群系统设计:实现缓存优化、泛目录与泛解析并增加AI生成文章插件
奥顺互联V
泛目录 苹果cms 缓存 人工智能 php 开源 前端 音视频 mysql
项目标题基于苹果CMS的影视站群系统设计与开发:实现缓存优化、泛目录与泛解析功能,并增加AI生成文章插件1.项目背景随着视频内容的激增,影视站群系统需要具备高效的内容管理和分发能力。通过苹果CMS进行二次开发,实现缓存优化、泛目录和泛解析功能,并引入AI生成文章插件,将显著提升系统性能和用户体验。2.功能需求2.1缓存优化页面缓存:实现对静态页面的缓存,减少数据库查询,提高页面加载速度。数据缓存:
2025年SSM框架的毕业设计推荐
yh1340327157
计算机毕设选题推荐案例 课程设计 java 开发语言 intellij-idea maven 后端 spring boot
博主介绍:✌全网粉丝30W+,CSDN全栈领域优质创作者,博客之星、掘金/华为云/阿里云等平台优质作者,计算机毕设实战导师。目前专注于大学生项目实战开发,讲解,毕业答疑辅导✌主要服务内容:选题定题、开题报告、任务书、程序开发、文档编写和辅导、文档降重、程序讲解、答辩辅导等,欢迎咨询~文末获取源码+数据库+文档感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及文档编写等相关问题都可以给我沟通,希望
Mybatis
一十一code
javaEE mybatis
什么是MyBatis?MyBatis是一款优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解来配置和映射原生信息,将接口和Java的POJOs(PlainOldJavaObjects,普通的Java对象)映射成数据库中的记录。mybatis和hibernate的比较mybati
SpringBoot 引⼊MybatisGenerator
雨 子
JavaEE spring boot java spring
SpringBoot引⼊MybatisGenerator1.引入插件2.添加generator.xml并修改3.生成文件1.引入插件org.mybatis.generatormybatis-generator-maven-plugin1.3.5src/main/resources/mybatis-generator/generatorConfig.xmltruetruemysqlmysql-con
Express连接postgres数据库
叁拾舞
数据库 express 数据库
文章目录Express介绍创建express项目连接postgres数据库创建查询接口创建插入接口Express介绍Express是一个基于Node.js的轻量级Web框架,用于快速构建RESTfulAPI和Web应用。它提供了路由、中间件、模板引擎等功能,是Node.js开发中最流行的框架之一。创建express项目新建【express-pgAdmin】文件夹,并用cmd打开,运行如下命令,使用
不同数据库与 WebGL 集成
一只小灿灿
# WebGL 数据库 webgl
一、引言在当今数字化时代,数据可视化是一个关键需求,而WebGL(WebGraphicsLibrary)为在网页上实现高性能3D图形渲染提供了强大的工具。然而,WebGL本身无法直接与数据库进行交互,为了将数据库中的数据以3D图形的形式展示在网页上,就需要借助后端服务器来实现WebGL与不同数据库的集成。本文将详细介绍如何使用常见的数据库,如SQLite、MySQL、Redis和MongoDB,与
SpringBoot 整合 Mybatis:提升你的Java项目开发效率
苏-言
java spring boot mybatis
第一章:数据自动管理引入JDBC的依赖和SpringBoot的应用场景:org.springframework.bootspring-boot-starter-jdbcorg.apache.commonscommons-dbcp2mysqlmysql-connector-javaruntime创建application.yaml进行配置:spring:datasource:username:roo
Mongo简介
修巴利耶
# Mongo 数据库 nosql mongodb
Mongo简介MongoDB是一种强大、灵活、追求性能、易扩展的数据库;是面向文档的数据库,不是关系型数据库,是NoSQL(notonlySQL)的一种。MongoDB的面向文档,就是将关系型数据库中的“行”的概念换成了更加灵活的”文档”,以文档为存储单位。文档的值可以是数组、文档等复杂的数据模型,这使得MongoDB可以支持复杂的结构类型;另外MongoDB也不需要预先定义文档的键值,这使得开发
MongoDB简介
白菜4220
MongoDB
在数据存储中,最常见的三种存储方案是:在文件系统的文件中直接存储,关系数据库和NoSQL数据库。本篇文章讲的就是第三类:一种叫MongoDB的NoSQL数据库。1,什么是NoSQLNoSQL(notonlySQL):由提供缺乏传统SQL关系数据库的严格限制模型的存储和检索技术组成。NoSQL背后的主要动机是简化设计,水平扩展,以及对数据的可用性进行更精细的控制。NoSQL的思路是打破关系数据库的传
非关系型数据库(NoSQL):MongoDB和Redis
檐角小猫
nosql 数据库 sql
非关系型数据库(NoSQL)在大数据和分布式计算环境中广泛使用,主要用于处理海量、结构化不统一的数据。NoSQL数据库种类包括文档型、键值型、列族型和图形数据库等。下面我将以MongoDB(一种流行的文档型NoSQL数据库)以及Redis为例,通过代码和案例讲解如何使用它。MongoDB简介MongoDB是一种基于文档存储模式的NoSQL数据库,数据以BSON格式(类似JSON)存储。它支持灵活的
ORA-01555 的应对方法?思维导图 代码示例(java 架构)
用心去追梦
java 架构 oracle
ORA-01555是Oracle数据库中的一个错误代码,表示“快照太旧(snapshottooold)”。这个错误通常发生在读取一致性查询时,当查询需要的数据已经被覆盖或移除,而这些数据对于恢复查询的一致性视图是必需的。这种情况可能会在长时间运行的查询中发生,尤其是在高并发和频繁更新的环境中。应对ORA-01555的方法为了有效应对ORA-01555错误,可以采取以下几种策略:增大UNDO表空间增
Python爬虫 -- 运用bs4爬取数据保存至sql数据库
小鞠..
Python爬虫 python 爬虫 开发语言 数据库 sql
网址链接:http://bang.dangdang.com/books/bestsellers/•导包importpymysqlimportrequestsfrombs4importBeautifulSoup•放入网址链接,转换格式url='http://bang.dangdang.com/books/bestsellers/'html=requests.get(url).text•连接数据库db
数据库操作 -- 添加数据、查看表结构、多表查询、创建视图、创建存储过程、多表删除记录
小鞠..
数据库 数据库 sql 数据库开发
创建数据表:T_student、T_course、T_score。任务点:•向每个表插入3条测试数据(样本数据包含下面题目中使用的数据);•查询出所有选修了“数据库原理”课程的学生学号、姓名和籍贯;•查询出“数据库原理”这门课的最高成绩;•查询有哪些课程没有被任何同学选修;•查询有哪些学生没有选修“日语”课程;•创建视图,统计每门课程的平均分,最高分,最低分;•创建存储过程,查询指定课程名称的平均
数据存储:Python对MySQL数据库操作
旧人小表弟
网络爬虫 数据库 mysql python sql java
安装mysql官网下载地址:https://dev.mysql.com/downloads/windows/installer/5.7.html如果提示没有.NETFramework框架,在提示框中找到下载链接,下载一个就可以了。如果提示没有MicrosoftVirtualC++x64(x86),百度或谷歌一下这个软件,安装即可。navicatnavicat是一个操作mysql数据库非常方便的可视
chatgpt赋能python:Python如何将数据存储在数据库中
虚幻私塾
chatgpt python 数据库 计算机
Python如何将数据存储在数据库中Python作为一种开发语言,不仅支持各种数据操作,还可以方便地将数据存储在数据库中。数据库技术是一项基础且重要的IT领域知识,掌握Python如何将数据存储在数据库中,对于开发者来说具有重要的意义。介绍在Python中存储数据可以选择使用文件,但是对于大量数据的存储和管理来说文件并不是最好的选择。相比之下,使用数据库可以更好地组织数据。Python有很多支持数
MySQL 进阶专题:自连接、子查询与合并查询的深入探讨
Purified_Soda
MySQL数据库 数据库 oracle mysql 学习 adb SQL
自连接、子查询与合并查询的深入探讨在关系型数据库中,自连接、子查询和合并查询是非常重要的技术。它们不仅能解决复杂的业务需求,还可以优化代码逻辑。本文结合实际案例和SQL语句,带您深入了解这些技术的使用场景和意义。自连接:表内关系的巧妙处理自连接是指在同一个表上执行连接操作。其作用在于处理表内的层级关系或对比同表中不同记录的属性。使用场景层级结构处理:如组织架构、商品分类。数据对比:如同一张表中,不
分享100个最新免费的高匿HTTP代理IP
mcj8089
代理IP 代理服务器 匿名代理 免费代理IP 最新代理IP
推荐两个代理IP网站:
1. 全网代理IP:http://proxy.goubanjia.com/
2. 敲代码免费IP:http://ip.qiaodm.com/
120.198.243.130:80,中国/广东省
58.251.78.71:8088,中国/广东省
183.207.228.22:83,中国/
mysql高级特性之数据分区
annan211
java 数据结构 mongodb 分区 mysql
mysql高级特性
1 以存储引擎的角度分析,分区表和物理表没有区别。是按照一定的规则将数据分别存储的逻辑设计。器底层是由多个物理字表组成。
2 分区的原理
分区表由多个相关的底层表实现,这些底层表也是由句柄对象表示,所以我们可以直接访问各个分区。存储引擎管理分区的各个底层
表和管理普通表一样(所有底层表都必须使用相同的存储引擎),分区表的索引只是
JS采用正则表达式简单获取URL地址栏参数
chiangfai
js 地址栏参数获取
GetUrlParam:function GetUrlParam(param){
var reg = new RegExp("(^|&)"+ param +"=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if(r!=null
怎样将数据表拷贝到powerdesigner (本地数据库表)
Array_06
powerDesigner
==================================================
1、打开PowerDesigner12,在菜单中按照如下方式进行操作
file->Reverse Engineer->DataBase
点击后,弹出 New Physical Data Model 的对话框
2、在General选项卡中
Model name:模板名字,自
logbackのhelloworld
飞翔的马甲
日志 logback
一、概述
1.日志是啥?
当我是个逗比的时候我是这么理解的:log.debug()代替了system.out.print();
当我项目工作时,以为是一堆得.log文件。
这两天项目发布新版本,比较轻松,决定好好地研究下日志以及logback。
传送门1:日志的作用与方法:
http://www.infoq.com/cn/articles/why-and-how-log
上面的作
新浪微博爬虫模拟登陆
随意而生
新浪微博
转载自:http://hi.baidu.com/erliang20088/item/251db4b040b8ce58ba0e1235
近来由于毕设需要,重新修改了新浪微博爬虫废了不少劲,希望下边的总结能够帮助后来的同学们。
现行版的模拟登陆与以前相比,最大的改动在于cookie获取时候的模拟url的请求
synchronized
香水浓
java thread
Java语言的关键字,可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码。当两个并发线程访问同一个对象object中的这个加锁同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。然而,当一个线程访问object的一个加锁代码块时,另一个线程仍然
maven 简单实用教程
AdyZhang
maven
1. Maven介绍 1.1. 简介 java编写的用于构建系统的自动化工具。目前版本是2.0.9,注意maven2和maven1有很大区别,阅读第三方文档时需要区分版本。 1.2. Maven资源 见官方网站;The 5 minute test,官方简易入门文档;Getting Started Tutorial,官方入门文档;Build Coo
Android 通过 intent传值获得null
aijuans
android
我在通过intent 获得传递兑现过的时候报错,空指针,我是getMap方法进行传值,代码如下 1 2 3 4 5 6 7 8 9
public
void
getMap(View view){
Intent i =
apache 做代理 报如下错误:The proxy server received an invalid response from an upstream
baalwolf
response
网站配置是apache+tomcat,tomcat没有报错,apache报错是:
The proxy server received an invalid response from an upstream server. The proxy server could not handle the request GET /. Reason: Error reading fr
Tomcat6 内存和线程配置
BigBird2012
tomcat6
1、修改启动时内存参数、并指定JVM时区 (在windows server 2008 下时间少了8个小时)
在Tomcat上运行j2ee项目代码时,经常会出现内存溢出的情况,解决办法是在系统参数中增加系统参数:
window下, 在catalina.bat最前面
set JAVA_OPTS=-XX:PermSize=64M -XX:MaxPermSize=128m -Xms5
Karam与TDD
bijian1013
Karam TDD
一.TDD
测试驱动开发(Test-Driven Development,TDD)是一种敏捷(AGILE)开发方法论,它把开发流程倒转了过来,在进行代码实现之前,首先保证编写测试用例,从而用测试来驱动开发(而不是把测试作为一项验证工具来使用)。
TDD的原则很简单:
a.只有当某个
[Zookeeper学习笔记之七]Zookeeper源代码分析之Zookeeper.States
bit1129
zookeeper
public enum States {
CONNECTING, //Zookeeper服务器不可用,客户端处于尝试链接状态
ASSOCIATING, //???
CONNECTED, //链接建立,可以与Zookeeper服务器正常通信
CONNECTEDREADONLY, //处于只读状态的链接状态,只读模式可以在
【Scala十四】Scala核心八:闭包
bit1129
scala
Free variable A free variable of an expression is a variable that’s used inside the expression but not defined inside the expression. For instance, in the function literal expression (x: Int) => (x
android发送json并解析返回json
ronin47
android
package com.http.test;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import
一份IT实习生的总结
brotherlamp
PHP php资料 php教程 php培训 php视频
今天突然发现在不知不觉中自己已经实习了 3 个月了,现在可能不算是真正意义上的实习吧,因为现在自己才大三,在这边撸代码的同时还要考虑到学校的功课跟期末考试。让我震惊的是,我完全想不到在这 3 个月里我到底学到了什么,这是一件多么悲催的事情啊。同时我对我应该 get 到什么新技能也很迷茫。所以今晚还是总结下把,让自己在接下来的实习生活有更加明确的方向。最后感谢工作室给我们几个人这个机会让我们提前出来
据说是2012年10月人人网校招的一道笔试题-给出一个重物重量为X,另外提供的小砝码重量分别为1,3,9。。。3^N。 将重物放到天平左侧,问在两边如何添加砝码
bylijinnan
java
public class ScalesBalance {
/**
* 题目:
* 给出一个重物重量为X,另外提供的小砝码重量分别为1,3,9。。。3^N。 (假设N无限大,但一种重量的砝码只有一个)
* 将重物放到天平左侧,问在两边如何添加砝码使两边平衡
*
* 分析:
* 三进制
* 我们约定括号表示里面的数是三进制,例如 47=(1202
dom4j最常用最简单的方法
chiangfai
dom4j
要使用dom4j读写XML文档,需要先下载dom4j包,dom4j官方网站在 http://www.dom4j.org/目前最新dom4j包下载地址:http://nchc.dl.sourceforge.net/sourceforge/dom4j/dom4j-1.6.1.zip
解开后有两个包,仅操作XML文档的话把dom4j-1.6.1.jar加入工程就可以了,如果需要使用XPath的话还需要
简单HBase笔记
chenchao051
hbase
一、Client-side write buffer 客户端缓存请求 描述:可以缓存客户端的请求,以此来减少RPC的次数,但是缓存只是被存在一个ArrayList中,所以多线程访问时不安全的。 可以使用getWriteBuffer()方法来取得客户端缓存中的数据。 默认关闭。 二、Scan的Caching 描述: next( )方法请求一行就要使用一次RPC,即使
mysqldump导出时出现when doing LOCK TABLES
daizj
mysql mysqdump 导数据
执行 mysqldump -uxxx -pxxx -hxxx -Pxxxx database tablename > tablename.sql
导出表时,会报
mysqldump: Got error: 1044: Access denied for user 'xxx'@'xxx' to database 'xxx' when doing LOCK TABLES
解决
CSS渲染原理
dcj3sjt126com
Web
从事Web前端开发的人都与CSS打交道很多,有的人也许不知道css是怎么去工作的,写出来的css浏览器是怎么样去解析的呢?当这个成为我们提高css水平的一个瓶颈时,是否应该多了解一下呢?
一、浏览器的发展与CSS
《阿甘正传》台词
dcj3sjt126com
Part Ⅰ:
《阿甘正传》Forrest Gump经典中英文对白
Forrest: Hello! My names Forrest. Forrest Gump. You wanna Chocolate? I could eat about a million and a half othese. My momma always said life was like a box ochocol
Java处理JSON
dyy_gusi
json
Json在数据传输中很好用,原因是JSON 比 XML 更小、更快,更易解析。
在Java程序中,如何使用处理JSON,现在有很多工具可以处理,比较流行常用的是google的gson和alibaba的fastjson,具体使用如下:
1、读取json然后处理
class ReadJSON
{
public static void main(String[] args)
win7下nginx和php的配置
geeksun
nginx
1. 安装包准备
nginx : 从nginx.org下载nginx-1.8.0.zip
php: 从php.net下载php-5.6.10-Win32-VC11-x64.zip, php是免安装文件。
RunHiddenConsole: 用于隐藏命令行窗口
2. 配置
# java用8080端口做应用服务器,nginx反向代理到这个端口即可
p
基于2.8版本redis配置文件中文解释
hongtoushizi
redis
转载自: http://wangwei007.blog.51cto.com/68019/1548167
在Redis中直接启动redis-server服务时, 采用的是默认的配置文件。采用redis-server xxx.conf 这样的方式可以按照指定的配置文件来运行Redis服务。下面是Redis2.8.9的配置文
第五章 常用Lua开发库3-模板渲染
jinnianshilongnian
nginx lua
动态web网页开发是Web开发中一个常见的场景,比如像京东商品详情页,其页面逻辑是非常复杂的,需要使用模板技术来实现。而Lua中也有许多模板引擎,如目前我在使用的lua-resty-template,可以渲染很复杂的页面,借助LuaJIT其性能也是可以接受的。
如果学习过JavaEE中的servlet和JSP的话,应该知道JSP模板最终会被翻译成Servlet来执行;而lua-r
JZSearch大数据搜索引擎
颠覆者
JavaScript
系统简介:
大数据的特点有四个层面:第一,数据体量巨大。从TB级别,跃升到PB级别;第二,数据类型繁多。网络日志、视频、图片、地理位置信息等等。第三,价值密度低。以视频为例,连续不间断监控过程中,可能有用的数据仅仅有一两秒。第四,处理速度快。最后这一点也是和传统的数据挖掘技术有着本质的不同。业界将其归纳为4个“V”——Volume,Variety,Value,Velocity。大数据搜索引
10招让你成为杰出的Java程序员
pda158
java 编程 框架
如果你是一个热衷于技术的
Java 程序员, 那么下面的 10 个要点可以让你在众多 Java 开发人员中脱颖而出。
1. 拥有扎实的基础和深刻理解 OO 原则 对于 Java 程序员,深刻理解 Object Oriented Programming(面向对象编程)这一概念是必须的。没有 OOPS 的坚实基础,就领会不了像 Java 这些面向对象编程语言
tomcat之oracle连接池配置
小网客
oracle
tomcat版本7.0
配置oracle连接池方式:
修改tomcat的server.xml配置文件:
<GlobalNamingResources>
<Resource name="utermdatasource" auth="Container"
type="javax.sql.DataSou
Oracle 分页算法汇总
vipbooks
oracle sql 算法 .net
这是我找到的一些关于Oracle分页的算法,大家那里还有没有其他好的算法没?我们大家一起分享一下!
-- Oracle 分页算法一
select * from (
select page.*,rownum rn from (select * from help) page
-- 20 = (currentPag