[Java基础]—JDBC
前言
其实学Mybatis前就该学了,但是寻思目前主流框架都是用mybatis和mybatis-plus就没再去看,结果在代码审计中遇到了很多cms是使用jdbc的因此还是再学一下吧。
第一个JDBC程序
sql文件
INSERT INTO `users`(`id`, `NAME`, `PASSWORD`, `email`, `birthday`) VALUES (1, 'zhansan', '123456', 'zs@sina.com', '1980-12-04');
INSERT INTO `users`(`id`, `NAME`, `PASSWORD`, `email`, `birthday`) VALUES (2, 'lisi', '123456', 'lisi@sina.com', '1981-12-04');
INSERT INTO `users`(`id`, `NAME`, `PASSWORD`, `email`, `birthday`) VALUES (3, 'wangwu', '123456', 'wangwu@sina.com', '1979-12-04');
HelloJDBC
import java.sql.*;public class HelloJDBC {public static void main(String[] args) throws ClassNotFoundException, SQLException {//1. 加载驱动Class.forName("com.mysql.jdbc.Driver");//2. 用户信息和urlString url = "jdbc:mysql://127.0.0.1:3306/jdbc?useUnicode=true&characterEncoding=utf8&useSSL=true";String name = "root";String password = "123456";//3. 连接数据库 connection是数据库对象Connection connection = DriverManager.getConnection(url, name, password);//4. 执行sql的对象 statement是执行sql的对象Statement statement = connection.createStatement();//5. 用statement对象执行sql语句String sql = "select * from users";ResultSet resultSet = statement.executeQuery(sql);while (resultSet.next()){System.out.println("id:"+resultSet.getObject("id")+",name:"+resultSet.getObject("name")+",password:"+resultSet.getObject("password"));System.out.println("=============================");}//6.释放资源resultSet.close();statement.close();connection.close();}
}
Statement对象
工具类
package utils;import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;public class JdbcUtils {public static Connection connection() throws ClassNotFoundException, SQLException, IOException {InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");Properties properties = new Properties();properties.load(in);String driver = properties.getProperty("driver");String url = properties.getProperty("url");String username = properties.getProperty("username");String password = properties.getProperty("password");Class.forName(driver);return DriverManager.getConnection(url,username,password);}public static void relese(ResultSet resultSet, Statement statement, Connection connection) throws SQLException {if (resultSet!=null){resultSet.close();}if (statement!=null){statement.close();}if (connection!=null){connection.close();}}
}
Demo
import utils.JdbcUtils;import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;public class JdbcStatement {public static void main(String[] args) throws Exception {
// query();insert();}public static void query() throws SQLException, ClassNotFoundException, IOException{Connection connection = JdbcUtils.connection();String sql = "select * from users";Statement statement = connection.createStatement();ResultSet resultSet = statement.executeQuery(sql);while(resultSet.next()){System.out.println("id:"+resultSet.getObject("id"));}JdbcUtils.relese(resultSet,statement,connection);}public static void insert() throws Exception{Connection connection = JdbcUtils.connection();String sql = "insert into users values(4,'Sentiment',123456,'Sentiment@qq.com','1980-12-04')";Statement statement = connection.createStatement();int i = statement.executeUpdate(sql);System.out.println(i);JdbcUtils.relese(null,statement,connection);}
}
查询用executeQuery(),增、删、改用executeUpdate()
PreparedStatement对象
用statement的话会有sql注入问题,因此可以用preparedstatement进行预处理来进行防御
主要是通过占位符来执行查询语句
public class JdbcPreparedStatement {public static void main(String[] args) throws SQLException, IOException, ClassNotFoundException {Connection connection = JdbcUtils.connection();String sql = "insert into users values(?,?,?,null,null)";PreparedStatement ps = connection.prepareStatement(sql);ps.setInt(1,5);ps.setString(2,"Sentiment");ps.setInt(3,123456);ps.execute();}
}
操作事务
mybatis中学过,不过连含义都忘了。。。。
其实就是执行语句时要不都成功执行,一个不能执行则全部都不执行
主要就是关闭自动提交事务
connection.setAutoCommit(false); //开启事务
Demo
PreparedStatement ps = null;Connection connection = null;try {connection = JdbcUtils.connection();//关闭数烟库的自动提交,自动会开启事务connectionconnection.setAutoCommit(false); //开启事务String sql1 = "update users set name = 'Sentiment' where id=3";ps = connection.prepareStatement(sql1);ps.executeUpdate();int x = 1 / 0;String sql2 = "update users set name = 'Sentiment' where id=1";ps = connection.prepareStatement(sql2);ps.executeUpdate();connection.commit();System.out.println("Success!");}catch (SQLException e){connection.rollback(); //执行失败后,事务回滚}finally {JdbcUtils.relese(null,ps,connection);}}
数据库连接池
在上述工具类中,是通过以下方法来获取配置文件参数,并连接连接池
String driver = properties.getProperty("driver");
String url = properties.getProperty("url");
String username = properties.getProperty("username");
String password = properties.getProperty("password");
Class.forName(driver);
return DriverManager.getConnection(url,username,password);
而我们可以用开源的数据库连接池如DBCP、C3P0、Druid等
使用了这些数据库连接池之后,我们在项目开发中就不需要编写连接数据库的代码了!
DBCP
<dependency><groupId>commons-dbcp</groupId><artifactId>commons-dbcp</artifactId><version>1.4</version>
</dependency><dependency><groupId>commons-pool</groupId><artifactId>commons-pool</artifactId><version>1.5.4</version>
</dependency>
配置文件
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/jdbc?useUnicode=true&characterEncoding=utf8&useSSL=true
username=root
password=123456#<!-- 初始化连接 -->
initialSize=10#最大连接数量
maxActive=50#<!-- 最大空闲连接 -->
maxIdle=20#<!-- 最小空闲连接 -->
minIdle=5#<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
maxWait=60000
#JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:【属性名=property;】
#注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。
connectionProperties=useUnicode=true;characterEncoding=utf8#指定由连接池所创建的连接的自动提交(auto-commit)状态。
defaultAutoCommit=true#driver default 指定由连接池所创建的连接的只读(read-only)状态。
#如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)
defaultReadOnly=true#driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
#可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=READ_COMMITTED
Demo
使用DBCP后,utils就可以简化为:
public static Connection connection() throws Exception {InputStream in = DBCP_Utils.class.getClassLoader().getResourceAsStream("dbcp.properties");Properties properties = new Properties();properties.load(in);//创建数据源DataSource dataSource = BasicDataSourceFactory.createDataSource(properties);return dataSource.getConnection();
}
读取配置文件,交给数据源即可
C3P0
这个更简单
<dependency><groupId>com.mchange</groupId><artifactId>c3p0</artifactId><version>0.9.5.5</version>
</dependency>
<dependency><groupId>com.mchange</groupId><artifactId>mchange-commons-java</artifactId><version>0.2.19</version>
</dependency>
配置文件
这里设置了两个数据源:
<default-config>:默认值创建数据源时不需要形参,ComboPooledDataSource ds=new ComboPooledDataSource();
<named-config name="MySQL">: 非默认要指定数据源,ComboPooledDataSource ds=new ComboPooledDataSource(“MySQL”);
<?xml version="1.0" encoding="UTF-8"?><c3p0-config><!--c3p0的缺省(默认)配置如果在代码中"ComboPooledDataSource ds=new ComboPooledDataSource();"这样写就表示使用的是c3p0的缺省(默认)--><default-config><property name="driverClass">com.mysql.jdbc.Driver</property><property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/jdbc?useUnicode=true&characterEncoding=utf8&useSSL=true</property><property name="user">root</property><property name="password">123456</property><property name="acquiredIncrement">5</property><property name="initialPoolSize">10</property><property name="minPoolSize">5</property><property name="maxPoolSize">20</property></default-config><!--c3p0的命名配置如果在代码中"ComboPooledDataSource ds=new ComboPooledDataSource("MySQL");"这样写就表示使用的是mysql的缺省(默认)--><named-config name="MySQL"><property name="driverClass">com.mysql.jdbc.Driver</property><property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/jdbc?useUnicode=true&characterEncoding=utf8&useSSL=true</property><property name="user">root</property><property name="password">123456</property><property name="acquiredIncrement">5</property><property name="initialPoolSize">10</property><property name="minPoolSize">5</property><property name="maxPoolSize">20</property></named-config></c3p0-config>
Demo
xml文件默认能读取到
public static Connection connection() throws Exception {ComboPooledDataSource dataSource=new ComboPooledDataSource();return dataSource.getConnection();
}
自带日志

相关文章:
[Java基础]—JDBC
前言 其实学Mybatis前就该学了,但是寻思目前主流框架都是用mybatis和mybatis-plus就没再去看,结果在代码审计中遇到了很多cms是使用jdbc的因此还是再学一下吧。 第一个JDBC程序 sql文件 INSERT INTO users(id, NAME, PASSWORD, email, birthday) VAL…...
基本面向对象编程-计算机基本功能实现_
《C/S项目实训》实验报告 实验名称: 基本面向对象编程-计算机基本功能实现_ 一、实验目的 通过综合实践项目,理解Java 程序设计是如何体现面向对象编程基本思想,掌握OOP方法,掌握事件触发、消息响应机制。进一步巩固面向对…...
C++面向对象之多态性
文章目录C面向对象之多态性1.静态多态2.动态多态3.多态的好处3.1使用方法4.纯虚函数5.虚析构与纯虚析构5.1问题5.2解决6.其他知识点7.代码8.测试结果8.1父类中无虚函数,父类的指针指向子类对象,将调用父类中的函数,无法调用子类中的重写函数&…...
Android性能优化系列篇:弱网优化
弱网优化1、Serializable原理通常我们使用Java的序列化与反序列化时,只需要将类实现Serializable接口即可,剩下的事情就交给了jdk。今天我们就来探究一下,Java序列化是怎么实现的,然后探讨一下几个常见的集合类,他们是…...
Mysql 插入大批量数据调优方法
Mysql 插入大批量数据调优方法[toc]1、多线程插入(单表)在数据里做插入操作的时候,整体时间的分配是这样的:链接耗时 (30%)发送query到服务器 (20%)解析query (20%&#…...
matlab基础
系列文章目录 文章目录系列文章目录前言1 基本用法总结基础语法桌面管理矩阵均匀间隔矢量矩阵创建矩阵索引前言 介绍了matlab的基本用法 1 基本用法 >> save filename.mat % 将当前工作区的所有变量保存为mat文件 >> load filename.mat % 加载文件>> loa…...
自动化测试——多窗口切换和切换frame
这里写目录标题一、多窗口切换1、base.py:公共代码2、切换句柄的方式1,通过for循环3、切换句柄的方式2,通过索引切换4、源代码二、frame窗口1、什么是frame?2、Frame 分类3、判断要定位的元素在不在frame中两种方式方式一:鼠标选…...
C#中,Elasticsearch.Net判断空字符串
之前有个业务需求,由于最开始存储到es里的,是默认空字符串。 后面程序取数据时,发现需要取空字符串的数据时,不好取出来。 字符串的字段如图: 实际数据如图: 我用的是C#语言,使用的是Elastic…...
23种设计模式-适配器模式
适配器模式(Adapter Pattern)是一种常用的设计模式,它可以将不兼容的接口转换成可兼容的接口,使得原本不能一起工作的类可以协同工作。 在Java中,适配器模式一般有两种实现方式,即类适配器模式和对象适配器…...
深入理解this指向问题
this指向 在运行时绑定,所以this和函数的调用方式和调用的位置有关,和定义的位置没关系 绑定规则 默认绑定(非严格模式下this指向全局变量,在严格模式下函数内的this指向undefined) 独立函数调用,没有主题 …...
事业单位联考(综合应用A类)典型例题教案
【联考A类】根据材料2,请你概括C市B县旅游质监所投诉处理科小王在接待投诉时存在的主要问题,并指出问题的具体表现。(35分)要求:准确、全面、分条作答。字数在300字以内。材料2:某日,几位游客家…...
frp内网穿透实验
Frp (Fast Reverse Proxy) 是比较流行的一款。FRP 是一个免费开源的用于内网穿透的反向代理应用,它支持 TCP、UDP 协议, 也为 http 和 https 协议提供了额外的支持。你可以粗略理解它是一个中转站, 帮你实现 公网 ←→ FRP(服务器) ←→ 内网…...
认识JavaScript中的防抖函数
👨 作者简介:大家好,我是Taro,前端领域创作者 ✒️ 个人主页:唐璜Taro 🚀 支持我:点赞👍📝 评论 ⭐️收藏 文章目录前言一、防抖是什么?1. deounce-v1的基本…...
macOS 13.3 Beta 2 (22E5230e)With OpenCore 0.8.9正式版 and winPE双引导分区原版镜像
原文地址:http://www.imacosx.cn/112340.html,转载需注明出处镜像特点完全由黑果魏叔官方制作,针对各种机型进行默认配置,让黑苹果安装不再困难。系统镜像设置为双引导分区,全面去除clover引导分区(如有需要…...
JetPack—DataStore核心原理与使用
简介 首先,DataStore是Jetpack一部分,是一种数据存储解决方案。其次,DataStore使用协程及flow以异步、一致的方式实现数据的存储。最后是DataStore的实现,分为Preferences DataStore和Proto DataStore:Preferences Da…...
热烈祝贺|酒事有鲤盛装亮相2023中国(山东)精酿啤酒产业发展创新论坛暨展览会
酒事有鲤(济南)品牌管理有限公司是一家致力于将世界顶级精酿啤酒技术和理念与“ 在地”文化有机融合,做世界认 可的多元化好啤酒,通过精致 舒适的家门口酒馆,让啤酒的 世界观更为完整。 中国生物发酵产业协会联合齐鲁…...
深度强化学习DLR
1 强化学习基础知识 强化学习过程:⾸先环境(Env)会给智能体(Agent)⼀个状态(State),智能体接收到环境给的观测值之后会做出⼀个动作(Action),环境接收到智能体给的动作之后会做出⼀系列的反应,例如对这个动作给予⼀个奖励(Reward…...
Android Handler机制(四) Message源码分析
一. 简介 接上一篇文章:Android Handler机制(三) Looper源码分析 ,我们来继续分析一下Message源码 这一系列文章都是为了深入理解Handler机制. Message 作为消息传递的载体,源码主要分为以下 几个部分: 1. 操作数据相关,类似 getter()和 setter()这种…...
【Git】git命令(全)
Git1、本地操作2、版本管理3、远端仓库4、分支管理5、缓存stash6、遗留rebase7、标签管理8、解决冲突9、参考教程10、示例代码1、本地操作 Linux安装git:yum install git查看git版本 git version查看git设置 git config --list设置git属性 git config --global初始…...
软考论文-成本管理(1)
成本管理 1.成本管理的主要内容? 规划成本:制定一个成本管理的计划。估算成本:根据项目范围说明书,项目管理计划和wbs等文档,采用xxx方法进行估算成本成本预算:可以算工作包的费用,制定预算和…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...
基于PHP的连锁酒店管理系统
有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发,数据库mysql,前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...
零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程
STM32F1 本教程使用零知标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器,实现姿态解算,并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化,适合嵌入式及物联网开发者。在基础驱动上新增…...
深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏
一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...
