1. 概念
1.1 介绍
JDBC全称为Java Database Connectivity,中文名称为 Java 数据库连接,它是一种用于执行 SQL 语句的 Java API,它由一组用 Java 编程语言编写的类和接口组成。JDBC 为数据库开发人员提供了一个标准的 API,使他们能够用纯 Java API 来编写数据库应用程序。
1.2组成
JDBC API 是 Java 开发工具包(JDK)的组成部份,由三部分组成:
- JDBC 驱动程序管理器
- JDBC 驱动程序测试工具包
- JDBC-ODBC 桥
a. JDBC 驱动程序管理器是 JDBC 体系结构的支柱,其主要作 用是把 Java 应用程序连接到正确的 JDBC 驱动程序上。
b. JDBC 驱动程序测试工具包为 JDBC 驱动程序的运行提供一定的可信度,只有通过 JDBC 驱动程序测试包的驱动程序才被认为是符合 JDBC 标准的。
c. JDBC-ODBC 桥使 ODBC 驱动程序可被用作 JDBC 驱动程序。其目标是为方便实现访问某些不常见的 DBMS(数据库管理系统),它的实现为 JDBC 的快速发展提供了一条途径。
1.3 数据库访问模型
- 数据库访问的两层模型
- 数据库访问的三层模型
2. JDBC连接数据库
2.1 步骤
- 导入驱动程序
- 注册驱动程序:JVM加载所需的驱动类到内存
- 数据库URL指定
- 创建连接对象:代码调用
DriverManager
对象的getConnection()
方法建立实际的数据库连接
2.2 导入JDBC驱动
将mysql-connector-java-5.1.7-bin加入biuld-path
2.3 注册驱动程序
将我们将要使用的数据库的驱动类文件动态的加载到内存中
- 方法1——
Class.forName()
:
Class.forName("com.mysql.jdbc.Driver");
- 方法2——
DriverManager.registerDriver()
:
Driver driver = new com.mysql.jdbc.Driver();
DriverManager.registerDriver(driver);
2.4 指定数据库连接URL
DriverMannager.getConnection()有三个重载方法
getConnection(String url)
getConnection(String url, Properties prop)
getConnection(String url, String user, String password)
下表列出了下来流行的JDBC驱动程序名和数据库的URL
项目 | Value | URL |
---|---|---|
Mysql | com.mysql.jdbc.Driver | jdbc:mysql://hostname/ databaseName |
Oracle | oracle.jdbc.driver.OracleDriver | jdbc:oracle:thin:@hostname:port Number:databaseName |
DB2 | COM.ibm.db2.jdbc.net.DB2Driver | jdbc:db2:hostname:port Number/databaseName |
Sybase | com.sybase.jdbc.SybDriver | jdbc:sybase:Tds:hostname: port Number/databaseName |
2.5 创建连接对象
下面三种形式DriverManager.getConnection()方法来创建一个连接对象,以 Mysql 为例。getConnection()最常用形式要求传递一个数据库URL,用户名 username和密码 password。
- 使用数据库URL的用户名和密码
String URL = "jdbc:mysql://localhost/EXAMPLE";
String USER = "username";
String PASS = "password"
Connection conn = DriverManager.getConnection(URL, USER, PASS);
- 只使用一个数据库URL
在这种情况下,数据库的URL,包括用户名和密码。
String URL = "jdbc:mysql://localhost/EXAMPLE?user=root&password=0909";
//Mysql URL的参数设置详细可以查阅相关资料
Connection conn = DriverManager.getConnection(URL);
- 使用数据库的URL和一个Properties对象
import java.util.*;
String URL = "jdbc:mysql://localhost/EXAMPLE";
Properties pro = new Properties( );
//Properties对象,保存一组关键字-值对
pro.put( "user", "root" );
pro.put( "password", "" );
Connection conn = DriverManager.getConnection(URL, pro);
4、关闭JDBC 连接
conn.close();
3. JDBC接口
接口 | 应用场景 |
---|---|
Statement | 当在运行时使用静态 SQL 语句时(Statement接口不能接收参数) |
CallableStatement | 当要访问数据库中的存储过程时(CallableStatement对象的接口还可以接收运行时输入参数) |
PreparedStatement | 当计划多次使用 SQL 语句时(PreparedStatement 接口接收在运行时输入参数) |
3.1 Statement
使用Connection对象
的creatStatement()
方法创建Statement对象
Statement stmt = conn.creatStatement();
stmt.close()
Statementd对象方法
方法 | 说明 |
---|---|
boolean execute(String SQL) | 如果 ResultSet 对象可以被检索返回布尔值 true,否则返回 false。使用这个方法来执行 SQL DDL 语句,或当需要使用真正的动态 SQL |
int executeUpdate(String SQL) | 用于执行 INSERT、UPDATE 或 DELETE 语句以及 SQLDDL(数据定义语言)语句。返回值是一个整数,指示受影响的行数(即更新计数) |
ResultSet executeQuery(String SQL) | 返回 ResultSet 对象。用于产生单个结果集的语句,例如 SELECT 语句 |
3.2 PreparedStatement
PreparedStatement 接口扩展了 Statement 接口,有利于高效地执行多次使用的 SQL 语句。先创建一个 PreparedStatement 对象。 Statement 为一条 SQL 语句生成执行计划。如果要执行两条 SQL 语句,会生成两个执行计划。一万个查询就生成一万个执行计划!
select colume from table where colume=1;
select colume from table where colume=2;
PreparedStatement 用于使用绑定变量重用执行计划。通过 set 不同数据,只需要生成一次执行计划,并且可以重用。
select colume from table where colume=:x;
PreparedStatement pstmt = null;
try {
/*
在JDBC中所有的参数都被代表?符号,这是已知的参数标记。在执行SQL语句之前,必须提供值的每一个参数。
*/
String SQL = "Update Students SET age = ? WHERE id = ?";
pstmt = conn.prepareStatement(SQL);
. . .
}
/*
setXXX()方法将值绑定到参数,其中XXX表示希望绑定到输入参数值的 Java 数据类型。如果忘了提供值,将收到一个 SQLException。
*/
3.3 CallableStatement
CallableStatement 对象为所有的 DBMS 提供了一种以标准形式调用存储过程的方法。存储过程储存在数据库中。对储存过程的调用是 CallableStatement 对象所含的内容。三种类型的参数有:IN,OUT和INOUT。PreparedStatement对象只使用IN参数。 CallableStatement对象可以使用所有三个
参数 | 描述 |
---|---|
IN | 它的值是在创建 SQL 语句时未知的参数,将 IN 参数传给 CallableStatement 对象是通过 setXXX() 方法完成的 |
OUT | 其值由它返回的 SQL 语句提供的参数。从 OUT 参数的 getXXX() 方法检索值 |
INOUT | 同时提供输入和输出值的参数,绑定的 setXXX() 方法的变量,并使用 getXXX() 方法检索值 |
在 JDBC 中调用存储过程的语法如下所示。注意,方括号表示其间的内容是可选项;方括号本身并不是语法的组成部份。
{call 存储过程名[(?, ?, ...)]}
返回结果参数的过程的语法为:
{? = call 存储过程名[(?, ?, ...)]}
不带参数的存储过程的语法类似:
{call 存储过程名}
CallableStatement 对象是用 Connection 方法 prepareCall 创建的。
CallableStatement cstmt = null;
try {
String SQL = "{call getEXAMPLEName (?, ?)}";
cstmt = conn.prepareCall (SQL);
. . .
}
catch (SQLException e) {
. . .
}
finally {
cstmt.close();
}
4. JDBC结果集
4.1 ResultSet介绍
结果集通常是通过执行查询数据库的语句生成,表示数据库查询结果的数据表。ResultSet 对象具有指向其当前数据行的光标。最初,光标被置于第一行之前。next 方法将光标移动到下一行;因为该方法在 ResultSet 对象没有下一行时返回 false,所以可以在 while 循环中使用它来迭代结果集。光标可以方便我们对结果集进行遍历。默认的 ResultSet 对象不可更新,仅有一个向前移动的光标。因此,只能迭代它一次,并且只能按从第一行到最后一行的顺序进行。
ResultSet接口的方法可分为三类:
- 导航方法:用于移动光标
- 获取方法:用于查看当前行的光标所指向的列中的数据
- 更新方法:用于更新当前行的列中的数据
JDBC 提供下列连接方法来创建所需的ResultSet语句:
createStatement(int RSType, int RSConcurrency);
prepareStatement(String SQL, int RSType, int RSConcurrency);
prepareCall(String sql, int RSType, int RSConcurrency);
RSType 表示 ResultSet 对象的类型,RSConcurrency 是 ResultSet 常量,用于指定一个结果集是否为只读或可更新。
ResultSet 的类型,如果不指定 ResultSet 类型,将自动获得一个是TYPE_FORWARD_ONLY:
类型 | 描述 |
---|---|
ResultSet.TYPE_FORWARD_ONLY | 游标只能向前移动的结果集 |
ResultSet.TYPE_SCROLL_INSENSITIVE | 游标可以向前和向后滚动,但不及时更新,就是如果数据库里的数据修改过,并不在ResultSet中反应出来 |
ResultSet.TYPE_SCROLL_SENSITIVE | 游标可以向前和向后滚动,并及时跟踪数据库的更新,以便更改ResultSet中的数据 |
并发性的ResultSet,如果不指定任何并发类型,将自动获得一个为 CONCUR_READ_ONLY
并发 | 描述 |
---|---|
ResultSet.CONCUR_READ_ONLY | 创建结果集只读。这是默认的 |
ResultSet.CONCUR_UPDATABLE | 创建一个可更新的结果集 |
如初始化一个 Statement 对象来创建一个双向、可更新的ResultSet对象:
try {
Statement stmt = conn.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
}
catch(Exception ex) {
....
}
finally {
....
}
4.2 ResultSet方法
方法 | 说明 |
---|---|
public void beforeFirst() throws SQLException | 将光标移动到正好位于第一行之前 |
public void afterLast() throws SQLException | 将光标移动到刚刚结束的最后一行 |
public boolean first() throws SQLException | 将光标移动到第一行 |
public void last() throws SQLException | 将光标移动到最后一行 |
public boolean absolute(int row) throws SQLException | 将光标移动到指定的行 |
public boolean relative(int row) throws SQLException | 从它目前所指向向前或向后移动光标行的给定数量 |
public boolean previous() throws SQLException | 将光标移动到上一行。上一行关闭的结果集此方法返回false |
public boolean next() throws SQLException | 将光标移动到下一行。如果没有更多的行结果集中的此方法返回false |
public int getRow() throws SQLException | 返回的行号,该光标指向的行 |
public void moveToInsertRow() throws SQLException | 将光标移动到一个特殊的行,可以用来插入新行插入到数据库中的结果集。当前光标位置被记住 |
public void moveToCurrentRow() throws SQLException | 移动光标返回到当前行,如果光标在当前插入行,否则,这个方法不执行任何操作 |
5. 附录
5.1 SQL启动
启动服务: service mysqld start
连接数据库:mysql –u root
新建数据库:creat datavase EXAMPLE
使用数据库:use EXAMPLE
创建表:
mysql> create table Students
-> (
-> id int not null,
-> age int not null,
-> name varchar(255),
-> primary key(id)
-> );
表中插入数据:insert into Students values(1,18,'Tom'),(2,20,'Aby'),(4,20,'Tomson');
5.2 SQL操作
5.2.1 创建数据库
//CREATE DATABASE语句用于创建一个新的数据库。语法是:
SQL> CREATE DATABASE DATABASE_NAME;
//例子,创建一个名为 EXAMPLE 数据库:
SQL> CREATE DATABASE EXAMPLE;
5.2.2 删除数据库
//使用DROP DATABASE语句用于删除现有的数据库。语法是:
SQL> DROP DATABASE DATABASE_NAME;
//注意:要创建或删除,应该有数据库服务器上管理员权限。请注意,删除数据库将损失所有存储在数据库中的数据。
//例子,删除我们刚刚建好的数据库:
SQL> DROP DATABASE EXAMPLE;
5.2.3 创建表
//CREATE TABLE语句用于创建一个新表。语法是:
SQL> CREATE TABLE table_name
(
column_name column_data_type,
column_name column_data_type,
column_name column_data_type
...
);
//例子,下面的SQL语句创建一个有四个属性的 Students 表:
SQL> CREATE TABLE Students
(
id INT NOT NULL,
age INT NOT NULL,
name VARCHAR(255),
major VARCHAR(255),
PRIMARY KEY ( id )
);
5.2.4 删除表
//DROP TABLE语句用于删除现有的表。语法是:
SQL> DROP TABLE table_name;
//例子,下面的SQL语句删除一个名为 Students 表:
SQL> DROP TABLE Students;
5.2.5 插入数据
//语法 INSERT 如下,其中 column1, column2 ,依此类推的属性值:
SQL> INSERT INTO table_name VALUES (column1, column2, ...);
//例子,下面的 INSERT 语句中插入先前创建的 Students 表:
SQL> INSERT INTO Students VALUES (1, 18, 'Mumu', 'Java');
5.2.6 查询数据
//SELECT语句用于从数据库中检索数据。该语法的SELECT是:
SQL> SELECT column_name, column_name, ...
FROM table_name
WHERE conditions;
//WHERE 子句可以使用比较操作符例如 =, !=, <, >, <=, >=,以及 BETWEEN 和 LIKE 等操作符。
//例子,下面的 SQL 语句从 Students 表选择 id 为1的学生,并将该学生的姓名和年龄显示出来:
SQL> SELECT name, age
FROM Students
WHERE id = 1;
//下面的SQL语句从 Students 表中查询姓名中有 om 字样的学生,并将学生的姓名和专业显示出来:
SQL> SELECT name, major
FROM Students
WHERE name LIKE '%om%';
5.2.7 更新数据
//UPDATE语句用于更新数据。UPDATE语法为:
SQL> UPDATE table_name
SET column_name = value, column_name = value, ...
WHERE conditions;
//例子,下面的 SQL 的 UPDATE 语句表示将 ID 为1的学生的 age 改为20:
SQL> UPDATE Students SET age=20 WHERE id=1;
5.2.8 删除数据
//DELETE语句用来删除表中的数据。语法DELETE是:
SQL> DELETE FROM table_name WHERE conditions;
//例子,下面的 SQL DELETE 语句删除 ID 为1的学生的记录:
SQL> DELETE FROM Students WHERE id=1;
6. 问题
6.1 使用Eclipse连接linux虚拟机报错
Host is not allowed to connect to this MySQL server
Linux上面装完MySQL,可以本地登录,但是远程登录却报错Host is not allowed to connect to this MySQL server。这个错误,其实就是我们的MySQL不允许远程登录,所以远程登录失败了,解决方法如下:
- 在装有MySQL的机器上登录MySQL mysql -u root -p密码
- 执行use mysql;
- 执行update user set host = ‘%’ where user = ‘root’;这一句执行完可能会报错,不用管它。
- 执行FLUSH PRIVILEGES;
注: 第四步是刷新MySQL的权限相关表
6.2 service mysqld stop失败
停止mysql失败
解决方法:
sudo cat /var/run/mysqld/mysqld.pid
10064
kill 10064
service mysqld stop