持久化(Persistence
),是将数据保存到可永久保存的存储设备中。持久化的主要应用是将内存中的对象存储在数据库中,或者存储在磁盘文件中、XML数据文件中等等。JDBC就是一种持久化机制,文件IO也是一种持久化机制。
浅显的理解,在一定周期内保持不变就是持久化,持久化是针对时间来说的。数据库中的数据就是持久化了的数据,只要你不去删除或修改。
JDBC(Java Data Base Connectivity
,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一组标准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序。
有了JDBC,向各种数据库发送SQL语句就是一件很容易的事。换言之,有了JDBC API
,就不必为访问MySQL数据库专门写一个程序,为访问Oracle数据库又专门写一个程序,或为访问DB2数据库又编写另一个程序等等,程序员只需用JDBC API写一个程序就够了,它可向相应数据库发送SQL调用。同时,将Java语言和JDBC结合起来使程序员不必为不同的平台编写不同的应用程序,只须写一遍程序就可以让它在任何平台上运行,这也是Java语言“编写一次,处处运行”的优势。
Java数据库连接体系结构是用于Java应用程序连接数据库的标准方法。JDBC对Java程序员而言是API,对实现与数据库连接的服务提供商而言是接口模型。作为API
,JDBC为程序开发提供标准的接口,并为数据库厂商及第三方中间件厂商实现与数据库的连接提供了标准方法。JDBC实现了所有这些面向标准的目标并且具有简单、严格类型定义且高性能实现的接口。
JDBC可以做三件事:
在技术上,JDBC实现数据的添加、删除、修改、查询等操作,是Java应用程序与数据库通信的桥梁。
软件开发中的界面负责数据输入,并将输入的数据提交给Java程序,Java程序通过JDBC将数据保存到数据库中。JDBC也负责从数据库中获取数据,然后将数据交给Java程序,最后Java程序将数据交给界面显示,如下图所示。
Java程序访问数据库,使用JDBC提供的一套标准API,这套API主要是接口,由各个数据库的厂商去实现,并封装成jar
包的形式提供给开发人员,如下图所示:
在实际项目开发中,我们确定要连接的数据库,在对应的数据库官方网站下载厂商已经实现的数据库连接用的驱动jar包,将驱动jar包导入到我们的项目中即可完成项目对特定数据库连接的支持。
项目支持了数据库的连接之后,就需要开发人员开发具体的程序来实现数据库数据的操作了。java提供了以下接口和类来支持和数据库之间的操作。
类或接口 | 作用 |
---|---|
java.sql.DriverManager 类 |
表示数据库驱动包的管理对象 |
java.sql.Connection 接口 |
表示数据库的连接对象 |
java.sql.Statement 接口 |
表示发送sql给数据库执行的对象 |
java.sql.PreparedStatement 接口 |
java.sql.Statement 的子接口,表示sql预编译对象 |
java.sql.ResultSet 接口 |
表示从数据库查询返回的结果数据 |
JDBC在运行时的大致步骤如下图所示,执行的顺序如下:
DriverManager
类驱动数据库;Connection
接口负责将Java程序和数据库建立连接;Statement
接口将SQL语句发送到数据库中;ResultSet
接口处理数据库返回的结果集。DriverManager
管理一组 JDBC 驱动程序的基本服务。可以通过该管理类来建立并获取和指定数据库之间的连接。
返回值 | 方法名 | 作用 |
---|---|---|
Connection |
getConnection(String url, String user, String password) |
使用账号user 和密码password ,建立到指定数据库url 的连接,连接成功后返回新的数据库连接 |
Connection |
getConnection(String url) |
建立并获取到指定url 数据库的连接 |
DriverManager
类在加载数据库驱动时,需要指明url
,这里的url通常称作数据库连接字符串。数据库连接字符串用于确定连接协议、连接的数据库服务器、端口号、数据库名称及其连接参数。主协议:子协议://数据库服务器:端口号/数据库名称?连接参数
company_info
数据库如下: jdbc:mysql://localhost:3306/company_info?user=root&password=root
Connection
接口的作用让Java程序与数据库之间建立连接。只有在数据库连接后,才能将SQL语句发送到数据库中执行。Connection
接口常用方法如下表:
返回值 | 方法名 | 作用 |
---|---|---|
Statement |
createStatement() |
创建一个 Statement 对象来将 SQL 语句发送到数据库。 |
PreparedStatement |
prepareStatement(String sql) |
创建一个 PreparedStatement 对象来将参数化的 SQL 语句发送到数据库。 |
PreparedStatement |
prepareStatement(String sql, int autoGeneratedKeys) |
创建一个默认 PreparedStatement 对象,该对象能获取自动生成的键。 |
void |
setAutoCommit(Boolean autoCommit) |
将此连接的自动提交模式设置为给定状态。 |
void |
commit() |
使所有上一次提交/回滚后进行的更改成为持久更改,并释放此Connection 对象当前持有的所有数据库锁。 |
void |
rollback() |
取消在当前事务中进行的所有更改,并释放此Connection 对象当前持有的所有数据库锁。 |
boolean |
isClosed() |
查询此Connection 对象是否已经被关闭。 |
void |
close() |
立即释放此Connection 对象的数据库和 JDBC 资源,而不是等待它们被自动释放。 |
返回值 | 方法名 | 作用 |
---|---|---|
boolean |
execute(String sql) |
执行给定的 SQL 语句,该语句可能返回多个结果。 |
boolean |
execute(String sql, int autoGeneratedKeys) |
执行给定的 SQL 语句(该语句可能返回多个结果),并通知驱动程序所有自动生成的键都可用于获取。 |
int |
executeUpdate(String sql) |
执行给定 SQL 语句,该语句可能为 INSERT 、UPDATE 或 DELETE 语句,或者不返回任何内容的 SQL 语句(如 SQL DDL 语句)。 |
int |
executeUpdate(String sql, int autoGeneratedKeys) |
执行给定的 SQL 语句,并用给定标志通知驱动程序由此 Statement 生成的自动生成键是否可用于获取。 |
ResultSet |
executeQuery(String sql) |
执行给定的 SQL 语句,该语句返回单个ResultSet 对象。 |
boolean |
isClosed() |
获取是否已关闭了此Statement 对象。 |
void |
close() |
立即释放此Statement 对象的数据库和 JDBC 资源,而不是等待该对象自动关闭时发生此操作。 |
返回值 | 方法名 | 作用 |
---|---|---|
boolean |
execute() |
在此 PreparedStatement 对象中执行 SQL 语句,该语句可以是任何种类的 SQL 语句。 |
void |
setObject(int parameterIndex, Object x) |
使用给定对象设置指定参数的值。 |
int |
executeUpdate() |
在此 PreparedStatement 对象中执行 SQL 语句,该语句必须是一个 SQL 数据操作语言(Data Manipulation Language ,DML )语句,比如 INSERT 、UPDATE 或 DELETE 语句;或者是无返回内容的 SQL 语句,比如 DDL 语句。 |
ResultSet |
executeQuery() |
在此 PreparedStatement 对象中执行 SQL 查询,并返回该查询生成的 ResultSet 对象 |
返回值 | 方法名 | 作用 |
---|---|---|
boolean |
next() |
将光标从当前位置向前移一行 |
Object |
getObject(int columnIndex) |
以 Java 编程语言中 Object 的形式获取此 ResultSet 对象的当前行中指定列的值 |
Object |
getObject(String columnLabel) |
以 Java 编程语言中 Object 的形式获取此 ResultSet 对象的当前行中指定列的值 |
boolean |
isClosed() |
获取此 ResultSet 对象是否已关闭 |
void |
close() |
立即释放此 ResultSet 对象的数据库和 JDBC 资源,而不是等待该对象自动关闭时发生此操作 |
返回值 | 方法名 | 作用 |
---|---|---|
String |
getCatalogName(int column) |
获取指定列的表目录名称 |
String |
getColumnClassName(int column) |
如果调用方法 Resultset. getobiect 从列中获取值,则返回构造其实例的Java类的完全限定名称 |
int |
getColumnCount() |
返回此 Resultset 对象中的列数 |
int |
getColumnDisplaySize(int column) |
指示指定列的最大标准宽度,以字符为单位。 |
String |
getColumnLabel(int column) |
获取用于打印输出和显示的指定列的建议标题。 |
String |
getColumnName(int column) |
获取指定列的名称 |
int |
getColumnType(int column) |
获取指定列的SQL类型 |
String |
getColumnTypeName(int column) |
获取指定列的数据库特定的类型名称 |
int |
getPrecision(int column) |
获取指定列的指定列宽 |
int |
getScale(int column) |
获取指定列的小数点右边的位数 |
String |
getSchemaName(int column) |
获取指定列的表模式。 |
String |
getTableName(int column) |
获取指定列的名称 |
boolean |
isAutoincrement(int column) |
指示是否自动为指定列进行编号。 |
boolean |
isCaseSensitive(int column) |
指示列的大小写是否有关系 |
boolean |
isCurrency(int column) |
指示指定的列是否是一个哈希代码值。 |
boolean |
isDefinitelyWritable(int column) |
指示在指定的列上进行写操作是否明确可以获得成功。 |
int |
isNullable(int column) |
指示指定列中的值是否可以为null |
boolean |
isReadOnly(int column) |
指示指定的列是否明确不可写入 |
boolean |
isSearchable(int column) |
指示是否可以在 where 子句中使用指定的列 |
boolean |
isSigned(int column) |
指示指定列中的值是否带正负号 |
boolean |
isWritable(int column) |
指示在指定的列上进行写操作是否可以获得成功 |
JDBC操作数据库分为7步(祖传七步)
现在来创建一个数据库,命名为jdbc_demo
,在jdbc_demo
数据库中users
表,users
表结构如下表。利用jdbc_demo
数据库完成jdbc操作数据库的任务.
列名 | 类型 | 约束 |
---|---|---|
id |
int |
主键,自增长 |
username |
Varchar(20) |
用户名 |
userpass |
Varchar(20) |
密码 |
CREATE TABLE users(
id int PRIMARY KEY not null auto_increment COMMENT '主键id',
username VARCHAR(20) not null COMMENT '用户名',
userpass VARCHAR(20) not null COMMENT '用户密码'
)
package com.luas.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
/**
* 使用jdbc添加用户
*
* @author DingYi
* @date 2020/4/4 15:11
*/
public class AddUserDemo {
public static void main(String[] args) {
addUser("武汉","23456");
}
/**
* 添加用户的方法
* @param username 用户名称
* @param userpass 用户密码
*/
private static void addUser(String username,String userpass){
Connection conn = null;
Statement stat = null;
try{
// 1.注册数据库驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.建立和数据库之间的驱动
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc_demo?useSSL=false&characterEncoding=utf8","root","root");
// 3. 拼写SQL语句
String sql = "insert into users(username,userpass) values ('" + username + "','" + userpass + "')";
// 4. 向数据库发送并执行SQL语句
stat = conn.createStatement();
int rows = stat.executeUpdate(sql);
// 5. 处理执行结果
System.out.println("数据库中有" + rows + "条数据被执行……");
}catch(ClassNotFoundException | SQLException e){
e.printStackTrace();
}finally {
// 6. 关闭资源
if (conn != null){
try{
conn.close();
conn = null;
}catch (SQLException e){
e.printStackTrace();
}
}
}
}
}
package com.luas.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
/**
* 使用jdbc修改数据库中的信息
*
* @author DingYi
* @date 2020/4/5 15:43
*/
public class UpdateUserDemo {
public static void main(String[] args) {
updateUser("张三","2580",3);
}
/**
* 修改用户的方法
*
* @param username 用户名称
* @param userpass 用户密码
* @param id 用户编号
*/
public static void updateUser(String username,String userpass,int id){
Connection conn = null;
Statement stat = null;
try{
// 1. 注册数据库驱动
Class.forName("com.mysql.jdbc.Driver");
// 2. 建立和数据库之间的连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc_demo?useSSL=false&characterEncoding=utf8","root","root");
// 3. 拼写SQL语句
String sql = "update users set username ='"+ username +"',userpass = '"+ userpass +"' where id = " + id;
// 4. 向数据库发送并执行SQL语句
stat = conn.createStatement();
int rows = stat.executeUpdate(sql);
// 5. 处理执行结果
System.out.println("数据库中有" + rows + "条数据被执行……");
}catch(ClassNotFoundException | SQLException e){
e.printStackTrace();
}finally {
// 6. 关闭资源
if(conn != null){
try{
conn.close();
conn = null;
}catch(SQLException e){
e.printStackTrace();
}
}
if(stat != null){
try{
stat.close();
stat = null;
}catch(SQLException e){
e.printStackTrace();
}
}
}
}
}
package com.luas.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
/**
* 使用JDBC删除表中数据
*
* @author DingYi
* @date 2020/4/5 16:14
*/
public class DeleteUserDemo {
public static void main(String[] args) {
deleteUser(3);
}
/**
* 删除用户方法
*
* @param id 用户编号
*/
private static void deleteUser(int id){
Connection conn = null;
Statement stat = null;
try{
// 1.注册数据库驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.建立和数据库之间的连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc_demo?useSSL=false&characterEncoding = utf8","root","root");
// 3.拼写SQL语句
String sql = "delete from users where id = " + id;
// 4.向数据库发送并执行SQL语句
stat = conn.createStatement();
int rows = stat.executeUpdate(sql);
// 5.处理执行结果
System.out.println("数据库中有" + rows + "条语句被执行...");
}catch(ClassNotFoundException | SQLException e){
e.printStackTrace();
}finally {
// 6.关闭资源
if (conn != null) {
try{
conn.close();
conn = null;
}catch (SQLException e){
e.printStackTrace();
}
}
if (stat != null) {
try {
stat.close();
stat = null;
}catch (SQLException e){
e.printStackTrace();
}
}
}
}
}