[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方法进行估算成本成本预算:可以算工作包的费用,制定预算和…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...

【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...

LLMs 系列实操科普(1)
写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...

Python 实现 Web 静态服务器(HTTP 协议)
目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1)下载安装包2)配置环境变量3)安装镜像4)node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1)使用 http-server2)详解 …...
LOOI机器人的技术实现解析:从手势识别到边缘检测
LOOI机器人作为一款创新的AI硬件产品,通过将智能手机转变为具有情感交互能力的桌面机器人,展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家,我将全面解析LOOI的技术实现架构,特别是其手势识别、物体识别和环境…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!
本文介绍了一种名为AnomalyAny的创新框架,该方法利用Stable Diffusion的强大生成能力,仅需单个正常样本和文本描述,即可生成逼真且多样化的异常样本,有效解决了视觉异常检测中异常样本稀缺的难题,为工业质检、医疗影像…...