本文是学习JavaEE开发的记录笔记
大纲
JDBC安装
- 进入官方网站选择平台独立版下载
- 下载后解压缩可以看到.jar包mysql-connector-java-5.1.46-bin.jar,将其放在JDK目录下的lib目录下
- 配置classpath
至此就完成了mysql数据库的JDBC包的安装,在所有java文件中都可以通过import java.sql.*导入mysql的JDBC包了
JDBC简单演示
JDBC进行数据库操作主要有六步:
- 1.导入包:import java.sql.*;
- 2.注册JDBC驱动程序:Class.forName(DriverName);
- 3.创建数据库连接:Connection conn=DriverManager.getConnection(DB_URL,USER,PASS);
- 4.执行数据库语句操作 :Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery(sql);
- 5.从结果集提取数据:rs.getType(valueName);
- 6.关闭连接:ResultSet/Statement/Connection.close();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70//1.导入包
import java.sql.*;
public class sqlTest {
//一些静态数据
//JDBC驱动类型 以下为mysql驱动
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
//JDBC驱动类型对应的数据库URL 以下为mysqlURL格式jdbc:mysql://hostname/databaseName
static final String DB_URL = "jdbc:mysql://localhost/mt?useUnicode=true&characterEncoding=utf-8&useSSL=false";
//数据库账号密码
static final String USER = "root";
static final String PASS = "";
public static void main(String[] args) {
//数据库连接实例
Connection conn = null;
//执行语句实例
Statement stmt = null;
try{
//2.注册JDBC驱动程序
Class.forName("com.mysql.jdbc.Driver");
//3.创建一个数据库物理连接Connection
conn = DriverManager.getConnection(DB_URL,USER,PASS);
//4.执行数据库语句操作Statement
stmt = conn.createStatement();
//读操作使用stmt.executeQuery()执行
String sql;
sql = "SELECT id,sid,name,description FROM mt_product";
ResultSet rs = stmt.executeQuery(sql);
//写操作使用stmt.executeUpdate()执行 如UPDATE/INSERT/DELETE
//5.从结果集提取数据
while(rs.next()){
int id = rs.getInt("id");
int sid = rs.getInt("sid");
String name = rs.getString("name");
String description = rs.getString("description");
}
//6.依次关闭数据库连接
rs.close();
stmt.close();
conn.close();
}catch(SQLException se){
//处理JDBC操作数据库出错
se.printStackTrace();
}catch(Exception e){
//处理Class.forName即JDBC驱动程序出错
e.printStackTrace();
}finally{
//使用finally关闭数据库连接
try{
if(stmt!=null) stmt.close();
}catch(SQLException se2){
//不做任何事情
}
try{
if(conn!=null) conn.close();
}catch(SQLException se){
se.printStackTrace();
}
}
}
}
JDBC架构与组件
JDBC体系架构由两层组成:
- JDBC API:连接应用程序(Java Application)到JDBC驱动管理器(JDBC Driver Manager)
- JDBC 驱动程序API:连接JDBC驱动管理器(JDBC Driver Manager)到驱动程序(JDBC Driver)
JDBC驱动管理器:确保程序使用正确驱动访问数据源,支持连接到多个异构数据库的多个并发驱动程序
JDBC API提供的接口和类:
- DriverManager:管理数据库驱动程序列表,使用其DriverManager.getConnection();方法建立数据库连接
- Driver:处理与数据库服务器的通信,我们很少直接与Driver交互,而是通过DriverManager管理Driver
- Connection:与数据库所有通信方法的联系来源,如Connection.createStatement()创建语句对象
- Statement:语句对象,用于将SQL语句提交到数据库,如Statement.executeQuery(读语句)/Statement.executeUpdate(写语句)
- ResultSet:数据库返回的查询结果集
- SQLException:数据库应用程序中发生的任何错误
JDBC驱动类型
JDBC驱动程序:JDK附带的java.sql中包含各种类的定义,JDBC驱动程序则实现其中的java.sql.Driver接口使得Java应用可以与数据库服务器进行交互
JDBC驱动程序类型:Sun公司根据其架构可分为四类
- JDBC-ODBC桥驱动程序
- JDBC本地API
- JDBC-Net纯Java
- 100%纯Java
100%纯Java驱动类型:MySQL Connector/J使用,基于纯Java的驱动程序通过套接字连接与供应商的数据库直接通信,是数据库最高性能的驱动程序,不需要在客户端或服务器安装特殊软件
注册JDBC驱动程序
注册驱动程序是使JVM将Oracle驱动程序的类文件加载到内存中的过程,因此可以将其用作JDBC接口的实现,只需在程序中注册一次就可以
注册驱动程序方法:
- Class.forName():将驱动程序的类文件动态加载到内存中,并将其自动注册
1
2
3
4
5
6
7try {
Class.forName("com.mysql.jdbc.Driver");
}
catch(ClassNotFoundException ex) {
System.out.println("Error: unable to load driver class!");
System.exit(1);
} - DriverManager.registerDriver():
1
2
3
4
5
6
7
8try {
Driver myDriver = new com.mysql.jdbc.Driver();
DriverManager.registerDriver( myDriver );
}
catch(ClassNotFoundException ex) {
System.out.println("Error: unable to load driver class!");
System.exit(1);
}
Connection对象:数据库URL配置
注册驱动程序后,使用DriverManager.getConnection()根据对应驱动程序的数据库URL建立连接获取Connectiond对象
JDBC驱动程序与对应数据库URL:
常用的getConnection()构造方法:使用数据库URL+数据库账号+数据库密码1
2
3
4String URL = "jdbc:mysql://hostname/databaseName";
String USER = "username";
String PASS = "password"
Connection conn = DriverManager.getConnection(URL, USER, PASS);
数据库交互
数据库连接后进行数据库交互的对象有
Statement对象:通过Statement stmt=Connection.createStatement()获得,对象方法有
PreparedStatement对象:通过在SQL语句中使用占位符,使用SetXXX()方法绑定参数1
2
3
4
5
6
7
8
9Connection conn = DriverManager.getConnection(DB_URL,USER,PASS);
//SQL语句中使用占位符
String sql = "UPDATE Employees set age=? WHERE id=?";
PreparedStatement pstmt = conn.prepareStatement(sql);
//设置占位符值
stmt.setInt(1, 35);
stmt.setInt(2, 102);
//执行语句
int rows = stmt.executeUpdate();
CallableStatement对象:比PreparedStatement对象更强大的是不仅提供了SetXXX()方法绑定输入参数,还提供getXXX()绑定SQL语句返回的参数值
ResultSet类:结果集
ResultSet对象实现了java.sql.ResultSet接口,可以在创建数据库交互对象时(createStatement(int RSType, int RSConcurrency);)指定ResultSet对象类型和ResultSet的并发性
浏览结果集:结果集对象实质是一个行列表,因此可以通过移动光标遍历结果集,移动光标方法如下
- beforeFirst()光标移动到第一行之前
- afterLast()光标移动到最后一行之后
- boolean first()光标移动到第一行
- last()光标移动到最后一行
- boolean absolute(int row)光标移动到row行
- boolean relative(int row)光标在当前位置向前(row<0)向后(row>0)移row行0)向后(row>
- boolean previous()光标移动到上一行 第一行时返回false
- boolean next()光标移动到下一行 最后一行时返回false
- int getRow()返回当前行数
- moveToInsertRow()光标移动到插入行
- moveToCurrentRow()光标移回原先行数
查看结果集:
通过列名称/列索引:getType(String columnName)/getType(int columnIndex)获取当前行数据
更新结果集:
通过列名称/列索引:updateType(String columnName, Type newValue)/updateType(int columnIndex,Type newValue)更新当前行数据
通过更新结果集数据更新数据库:
JDBC数据类型
JDBC驱动程序将Java数据类型与SQL数据类型提供一一对应的映射
NULL值处理:在查询结果集时若数据出现NULL值,需要使用ResultSet对象的wasNull()方法来将SQL的NULL值处理成java的数据类型,值得注意的是,ResultSet.wasNull()方法需要在getXXX()方法后使用
JDBC事务
- 启动手动事务支持:Connection.setAutoCommit(false);
- 提交事务:Connection.commit();
- 回滚事务:Connection.rollback();
- 回滚点:Savepoint savepoint=Connection.setSavepoint(“Savepoint1”);rollback(savepoint)仅保存回滚点前的更改
- 完整事务框架:
1
2
3
4
5
6
7
8
9
10
11
12
13try{
conn = DriverManager.getConnection(DB_URL,USER,PASS);
//启动手动事务支持
conn.setAutoCommit(false);
//数据库交互代码
//提交事务
conn.commit();
}catch(SQLException se){
//若出现错误 回滚事务
conn.rollback();
}
JDBC异常
对于JDBC,最常处理的的异常是java.sql.SQLException,驱动程序/数据库交互都会发生SQLException异常,我们可以使用try-catch-finally捕获SQLException异常对象进行处理,一般采用SQLException.printStackTrace();打印错误信息,以下有SQLException对象用于检索异常信息的方法
JDBC批量处理
- 确认数据库是否支持批量处理:DatabaseMetaData dbmd=Connection.getMetaData();dbmd.supportsBatchUpdates();返回boolean确定数据库是否支持批量更新操作
- 取消自动提交:Connection.setAutoCommit(false);
- 添加多条SQL语句到Statement对象中:Statement.addBatch(SQL);
- 执行SQL语句:int[] count = Statement.executeBatch();会返回整数数组表示相应更新语句的更新计数
- 提交事务更改:Connection.commit();
- 清除所有添加的批量语句:Statement.clearBatch();
SQL转义
通过转义序列,使得JDBC驱动可以以目标数据库的格式存储相应数据
- 日期:{d ‘yyyy-mm-dd’}
- 时间:{t ‘hh:mm:ss’}
- 日期+时间:{ts ‘yyyy-mm-dd hh:mm:ss’}
- DBMS中的标量函数:如SQL函数length获取字符串长度{fn length(‘Hello World’)}
- 外部连接:{oj outer-join}
JDBC流数据
JDBC中PreparedStatement对象可以使用输入流和输出流处理数据,例如针对CLOB/BLOB数据等大值数据可以通过转换成ASCII/UNICODE/二进制等流形势存储和读取数据
- setAsciiStream(int 参数占位符,FileInputStream 文件流,int 文件长度):将文件流转换成ASCII值
- setCharacterStream(int 参数占位符,FileInputStream 文件流,int 文件长度):将文件流转换成Character值
- setBinaryStream(int 参数占位符,FileInputStream 文件流,int 文件长度):将文件流转换成Binary值
- 相对应的ResultSet.getXXXStream(int columnIndex)将对应值转换成输入流InputStream