java 的JDBC操作

2023-10-27

JDBC(java数据库连接)提供了一套数据库操作标准,这些标准需要各个数据库厂商去实现并提供一个驱动程序,目前常见的4类JDBC驱动程序:

JDBC-ODBC 直接利用微软的ODBC进行数据库连接操作,性能低,一般不推荐
JDBC本地驱动 直接使用各个数据库厂商提供的驱动程序,只能在特定的数据库上,性能高,可移植性低
JDBC网络驱动 JDBC转换为与DBMS无关的网络协议,又被某个服务器转化为一种DBMS协议,这样可以连接到多个数据库,所用的具体协议取决于提供者,通常是最灵活的
本地协议纯JDBC 将JDBC调用直接转换为DBMS所使用的网络协议,这将允许用户从客户端直接调用DBMS服务器,是internet访问的一个实用的解决方法
数据类型 字节数
TINYINT 1
SMALLINT 2
MEDIUMINT 3
INT0 4
BIGINT 8
FLOAT 4
DOUBLE 8
DECIMAL(M,D) M+2 这里的M为数据的长度,D为小数点的位数
插入值 CHAR(3) 存储需求 VARCHAR(3) 存储需求
‘’ ‘’ 3个字节 ‘’ 1个字节
‘a’ ‘a’ 3个字节 ‘a’ 2个字节
‘ab’ ‘ab’ 3个字节 ‘ab’ 3个字节
‘abc’ ‘ab’ 3个字节 ‘abc’ 4个字节
‘abcd’ ‘ab’ 3个字节 ‘abc’ 4个字节

在MySQL中常用CHAR 和 VARCHAR 表示字符串。VARCHAR是可变长度的字符串。 当数据为CHAR(M)类型时,不管插入值的长度是实际是多少它所占用的存储空间都是M个字节;而VARCHAR(M)所对应的数据所占用的字节数为实际长度加1

文本类型用于表示大文本数据,例如,文章内容、评论、详情等:

TINYTEXT 1个字节*字节
TEXT 2个字节*字节
MEDIUMTEXT 3个字节*字节
LONGTEXT 4个字节*字节

时间与日期

数据类型 字节数 取值范围 日期格式 零值
YEAR 1 1901~2155 YYYY 0000
DATE 4 1000-01-01~9999-12-31 YYYY-MM-DD 0000-00-00
TIME 3 -838:59:59~ 838:59:59 HH:MM:SS 00:00:00
DATETIME 8 1000-01-01 00:00:00~9999-12-31 23:59:59 YYYY-MM-DD HH:MM:SS 0000-00-00 00:00:00
TIMESTAMP 4 1970-01-01 00:00:01~2038-01-19 03:14:07 YYYY-MM-DD HH:MM:SS 0000-00-00 00:00:00

YEAR类型用于表示年份,在MySQL中,可以使用以下格式指定YEAR类型 的值。

  1. 使用4位字符串或数字表示 2019或 ‘2019’ 都表示2019年,范围为1901—2155年
  2. 使用两位字符串表示 范围 ‘00’-‘99’ ,‘00’—'69’范围的值会被转换为 2000—2069范围的YEAR值,‘70’—'99’范围的值会被转换为1970—1999范围的YEAR 值。如果使用数字指定类似字符串指定,区别不能使用数子 00,00代表YEAR值是0000

TIME类型用于表示时间值可以使用以下格式指定TIME类型 的值

  1. 以’D HH:MM:SS’字符串格式表示。其中,D表示日可取0—34之间的值, 插人数据时,小时的值等于(DX24+HH)。例如,输入’2 11:30:50’插人数据库中的日期为59:30:50。
  2. 以’HHMMSS’字符串格式或者HHMMSS数字格式表示。 例如,输人’115454’或115454,插入数据库中的日期为11:54:54
  3. 使用CURRENT_TIME或NOW()输人当前系统时间。

DATETIME类型用于表示日期和时间值**可以使用以下格式指定

  1. 以’YY-MM-DD HH:MM:SS’或者’YYMMDDHHMMSS’字符串或数字格式表示的日期和时间
  2. 使用NOW来输人当前系统的日期和时间。

TIMESTAMP与DATETIME相同但取值范围比DATETIME小。这是3种不同的形式

  1. 使用CURRENT_TIMESTAMP输人系统当前日期和时间。
  2. 输人NULL时系统会输人系统当前日期和时间。
  3. 无任何输人时系统会输入系统当前日期和时间。

BLOB存储二进制类型的数据,例如:图片、PDF文档等。BLOB类型分为如下四种:

二进制类型 大小
TINYBLOB 1个字节*字节
BLOB 2个字节*字节
MEDIUMBLOB 3个字节*字节
LONGBLOB 4个字节*字节

数据库的基本操作

DDL 数据定义语言
DML 数据操作语言
DQL 数据查询语言
DCL 数据控制语言

mysql -u 用户名 -p 连接数据库 (我的用户名czdsb,密码123456) net start 服务器名字 :开启服务器 (我的服务器名字mysql80) net stop 服务器名字:关闭服务器
单行注释--或# 多行

这是DDL的指令,这里的[]都表示可选,输入时不用吧 [] 输进去,直接忽略就行

show databases 查询全部数据库
SELECT DATABASE() 查询当前数据库
CREATE [IF NOT EXISTS]数据库名[DEFAULT CHARSET 字符编码格式如UTF-8m4][COLLATE 排序规则] 创建数据库
DROP DATABASE [IF NOT EXISTS]数据库名 删除数据库
use 数据库名 切换数据库
show tables 查询当前数据库的表
desc 表名 查看表格内容
show create table 表格名 查看指定表的建表语句
create table 表名(
id int comment '注释',
变量名 变量类型 
);

注意:在 )前面不能有,字符类形为varchar(容量大小)

alter database 数据库名 character set gbk; 将数据库的字符集修改为gbk
alter table 表名 rename to 表名; 修改表名
alter table 表名 change name1 name2 变量类型; 将字段name1变为name2
alter table 表名 modify 字段名 字段类型; 修改字段数据类型
alter table 表名 add 字段名 字段类型; 增加字段
alter table 表名 drop 字段名; 删除字段
drop table 表名; 删除数据表

插入数据

INSERT INTO 表名 [(字段名1,字段名2,...)]VALUES (值 1,值 2,…),(值 1,值 2,…); 插入一条
INSERT INTO 表名 [(字段名1,字段名2,...)]VALUES (值 1,值 2,…),(值 1,值 2,…),...; 插入多条内容

select * from 表名 查询表里的内容

UPDATE基本语法

UPDATE 表名 SET 字段名1=值1[,字段名2 =值2,…] [WHERE 条件表达式]; 更新部分数据
update 表名 set 字段=值; 将所有该字段的值都一起设定
update student set age=20,gender='female' where name='tom';
//将name为tom的记录 的age设置为20并将其gender设置为female

DELETE删除数据

DELETE FROM 表名 [WHERE 条件表达式];

如果加where条件筛选就只删一部分,不加就删完

查询

select * from 表名; 查询所有字段
select 字段 或 常量 from 表名; 查询指定字段,如select id,name from student;只查询名字和id
select distinct 字段 from 表名; 从查询结果中过滤重复数据,如select distinct gender from student; 结果为 男和女。DISTINCT关键字只能用在第一个所查列名之前

在SELECT查询语句中还可以使用加减乘除运算符。

select sname,age+10 from student; 即查询10年后的age(输出为原先age+10)


在java中加载驱动程序

String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver"; 
String DB_URL = "jdbc:mysql://localhost:3306/你的mysql数据库名字?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC";
String user="你的mysql的用户名",pass="你的mysql的密码";
Class.forName(JDBC_DRIVER);
Connection conn = DriverManager.getConnection(DB_URL,user,pass);

在这里用到了Connection与Statement接口

Connection方法 作用
createStatement() 创建Statement对象
prepareStatement(String sql) 创建prepareStatement对象
Statement方法 作用
executeUpdate(String sql) 执行更新的操作,如insert,update,delete
executeQuery(String sql) 执行查询操作,返回一个结果 ResultSet 对象
addBatch(String sql) 增加一个待执行的sql语句
executeBatch(String sql) 批量执行sql语句
close() 关闭Statement
execute(String sql) 执行sql语句
ResultSet接口 作用
next() 将指针移向下一行
getInt(int index) 按列的index取得指定列的整数
getInt(String name) 按列的名字取得列的整数
getFloat(int index)与getFloat(String name) 同上
getString(int index)getString(String name) 同上
getDate(int index)getDate(String name) 同上

ResultSet是一个set集合,本质是指针来存储,要用next()来把指针移向下一个

getString()可以接受任意类型的内容

查询时尽量不要用select * from user 来查询 ,尽量要指定查询哪一列

PreparedStatement

因为Statement接口安全性较差,所以一般用PreparedStatement接口,且PreparedStatement已预编译,执行效率高,以下是比Statement多的方法,使用Connection的prepareStatement(String sql)来实例化

executeUpadte() 执行预编译的sql语句
executeQuery() 查询,返回ResultSet对象
setFloat(int 列号,float值) 设置值
setInt方法 同上
setString方法 同上
setDate方法 同上

PreparedStatement可以通过拼凑sql语句如:

String str="insert into jb (id,name,url) value(?,?,?)";
PreparedStatement statement=conn.prepareStatement(str);

实例化对象时传入一个 可拼凑的sql语句,用 ? 来当一个占位符

statement.setString(2, "沙立浩为什么这么骚");

这里就指定 将第 2个?替换为 "沙立浩为什么这么骚" 这个字符串

将全部的?替换后就可以 用executeUpadte()来执行你的sql语句了

在查询的时候将字符串 两端左右加 %,作为模糊查询


ALTER DATABASE 数据库 DEFAULT CHARACTER SET utf8 COLLATE utf8_bin 将指定数据库字符编码设置为utf-8
ALTER TABLE 表名 DEFAULT CHARACTER SET utf8 COLLATE utf8_bin 将指定表字符编码设置为utf-8
ALTER TABLE 表名 CHANGE 字段名 字段名 VARCHAR( 45 ) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL 将指定字段字符编码设置为utf-8

有时候向数据库里输入时会产生 字符编码不一致而报错的情况,所以要设置一下

处理大数据

使用CLOB和BLOB两种类型的字段,在CLOB中存储海量文件 。

mysql中提供了longtext等文本类型来存储大文本数据。

在使用PreparedStatement来对 text 类型输入时,可以这样:

statement.setAsciiStream(3, new FileInputStream(f), (int)f.length());

调用setAsciiStream(int index, input对象, int 文件大小);方法将 文件流中的文本输出到数据库中。

Class.forName("com.mysql.cj.jdbc.Driver");
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jk?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC","root","123456");
        System.out.print("已连接");
        PreparedStatement statement=conn.prepareStatement("select n from note where id like 2");
        ResultSet rSet=statement.executeQuery();
        rSet.next();
            Scanner s=new Scanner(rSet.getAsciiStream(1));
            while (s.hasNext())
            {
                System.out.println(s.next());
            }

这里是先用rSet中 的next()把指针移向我们要读的数据

然后 rSet.getAsciiStream(1) 得到 要读的数据的 输入流,然后交给Scanner来处理文本


CallableStatement接口

该接口主要调用数据库中的储存过程,可以接收过程的返回值

那么mysql的储存过程又是啥呢?

set @a=10;  --这相当于定义了叫 a 的一个值为10 的用户变量
select @a;  --将这个用户变量输出   --用户变量一定要在前面加 @
create procedure 过程名 (各种参数....)

储存过程有三种类型声明

  1. IN 只会读进来,在过程里操作该变量,在过程结束后也不会影响变量
  2. INOUT 把值传进来,在过程中的修改会被保留
  3. OUT 过程中对此值的操作会被保留

注意:在建立 储存过程之前 要修改分隔符 (即 delimiter 分隔符 指令)

getInt(int 编号),getFloat(int 编号) 根据编号来取出返回值
setInt(int 编号)setFloat(int 编号) 设置指定编号的内容
registerParameter(int 编号,int Types.类型) 设置返回值的类型

Call 通过Connection类的prepareCall()方法来实列化

主要就是处理 sql的存储过程


可以滚动的结果集

在之前讲的ResultSet中只能从前往后输出,那要输出可以滚动的结果集,可以这样:

prepareStatement(String sql,int ResultSet.TYPE_SCROLL_SENSITIVE,
int ResultSet.CONCUR_READ_ONLY) 
//通过这个方法来得到一个 可滚动的PrepareStatement对象

其中ResultSet.TYPE_SCROLL_SENSITIVE与ResultSet.CONCUR_READ_ONLY都是

ResultSet中的int常量。

ResultSet中的常量 描述
TYPE_FORWARD_ONLY 表示指针只能向后滚动(默认值)
TYPE_SCROLL_SENSITIVE 表示指针可以滚动,可以更新内容
TYPE_SCROLL_INSENSITIVE 表示指针可以滚动,不可以更新内容
CONCUR_READ_ONLY 用只读的方式打开数据库
CONCUR_UPDATABLE 表示ResultSet可以更新
ResultSet中的方法补充 描述
absolute(int index) 将结果集移向指定行
previous() 将结果向前移动
afterLast() 将结果集移到末尾之后
beforeFirst() 将结果集移到首行之前
first() 将结果集移到第一行
last() 将结果集移到最后一行
updateString(int 列号,String x) 更新指定列的内容,改方法被重载多次
updateString(String 列名,String x) 更新指定列的内容,改方法被重载多次
moveToInsertRow() 将指针移到 插入行
cancelRow() 取消更新数据,在updateRow()调用之前有效
insertRow() 插入行数据
deleteRow() 删除行数据

使用结果集插入数据

  1. 在创建PrepareStatement对象是必须指定结果集可以更新数据
  2. prepareStatement(String sql,int ResultSet.TYPE_SCROLL_SENSITIVE,
    int ResultSet.CONCUR_UPDATABLE) 
    
  3. 设置可更新后,调用ResultSet的moveToInsertRow()将指针移向可插入的列
  4. 调用ResultSet 的Update***()之类的方法
  5. 最后使用insertRow()完成更新

使用结果集更新数据

在修改数据的时候要把指针指向要修改的行,所以用查询的sql语句

再用last(),再调用ResultSet 的Update***()之类的方法

最后调用updateRow()来完成修改

注意:在执行updateRow()方法之前,如果发现更新的数据有错误,可以使用

使用结果集删除数据

执行 ResultSet 的deleteRow()删除一行

批处理

使用批处理可以一次性插入多条sql语句,

PreparedStatement statement=conn.prepareStatement("insert into  jb(id,name,countriy,day) values(?,?,?,?)");
        for(int i=3;i<6;i++)
        {
            statement.setString(1, i+"");
            statement.setString(2,"沙立浩被干的次数"+i);
            statement.setString(3,"保加利亚"+i);
            statement.setDate(4, new Date(new java.util.Date().getTime()));
            statement.addBatch();
        }
        statement.executeBatch();

使用PreparedStatement对象的addBatch()加入批处理等待,

最后用executeBatch()执行批处理


事务处理

所谓的十五就是所有操作要么一起成功,要么都失败,事务本身具有原子性,一致性,隔离性(独立性),持久性

mysql对事物的支持 描述
set autocommit=0 取消自动提交,开启事务处理
set autocommit=1 开启自动提交,关闭事务处理
start transaction 启动事务
begin 启动事务,相当于start transaction
commit 提交事务
rollback 回滚
savepoint 事务保存点的名称 设置回滚点
rollback to savepoint 保存点名称 回滚到指定保存点

应用事件处理:

  1. 设置set autocommit=0
  2. 开启事务start transaction或begin
  3. 编写更新语句之类的
  4. 提交事务commit

在java中怎么实现这些步骤呢?

  1. 取消Connection中设置的自动提交方式 setAutoCommit(false)
  2. 如果批处理的时候操作成功就可以 Connection对象.commit()提交事务
  3. 有异常可以回滚** Connection对象.rollback()**,可以指定要回滚的保存点
  4. 可以设置savepoint,"SavePoint 检查点名字=Connection对象.setSavePoint()"

使用元数据分析数据库

DatabaseMetaData类可由Connection的getMetaDta()方法实例化

getDatabaseProductName() 得到数据库的名称
getDriverMajorVersion() 得到数据库的主版本号
getDriverMinorVersion() 得到数据库的次版本号
getPrimaryKeys(String,String,String) 得到表主键信息,1.表类别,2.表模式3.表名称4.列名称5.主键中的序列号,6.主键的名称。返回ResultSet对象
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jk?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC","root","123456");
System.out.print("已连接");
DatabaseMetaData dm=conn.getMetaData();//通过getMetaData()方法实例化

ResultSetMetaData

getColumnCount() 返回查询结果中的列数
isAutoIncrement(int 列号) 判断指定列是否是自动编号
getColumnName(int 列号) 返回列的名称
var statement=conn.prepareStatement("select * from jb");
        ResultSetMetaData rsmd=statement.getMetaData();

实例化方法

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java 的JDBC操作 的相关文章

随机推荐

  • java缓存面试问题_分布式缓存的面试题5

    1 面试题 如何保证Redis的高并发和高可用 redis的主从复制原理能介绍一下么 redis的哨兵原理能介绍一下么 2 面试官心里分析 其实问这个问题 主要是考考你 redis单机能承载多高并发 如果单机扛不住如何扩容抗更多的并发 re
  • R语言数据输入

    一 使用键盘输入数据 在导入数据比较少的时候 我们使用这种方法 R中的函数 edit 会自动调用一个允许手动输入数据的文本编辑器 具体步骤如下 1 创建一个空数据框 或矩阵 其中变量名和变量的模式需与理想中的最终数据集一致 2 针对这个数据
  • java使用aspose将word,excel,ppt转pdf

    1 测试环境springboot jdk1 8 aspose cells 8 5 2 jar 用于转换xls aspose words 16 8 0 jdk16 jar 用于转换doc 2 所用jar 签名百度网盘地址 链接 https p
  • Pytorch加载自己的数据集(以图片格式的Mnist数据集为例)

    文章目录 Pytorch加载自己的数据集 以图片格式的Mnist数据集为例 前言 一 数据集转换 二 构建自己的数据集 1 引入库 2 构建MnistDataset类 3 搭建网络模型 三 完整代码 总结 Pytorch加载自己的数据集 以
  • 【最新更新】2020研究生华为杯数学建模比赛题目+题目分析【持续更新】

    各参赛队伍 为了保证2020年 华为杯 第十七届中国研究生数学建模竞赛顺利举行 现将竞赛开赛的相关事项通知如下 一 时间节点 1 加密题目开始下载时间 2020年9月16日8 00 截止时间 2020年9月20日17 00 2 题目解密密码
  • 强化学习 OpenAI Gym Universe Docker在Windows WSL 2安装配置最全的全记录

    1 事情的起源 全记录事情的起源是为了学习Python强化学习实战 先在自己的windows操作系统的Pycharm Anaconda Gym配置下运行成功了CartPole示例和CarRacing示例 接着运行Universe 据说Ope
  • JVM 与 GC 讲解

    文章目录 一 概述 二 JVM 内存模型 三 GC算法和回收器 1 垃圾回收算法 2 垃圾回收器 四 垃圾回收机制 GC 1 分代垃圾回收机制 2 G1 垃圾回收器 3 FullGC 机制 一 概述 JVM Java Virtual Mac
  • Retrofit2+Rxjava2+Rxandroid+okhttp3+Lifecycle 的MVP网络框架,精简Google官方AAC框架,实现APP生命周期的管理

    一 介绍 目前使用较为广泛的网络请求框架 MVP Retrofit2 okhttp3 Rxjava2 我于2017年也加入了使用行列 在网上找了许多案例 实际项目开发中解决了一些所谓的坑 总结了些内容与大家共享一下 1 什么是MVP 在图中
  • 优惠价,百分比计算,折扣计算,打折计算

    一 优惠价 百分比计算 例如 原价是100元 优惠5 5 5 100 0 05 优惠价 100x5 100x0 05 5 计算得出优惠价是5元 优惠后的价格 原价 优惠价 95 100 5 计算得出优惠后的价格是95元 例如 原价是100元
  • 理解DDoS防护本质:基于资源较量和规则过滤的智能化系统

    本文由 网易云 发布 随着互联网生态逐渐形成 DDoS防护已经成为互联网企业的刚需要求 网易云安全 易盾 工程师根据DDoS的方方面面 全面总结DDoS的攻防对抗 1 什么是DDoS DDoS全称Distributed Denial of
  • steam deck科普、上手教程及模拟器配置指南

    steam deck 前言 早在2021年得时候 坊间就开始流传steam deck这个东西要问世了 但是中途跳了几次票 直到2022年2月 第一批steam deck才正式面向大众玩家 在熟悉steam deck之前 我们有必要了解如下的
  • VS2019 + libcurl5.7.0 + openssl3.0.5 简易编译教程

    VS2019 libcurl5 7 0 openssl编译配置 1 用途 工作用到C 对求高德地图发送https请求 进行逆地址分析 2 文件包下载 2 1 window的openssl3 0 5EXE安装包 链接 exe安装包 2 2 下
  • numpy求平均值

    本文转自链接 https www cnblogs com yibeimingyue p 11413295 html 1 对数组求平均值 import numpy as np a np array 1 2 3 4 print a print
  • C语言问题汇总

    C语言问题汇总 排序方法 冒泡排序 降序排序 作业 从文件中读取内容 字符写入文件 结构体数组 以二进制形式写入文件并读取 将字符串写入文件 并从文件中读取 查找字符在字符串中的位置 字符串链接 不使用strcpy函数 使用strcpy函数
  • 俄罗斯方块C++代码(转载他人代码)

    include
  • (ctf)攻防世界web模块020web2

    题目 首先来到给定的地址 题意很明确 miwen是加密之后的字符串 我们只需要逆向解密出miwen就能得到flag 我们先来代码审计 o strrev str strrev 函数是字符串的倒置 for 0 0 0
  • java.io.IOException: Connection reset by peer问题解决

    java io IOException Connection reset by peer问题解决 今天检查日志 发现 ClientAbortException java io IOException Connection reset by
  • font-spider(字蛛)的正确打开方式

    前言 最近在部署vue项目之后 在打开网页的时候 ttf文件下载时间实在是太久了 在经过合理的运用搜索引擎之后 可能自己的固化思维消化不了大佬们给出的方案 于是在他们的基础之上做了一些小小的改动 便叙文记之 1 引入font spider的
  • BigDecimal 前端丢失精度的问题解决

    问题描述 后端数字是85 00 但是前端显示85 SQL语句 select cast 字段 as decimal 10 2 value 这里已经保留两位小数了 from table where 实体类 这里是关键 注意不是 JSONFiel
  • java 的JDBC操作

    JDBC java数据库连接 提供了一套数据库操作标准 这些标准需要各个数据库厂商去实现并提供一个驱动程序 目前常见的4类JDBC驱动程序 JDBC ODBC 直接利用微软的ODBC进行数据库连接操作 性能低 一般不推荐 JDBC本地驱动