示意图
目录
创建 JDBC 应用
例子:通过本地协议纯 Java 驱动程序实现JDBC
代码具体步骤:
1.注册驱动
2.建立与数据库的连接
3.获取执行SQL语句的对象 Statement
4.定义执行 SQL 语句
5.操作结果集对象 ResultSet
6.关闭操作对象及连接对象
JDBC的主要类及常用方法
1.Class 类
2.DriverManager 类
3.Connection 类
4.Statement 类
5.ResultSet 类
SQL 注入问题
PreparedStatement 接口
JDBC连接不同的数据库
JDBC 核心类和库(java.sql)的主要类:
- DriverMananer.:负责管理 JDBC 驱动程序,在使用JDBC驱动程序之前,必须先将驱动程序加载并注册后才可以使用,同时提供方法来建立与数据库的连接。
- SQLException:有关数据库操作的异常。
而其主要接口如下:
- Connection:特定数据库的连接(会话)。在连接上下文中执行SQL语句并返回结果。
- PreparedStatement:表示预编译的SQL语句的对象。
- Statement:用于执行静态SQL语句并返回它所生成结果的对象。
- ResultSet:表示数据库结果集的数据表,通常通过执行查询数据库的语句生成。
- CallableStatement:用于执行SQL存储过程的接口。
创建 JDBC 应用程序
1.载入JDBC 驱动程序
首先要在应用程序中加载驱动程序 driver,使用 Class.forName() 方法加载特定的驱动程序,每种数据库管理系统的驱动程序不同,它们由数据库厂商提供。
2.定义连接URL
3.建立数据库连接
通过 DriverManager 类的 getConnection() 方法获得表示数据库连接的 Connection 类对象。4.创建 Statement对象
获取 Connection对象以后,可以用Connection对象的方法创建一个 Statement对象的实例。5.执行查询或更新
Statement对象可以执行 SELECT 语句的 executeQuery() 方法,可以执行 INSERT、UPDATE、DELETE 语句的 executeUpdate() 方法。
6.结果处理
利用语句对象对数据库操作返回的结果进行处理,ResultSet 包含一些用来从结果集中获取数据并保存到 Java 变量中的方法,主要包括 next() 方法:用于移动结果集游标;逐行处理结果集 getString()、getInt()、getDate()、getDouble() 等方法,用于将数据库中的数据类型转换为Java语言的数据类型。
7.关闭使用完的对象
使用与数据库相关的对象非常耗内存,因此,在数据库访问后要关闭与数据库的连接,同时还应该关闭ResultSet、 Statement和 Connection 等对象。可以使用每个对象自己的close()方法完成。
例子:通过本地协议纯 Java 驱动程序实现JDBC
以MySQL为例,我们先下载一个MySQL数据库驱动jar包。
前提:创建一个Java项目,在项目中创建一个名为libs的目录(为了方便管理,就把jar包文件放入此目录下),然后在src下建一个包,包下再建一个类,比如:
(注意!之后选择libs右键——>Add as Library,以导入识别jar包)
代码具体步骤:
- 导入jar包(package)
- 注册驱动
- 获取数据库的连接对象
- 获取执行SQL语句的对象
- 定义、执行SQL语句并接收返回结果
- 处理结果
- 释放资源
以 MySQL 为例来说明 JDBC 的步骤:
1.注册驱动
Class类提供的加载驱动程序的方法:
public static Class forName(String className) throws ClassNotFoundException
(加载驱动程序时会抛出 ClassNotFoundException 的 SQLException 异常)
例如加载 MySQL 驱动程序的语句描述:
Class.forName("com.mysql.jdbc.Driver");
2.建立与数据库的连接
DriverManager 类提供了 getConnection() 方法用于获取指定数据库的连接对象:
public static Connection getConnection (String url, String userName, String password) throws SQLException
MySQL 数据库的 url 格式为:
jdbc:mysql://[host1:port1],[host2:port2].../[database][?参数名1][=参数值1][&参数名2][=参数值2]...
例子:定义本地默认连接 url
1.
String url = " jdbc:mysql://localhost:3306/eshop?useUnicode=true&characterEncoding=UTF-8";
2.
String url2 = "jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&userSSL=false&serverTimezone=GMT%2B8";
拿到数据库的连接:
Connection conn = DriverManager.getConnection(url,"root","password")
3.获取执行SQL语句的对象 Statement
Connection 接口中提供了获取 Statement 对象的方法:
Statement createStatement() throws SQLException
通过调用重载的 createStatement() 方法指定参数,设置数据库操作结果的相关属性。比如获取 Statement 对象(用来执行 SQL 语句,并接收返回结果)
Statement stmt = conn.createStatement();
4.定义执行 SQL 语句
需通过可以发送 SQL 命令的 Statement 对象 st。比如调用对象 st 的 executeQuery() 方法发送 SQL 查询命令。查询的主要方法如下:
1.
boolean execute(String sql) throws SQLException
2.
ResultSet executeQuery(String sql) throws SQLException
3.
int executeUpdate(String sql) throws SQLException
5.操作结果集对象 ResultSet
ResultSet 接口提供可对结果集进行操作的主要方法如下:
1.
boolean next() throws SQLException
//移动结果集操作指针
2.
XXX getXXX(String columnName) throws SQLException
//指定数据类型,根据传入列的名字获取指定列的值
3.
XXX getXXX(1) throws SQLException
//指定数据类型,根据传入列的编号获取指定列的值
SQL 类型 | Java 类型 |
---|---|
CHAR | String |
VARCHAR | String |
LONGVARCHAR | String |
NUMERIC | java.math.BigDecimal |
DECIMAL | java.math.BigDecimal |
BIT | boolean |
TINYINT | byte |
SMALLINT | short |
INTEGER | int |
BIGINT | long |
REAL | flout |
FLOAT | double |
DOUBLE | double |
BINARY | byte[] |
VARBINARY | byte[] |
LONGVARBINARY | byte[] |
DATE | java.sql.Date |
TIME | java.sql.Time |
TIMESTAMP | java.sql.Timestamp |
6.关闭操作对象及连接对象
数据库操作完成后,就可调用接口 ResultSet、Statement、Connection 中的关闭方法了,立即释放数据库和JDBC相关资源。如下所示:
void close() throws SQLException
关闭顺序如下:
- 关闭 ResultSet 对象
- 关闭 Statement 对象
- 关闭 Connection 对象
JDBC的主要类及常用方法
JDBC 的一系列步骤都由 JDBC API 中一组类的方法实现,如下:
1.Class 类
java.lang.Class,Java程序运行时会自动创建程序中的每个类的Class对象,通过Class类的方法可以得到程序中每个类的信息。
格式 | 效能 | 补充/例子 |
---|---|---|
public static Class forName(String className) | 根据“限定全类名”来获取相应的Class对象 | Class.forName(sun.jdbc.odbc.JdbcOdbcDriver)加载指定名称(JDBC-ODBC桥)的驱动程序 |
public String getName() | 根据对象,返回类名 | 不怎么常用 |
2.DriverManager 类
DriverManager(驱动程序管理器)类维护着用户程序与数据库驱动程序之间的连接。它实现了驱动程序的装载、创建连接数据库系统的 Connection 类对象。
格式 | 效能 | 补充 |
---|---|---|
public static Connection getConnection(String url, String user, String password) | 根据url(数据库JDBC-ODBC桥名称)、数据库用户名、密码获取一个数据库的连接对象 | 静态成员方法 |
3.Connection 类
Connection 连接类用于管理指定数据库的连接。
格式 | 效能 |
---|---|
createStatement() | 创建 Statement 类的实例 |
prepareSatement() | 创建 PreparedStatement 类的实例 |
close() | 关闭 Connection 对象 |
4.Statement 类
Statement 数据库操作类提供执行数据库操作的方法,如更新、查询数据库记录等。例子如下:
Statement stmt = conn.createStatement();
重要的成员方法如下:
格式 | 效能 |
---|---|
ResultSet executeQuery(String sql) | 用来执行查询语句,并返回一个ResultSet对象 |
int executeUpdate(String sql) | 用来执行“增删改”语句,返回值代表影响的行数 |
boolean execute(String sql) | 用来执行任意语句,返回代表是否返回了ResultSet |
close() | 关闭 Statement 对象 |
5.ResultSet 类
ResultSet 结果集类提供对查询结果集进行处理的方法,如:
ResultSet rs = stmt.executeQuery("select * from users");
ResultSet 对象维持着一个指向表格的行的指针,开始运行时指向表格的起始位置(第一行之前:0行)
格式 | 效能 |
---|---|
next() | 光标(指针)移到下一条记录,返回一个boolean值 |
privious() | 光标(指针)移到上一条记录 |
getXXX("字段名")或 getXXX(int i)等 | 获取指定类型的字段值。 |
close() | 关闭 ResultSet 对象 |
方法 | Java返回类型 |
---|---|
getASCIIStream | java.io.InputStream |
getBigDecimal | java.math.BigDecimal |
getBinaryStream | java.io.InputStream |
getBoolean | boolean |
getByte | byte |
getBytes | byte[] |
getDate | java.sql.Date |
getDouble | double |
getFloat | float |
getInt | int |
getLong | long |
getObject | Object |
getShort | short |
getString | java.lang.String |
getTime | java.sql.Time |
getTimestamp | java.sql.Timestamp |
getUnicodeStream | java.io.InputStream of Unicode characters |
SQL 注入问题
在使用 Statement 对象查询数据库时,由于定义的 SQL 语句是拼接的,就有可能出现 SQL 注入问题。所谓SQL注入就是把SQL命令插入查询字符串中,最终达到欺骗服务器执行恶意的SQL命令的目的。
PreparedStatement 接口
此接口表示预编译的 SQL 语句的对象,是为了解决 Statement 静态拼接所产生的 SQL 注入问题。PreparedStatement 接口是 Statement 接口的子接口,其允许使用不同的参数多次执行相同的SQL语句。
Connection 接口提供创建 PreparedStatement 接口对象的方法,可指定SQL语句
PreparedStatement preparedStatement(String sql) throws SQLException
虽然 PreparedStatement 接口继承了 Statement 接口,但 PreparedStatement 语句中包含了警告预编译的 SQL 语句,因此其效率更高。
PreparedStatement | Statement | |
---|---|---|
能写啥? | 带参数的SQL语句 | 简单的SQL语句 |
比较 | 可动态设置参数、增加了预编译功能、提高了执行速度 | - |
而且 PreparedStatement 的语句可以包含多个用“?”代替的字段,设置时按要素出现顺序传参即可。如:
Connection conn = DBUtil.getConnection();
PreparedStatement ps = null;
ResultSet rs = null;
String sql = "SELECT * FROM users WHERE NAME=? AND PWD=?";
ps = conn.preparedStatement(sql);
ps.setString(1, name);
ps.setString(2, pwd);
rs = ps.executeQuery();
格式 | 效能 |
---|---|
ResultSet executeQuery() | 执行SQL查询并获取ResultSet对象 |
int executeUpdate() | 执行“增删改”操作,返回值是执行该操作所影响的行数 |
boolean execute() | 执行任意语句,返回代表是否返回了ResultSet |
方法 | SQL类型 |
---|---|
setASClIStream | 产生一个 LONGVARCHAR 型的 ASCII 流 |
setBigDecimal | NUMERIC |
setBinaryStream | LONGVARBINARY |
setBoolean | BIT |
setByte | TINYINT |
setBytes | VARBINARY 或 LONGVARBINARY (大小取决于对 VARBINARY 的限制) |
setDate | DATE |
setDouble | DOUBLE |
setFloat | FLOAT |
setInt | INTEGER |
setLong | BIGINT |
setNull | NULL |
setObject | 在发送之前,转换为目标 SQL 类型的给定对象 |
setShort | SMALLINT |
setString | VARCHAR 或LONGVARCHAR (大小取决于驱动程序对 VARCHAR 的限制) |
setTime | TIME |
setTimestamp | TIMESTAMP |
JDBC连接不同的数据库
JDBC 是一套数据库连接的标准,许多数据库连接的区别如下:
- 数据库驱动路径名不同
- 连接数据库的 url 不同
数据库连接池(连接对象的集合)
数据库连接池的特点:
- 是个容器,负责分配、管理数据库连接
- 允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个连接
- 释放空闲时间超过最大空闲时间的数据库连接,来避免因为没有释放数据库连接而引起的数据库连接遗漏
总结:(我觉得有点像 DHCP 服务器)
- 资源重用
- 提升系统响应速度
- 避免数据库连接遗漏
数据库连接池实现
标准接口:DateSource(而不是以往的 JavaManager)
- 官方(Sun)提供的数据库连接池标准接口,由第三方组织实现此接口
- 其功能就是获取连接
常见的数据库连接池:DBCP、C3P0、Druid
我们以Druid(德鲁伊)为例,其是阿里巴巴开源的数据库连接池项目(功能强大、性能优秀)。
注意SQL命令、参数设置、处理结果!
略,有点事以后补充!
DBUtils我觉得还算是一个挺好用组件,在学习Hibernate,Mybatis这些ORM框架之前,可以学着用用。可以极大简化我们的JDBC的代码,用起来也很方便。