目录


什么是JDBC

JDBC 是一套规范,由许多接口组成,相当于提供了一套协议,大家要怎么怎么做;

JDBC 下层是各家数据的驱动;我们只需要调用 JDBC 提供的接口就好了,至于 JDBC 自己去调用具体的数据库驱动,都经历了什么,这一项不需要我们去关心 ;

需要使用到两个包:java.sql 、javax.sql ;

同时也需要导入具体的数据库驱动 ;(如 mysqloracle 的数据库驱动,这里我给出一个 mysql 的数据库驱动)


操作JDBC的步骤

第一步,加载驱动 ;

第二步:获取数据库连接;

第三步:获取statement对象,以便向数据库发送语句 ;

第四步:向数据库发送语句,并得到 结果集

第五步:从 结果集 中,获得数据 ;

第六步:关闭连接,释放资源 ;


DriverManager对象

JDBC 程序中的 DriverManager 用于加载驱动,并创建与数据库的链接;

这个 API 的常用方法

// 注册驱动
DrverManager regsterDriver(new Driver())
//获取连接
DriverManager getConnect on(url,user,password)

注意:

在实际开发中并不推荐采用 registerDriver 方法注册驱动。

原因有二:

  1. 查看 Driver 的源代码可看到,如果采用此种方式,会导致驱动程序注册两次,在內存中会有2个Driver象。

    public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    public Driver() throws SQLException {
    } static {
    try {
    // mysql 自己在实现驱动的时候,在加载类的时候,已经把自己注册进去了
    DriverManager.registerDriver(new Driver());
    } catch (SQLException var1) {
    throw new RuntimeException("Can't register driver!");
    }
    }
    }
  2. 程序 importmysql 的驱动。导致程序依赖于 mysqlapi; 脱离 mysqljar 包。

    程序将无法编译,将来程序切换底层数据库将会非常麻烦,要改动许多代码。

推荐方式:

      Class.forName("完整类名") ;

其实在查看了源代码以后, 我们就知道了,就应该这样来加载驱动,驱动类自己在实现的时候,就用了static代码块,让加载自己的时候,就注册自己,厂商也是为了解耦的考虑,才那么写的;

同样在导入 Connection 包的时候,不要带入具体的数据库的包,比如 java.mysql.connection ;

这样程序就牢牢的和mysql绑定在一起了 ;我们直接导入它的父类,java.sql ;这样,无论我们用什么数据库,它的驱动的 Connetion 都是要遵循 java.sql 包下面的 Connection 接口规范 ;

——————————–备注———————————

这个 DriveManger 类,就是服务提供者框架里面的,那个对外提供服务的类 ;

Java.sql.Driver 则是 JDBC 框架对外提供的服务者接口

Driver类 则是 mysql厂商 自己根据 Java.sql.Driver 接口实现的类,就是服务实现者


数据库URL

URL用于标识数据库的位置,程序员通过URL地址告诉JDBC程序连接哪个数据库;

URL的写法为:

jdbc : mysql: [] // localhost : 3306 / 项目名 ? 参数名:参数值

对应关系:

协议 : 子协议 // 主机: 端口 / 数据库

Mysqlurl 地址的简写形式: **jdbc : mysql: /// 数据库名字

**


Connection对象

JDBC 程序中的 Connection,它于代表数据库的链接;

Collection 是数据库编程中最重要的一个对象,客户端与数据库所有交互都是通过 Collection 对象完成的;

这个对象的常用方法:

  • createStatement()

    创建向数据库发送 sqIstatement 对象。

  • prepareStatement("sql语句")

    创建向数据库发送 预编译 sqIPrepareSatement 对象。

  • prepareCall(sql)

    创建执行存储过程的 CallableStatement 对 象。

  • setAutoCommit(boolean autoCommit)

    设置事务是否自动提交。

  • commit()

    在链接上提交事务。

  • rollback():

    在此链接上回滚事务。


Statement对象

Jdbc程序中的 Statement 对象用于向数据库发送 SQL 语句 ;

Statement 对象常用方法:

  • executeQuery(String sql)

    用于向数据发送查询语句。

  • executeUpdate(String sql)

    用于向数据浑发送 insert.update或delete 语句

  • execute(String sql)

    用于向数据库发送任意sq语句

  • addBatch(String sql)

    把多条sql语句放到一个批处理中。

  • executeBatch()

    向数据库发送一批 sql 语句执行。

虽然 execute(); 可以向数据库发送任意SQL语句,但是我们一般不用它,因为它的返回值是 boolean,需要我们去判断,然后再做处理;得不偿失;

executeUpdate(),返回的 int 值,代表影响表中的行数 ;


ResultSet对象

Jdbc 程序中的 ResultSet 用于代表 Sql语句 的执行结果。

ResultSet 封装执行结果时,采用的类似于表格的方式ResultSet 对象维护了一个指向表格数据行的游标,初始的时候,游标 在第一行之前;

调用 ResutSet.next()方法,可以使游标指向具体的数据行,进行调用方法获取该行的数据。跟集合的迭代器操作是一样的

ResultSet 既然用于封装执行结果,那么该对象提供的都是用于获取数据的 get 方法:


获取任意类型的数据

// 根据游标
getObject(int index)
// 根据字段名
getObject(String columnName)

获取指定类型的数据

// 根据游标
getString(int index)
getInt(int index)
getDate(int index)
... // 根据字段名
getString(String columnName)
getInt(String columnName)
getDate(String columnName)
...

其中 ResultSetgetDate() 方法,返回的是 sql 包下面的 date;但是由于sql.dateutil.date 的子类,因此前者可以直接赋值给后者 ;


常用数据类型转换表

SQL类型 JDBC对应的方法 返回类型
BIT(1) 、 bit(10) getBoolean() 、getBytes() Boolean、Byte[ ]
TINYINT getByte() Byte
SMALLINT getShort() Short
Int getInt() Int
BIGINT getLong() Long
CHAR、VARCHAR、LONGVARCHAR getString() String
Text(clob)、Blob getClob、getBlob() Clob、Blob
DATE getDate() java.sql.Date
TIME getTime() java.sql.Time
TIMESTAMP getTimestamp() java.sql.Timestamp

释放资源

Jdbc程序运行完后,切记要释放程序在运行过程中,创建的那些与数据库进行交互的对象,这些对象通常是 ResultSet,Statement和Connection 对象。、

特别是 Connection 对象,它是非常稀有的资源,用完后必须马上释放,如果Connection 不能及时、正确的关闭,极易导致系统宅机。

Connection的使用原则:尽量晚创建,尽最早的释放。

为确保资源释放代码能运行,资源释放代码也- 一定要放在finally语句中。


SQL注入

产生的原因:使用 Statement 对象,对 sql 语句不进行任何操作,直接查询;因而,我们可以拼接出一条 where 条件为永真的语句,这样,就可以取到用户;

预防 SQL注入,使用 PreparedStatement 对象 ,它会对sql语句,进行转义,只要发现接受的参数中有sql的符号,就进行转义。然后,再发送给数据库;这样就拼接不出来想要的 sql 语句了;


statementpreparedStatement 对象的区别

  1. preparedStatementStatement 的子类(说是实现类更贴切);
  2. preparedStatement 可以防止 sql注入 的问题 ;
  3. preparedStatement 是编写 sql 语句变得更容易,使用占位符;
  4. preparedStatement 是对 sql 语句进行 预编译 的,可以减轻数据库的压力 ;

关于 预编译 :

我们利用 Statement 发送给数据库的语句,数据库并不是拿到以后,就立马执行的;数据库要先编译以后,再执行; 这样当业务比较大的时候,向数据库发送的语句很多的时候,数据库对每一条语句都要进行编译,这样数据库很难受的,压力很大 ;

而我们使用 preparedStatement 对象,在写代码的时候,就对 sql 语句进行了预编译;这样数据库那边就不再需要进行编译操作,以减轻服务器的压力 ;


关于数据库中时间的问题;

我们需要进行一个 String ——> date 的转换 ;

因为,我们前台页面中接受到的数据,都是字符串,我们要将它们存进数据库的时候,需要将字符串转换成数据库的时间接受的格式 ;

转换代码:

//                如果是日期,则进行日期转换
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
return (T) dateFormat.parse(date);
} catch (ParseException e) {
// 打印日志,便于查找错误
e.printStackTrace();
// 发生转换异常了,则报错;
throw new RuntimeException(e);
}

转换完以后的是日期是 java.utils.date 类型的,我们数据库中的 datejava.sql.date 类型的;因此在存进去之前,还需要再转换一下 ;

//            存进去的时候,需要将 java.utils.date 转成 java.sql.date 类型
statement.setDate(4,new Date(user.getBirthday().getTime()));

从数据库获取时间的时候,是不需要进行转换的,因为 java.utils.datejava.sql.date 的父类。取出的 java.sql.date 类型可以直接赋值给 java.utils.date

//                这里取出的是 java.sql.date 但是由于它是 java.utils.date 因此不用进行转换
user.setBirthday(resultSet.getDate("birthday"));

(十四)JDBC入门的更多相关文章

  1. Spring学习记录(十四)---JDBC基本操作

    先看一些定义: 在Spring JDBC模块中,所有的类可以被分到四个单独的包:1.core即核心包,它包含了JDBC的核心功能.此包内有很多重要的类,包括:JdbcTemplate类.SimpleJ ...

  2. Jmeter(三十四) - 从入门到精通进阶篇 - 参数化(详解教程)

    1.简介 前边三十多篇文章主要介绍的是Jmeter的一些操作和基础知识,算是一些初级入门的知识点,从这一篇开始我们就来学习Jmeter比较高级的操作和深入的知识点了.今天这一篇主要是讲参数化,其实前边 ...

  3. 第四十四篇 入门机器学习——matplotlib基础——实现数据可视化

    No.1. 绘制一条正弦曲线 No.2. 在一张图中绘制多条曲线 No.3. 可以为曲线指定颜色.线条样式 No.4. 可以指定横纵坐标轴的范围 也可以使用: No.6. 可以为每条曲线添加图示 No ...

  4. Jmeter(十四) - 从入门到精通 - JMeter定时器 - 下篇(详解教程)

    1.简介 用户实际操作时,并非是连续点击,而是存在很多停顿的情况,例如:用户需要时间阅读文字内容.填表.或者查找正确的链接等.为了模拟用户实际情况,在性能测试中我们需要考虑思考时间.若不认真考虑思考时 ...

  5. Jmeter(二十四) - 从入门到精通 - JMeter函数 - 中篇(详解教程)

    1.简介 在性能测试中为了真实模拟用户请求,往往我们需要让提交的表单内容每次都发生变化,这个过程叫做参数化.JMeter配置元件与前置处理器都能帮助我们进行参数化,但是都有局限性,为了帮助我们能够更好 ...

  6. Jmeter(四十四) - 从入门到精通高级篇 - Jmeter远程启动(本地运行+远程运行)(详解教程)

    1.简介 这篇文章其实很简单,就是为下一篇文章做一个铺垫,所以宏哥给小伙伴或童鞋们提前热身一下. 2.什么是远程运行? 远程执行,就是脚本放在本地,执行却在另一台电脑上执行,当然,可以是远程多台电脑一 ...

  7. SpringBoot开发二十四-Redis入门以及Spring整合Redis

    需求介绍 安装 Redis,熟悉 Redis 的命令以及整合Redis,在Spring 中使用Redis. 代码实现 Redis 内置了 16 个库,索引是 0-15 ,默认选择第 0 个 Redis ...

  8. Jmeter(五十四) - 从入门到精通高级篇 - 如何在linux系统下运行jmeter脚本 - 上篇(详解教程)

    1.简介 上一篇宏哥已经介绍了如何在Linux系统中安装Jmeter,想必各位小伙伴都已经在Linux服务器或者虚拟机上已经实践并且都已经成功安装好了,那么今天宏哥就来介绍一下如何在Linux系统下运 ...

  9. 无废话ExtJs 入门教程十四[文本编辑器:Editor]

    无废话ExtJs 入门教程十四[文本编辑器:Editor] extjs技术交流,欢迎加群(201926085) ExtJs自带的编辑器没有图片上传的功能,大部分时候能够满足我们的需要. 但有时候这个功 ...

  10. Bootstrap入门(二十四)data属性

    Bootstrap入门(二十四)data属性 你可以仅仅通过 data 属性 API 就能使用所有的 Bootstrap 插件,无需写一行 JavaScript 代码.这是 Bootstrap 中的一 ...

随机推荐

  1. gradle的简单使用

    Gradle是一个基于JVM的构建工具,是一款通用灵活的构建工具,支持maven, Ivy仓库,支持传递性依赖管理,而不需要远程仓库或者是pom.xml和ivy.xml配置文件,基于Groovy,bu ...

  2. 解决一些python的问题记录

    1.python3中出现ModuleNotFoundError: No module named 'pkg_resources' wget https://bootstrap.pypa.io/ez_s ...

  3. Android 系统添加SELinux权限

    本文为博主原创文章,转载请注明出处:https://i.cnblogs.com/EditPosts.aspx?postid=11185476 CPU:RK3288 系统:Android 5.1 SEL ...

  4. 机器学习 - 算法示例 - Xgboost

    安装 能直接安装就再好不过 pip install xgboost 如果不能就下载之后本地安装 安装包下载地址 这里 想要啥包都有 数据集 pima-indians-diabetes.csv 文件 调 ...

  5. 数据库连接池Flask-SQLAlchemy中多线程安全的问题

    使用flask-sqlalchemy写代码码到一半,突然想到,Session是否是线程安全的?于是上官方文档,答案是否! 那问题来了,怎么破?因为它会牵涉到多线程情况下,调用rollback导致的不可 ...

  6. elasticsearch _search结果解析

    kibana中输入:GET /_search 会返回一下结果: { "took": 9, # took:整个搜索请求花费多少毫秒 "timed_out": fa ...

  7. QML最大化

    Component.onCompleted: { root.visibility = Window.Maximized} Component.onCompleted: { root.showMaxim ...

  8. 处理线上CPU负载过高的故障现象

    如何处理线上CPU100%的故障现象 处理流程: 1.登陆线上机器top命令,查看耗费cpu的进程号,举例来说发现进程24008持续耗费资源 2.top -Hp 24008去查看持续耗费cpu的线程号 ...

  9. 修改root密码

    Linux 密码的修改,使用passwd 命令修改 命令如下图:sudo passwd root 即可修改成功

  10. MySQL安装时出现Apply Security Settings错误的解决办法(转)

    最近在学习MySQL时,下载了MySQL5.5版本的安装包,在配置向导的最后的页面却出现了Apply Security Settings的错误.第一次安装时比较顺利,中途卸载了一下,结果第二次安装的时 ...