JDBC核心技术
JDBC概述
数据持久化
-
持久化(persistence):把数据保存到可掉电式存储设备中以供之后使用。大多数情况下,特别是企业级应用数据持久化意味着将内存中的数据保存到硬盘上加以"固化”,而持久化的实现过程大多通过各种关系数据库来完成。
-
持久化的主要应用是将内存中的数据存储在关系型数据库中,当然也可以存储在磁盘文件、XML数据文件中
Java中的数据存储技术
-
在Java中,数据库存取技术可分为如下几类
- JDBC直接访问数据库
- JDO (Java Data Object)技术
- 第三方O/R工具,如Hibernate,Mybatis等
-
JDBC是java访问数据库的基石,JDO、Hibernate、MyBatis等只是更好的封装了JDBC。
JDBC介绍
- JDBC(ava Database Connectivitv)是一个独立于特定数据库管理系统、通用的SOL数据库存取和操作的公共接口(一组API),定义了用来访问数据库的标准Java类库,**(java.sql,javax.sql)**使用这些类库可以以一种标准的方法、方便地访问数据库资源。
- JDBC为访问不同的数据库提供了一种统一的途径,为开发者屏蔽了一些细节问题。
- JDBC的目标是使ava程序员使用JDBC可以连接任何提供了JDBC驱动程序的数据库系统,这样就使得程序员无需对特定的数据库系统的特点有过多的了解,从而大大简化和加快了开发过程。
JDBC 体系结构
- JDBC接口(API)包括两个层次:
- 面向应用的API:Java API,抽象接口,供应用程序开发人员使用(连接数据库,
执行SQL语句,获得结果)。 - 面向数据库的API:Java Driver API,供开发商开发数据库驱动程序用。
- 面向应用的API:Java API,抽象接口,供应用程序开发人员使用(连接数据库,
JDBC 是sun 公司提供一套用于数据库操作的接口,java 程序员只需要面向这套接口编程即可。
不同的数据库厂商,需要针对这套接口,提供不同实现。不同的实现的集合,即为不同数据库的
驱动 。
JDBC API
- JDBC API 是一系列的接口,它使得应用程序能够进行数据库联接,执行SQL语句,并且得到返回结果。
JDBC程序访问数据库步骤
补充:ODBC(Open Database Connectivity,开放式数据库连接),是微软在Windows平台下推出的。 使用
者在程序中只需要调用ODBC API,由ODBC驱动程序将调用转换成为对特定的数据库的调用请求。
获取数据库连接
Driver 接口实现类
Driver接口介绍
- java.sql.Driver 接口是所有 JDBC 驱动程序需要实现的接口。这个接口是提供给数据库厂商使用的,不同数据库厂商提供不同的实现
- 在程序中不需要直接去访问实现了 Driver 接口的类,而是由驱动程序管理器类(java.sql.DriverManager)去调用这些Driver实现
- Oracle的驱动:oracle.jdbc.driver.OracleDriver
- mySql的驱动: com.mysql.jdbc.Driver
加载与注册 JDBC 驱动
-
方式一:加载 JDBC 驱动需调用 Class 类的静态方法
forName()
,向其传
递要加载的 JDBC 驱动的类名Class.forName(“com.mysql.jdbc.Driver”);
mysql8.0以上使用:Class.forName("com.mysql.cj.jdbc.Driver");
-
方式二:
DriverManager
类是驱动程序管理器类,负责管理驱动程序DriverManager.registerDriver(com.mysql.jdbc.Driver);
mysql8.0以上使用:DriverManager.registerDriver(com.mysql.cj.jdbc.Driver);
- 通常不用显式调用
DriverManager
类的registerDriver()
方法来注册驱动程序类的实
例,因为 Driver 接口的驱动程序类都包含了静态代码块,在这个静态代码块中,会
调用DriverManager.registerDriver()
方法来注册自身的一个实例
URL
-
DBCURL用于标识一个被注册的驱动程序,驱动程序管理器通过这个URL选择正确的驱动程序,从而建立到数据库的连接。
-
JDBCURL的标准由三部分组成,各部分间用冒号分隔
- jdbc:子协议:子名称
- 协议:JDBC URL中的协议总是jdbc
- 子协议:子协议用于标识一个数据库驱动程序
- 子名称:一种标识数据库的方法。子名称可以依不同的子协议而变化,用子名称的目的是为了定位数据库提供足够的信息。包含主机名(对应服务端的ip地址),端口号,数据库名
-
举例:
几种常用数据库的JDBC URL
-
对于 Oracle 数据库连接,采用如下形式:
jdbc:oracle:thin:@localhost:1521:test
-
对于 SQLServer 数据库连接,采用如下形式:
jdbc:microsoft:sqlserver//localhost:1433; DatabaseName=sid
-
对于 MYSQL 数据库连接,采用如下形式:
jdbc:mysql://localhost:3306/test
/* jdbc:mysql:协议 localhost:ip地址 3306:默认mysql的端口号 test:数据库名称 */
-
Mysql8.0以上:
jdbc:mysql//localhost:3306/db1?useSSL=false&serverTimezone=UTC
注意:mysql里要修改时区,否则无法连接数据库
# 仅修改当前会话的时区,停止会话失效 set time_zone = '+8:00'; # 修改全局的时区配置 set global time_zone = '+8:00'; flush privileges; #重启连接之后,查看 show variables like '%time_zone%'; # 或者找到my.ini, 在mysqld 下增加 default-time-zone = '+8:00' # 必须放到mysqld 下,放入其它位置无效
快速入门
步骤
- 导入驱动jar包 mysql-connector-java-8.0.22-bin.jar
- 复制mysql-connector-java-8.0.22-bin.jar到项目的libs目录下
- 右键libs --> Add As Library(添加到库…)
- 注册驱动
- 获取数据库连接对象Connection
- 定义sql
- 获取执行sql语句的对象 Statement
- 执行sql,接受返回结果
- 处理结果
- 释放资源
代码实现
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
/**
* JDBC快速入门
*/
public class Demo01Jdbc {
public static void main(String[] args) throws Exception {
//1. 导入驱动jar包
//2. 注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//3. 获取数据库连接对象Connection
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db1?useSSL=false&serverTimezone=UTC", "root", "0705zxl");
//4. 定义sql
String sql = "update account set balance = 500 where id = 1";
//5. 获取执行sql语句的对象 Statement
Statement stmt = conn.createStatement();
//6. 执行sql,接受返回结果
int count = stmt.executeUpdate(sql);
//7. 处理结果
System.out.println(count);
//8. 释放资源
stmt.close();
conn.close();
}
}
详解各个对象
DriverManager驱动管理对象
-
功能:
-
注册驱动:告诉程序该使用哪一个数据库驱动jar
-
static void registerDriver(Driver driver):注册与给定的驱动程序DriverManager。
-
写代码使用:Class.forName(“com.mysql.jdbc.Driver”);
-
mysql8.0以上使用:Class.forName(“com.mysql.cj.jdbc.Driver”);
-
通过查看源码发现:在com.mysql.cj.jdbc.Driver类中存在静态代码块
static { try { DriverManager.registerDriver(new Driver()); } catch (SQLException var1) { throw new RuntimeException("Can't register driver!"); } }
注意:mysql5之后的驱动jar包可以省略注册驱动的步骤。
-
-
获取数据库连接
-
方法:static Connection getConnection(String url, String user, String password);
-
参数:
-
url:指定连接的路径
如果连接的是本机mysql服务器,并且mysql服务默认端口是3306,则url可以简写为:
jdbc:mysql:///数据库名称?useSSL=false&serverTimezone=UTC
-
user:用户名
-
password:密码
-
-
-
Connection数据库连接对象
- 功能:
- 获取执行sql的对象
- Statement createStatement()
- PreparedStatement perparedStatement(String sql)
- 管理事务:
- 开启事务:void setAutoCommit(boolean autoCommit):调用该方法设置参数为false,即开启事务
- 提交事务:void commit()
- 回滚事务:void rollback()
- 获取执行sql的对象
Statement执行sql对象
-
执行sql
- boolean execute(String sql):可以执行任意sql(了解)
- int executeUpdate(String sql):执行DML(insert、update、delete)语句、DDL(create、alter、drop)语句
- 返回值:影响的行数,可以通过影响的行数判断DML语句是否执行成功 返回值>0的则执行成功,反之则失败
- ResultSet executeQuery(String sql):执行DQL(select)语句
-
练习
-
account表 添加一条记录
import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; /** * account表 添加一条记录 insert 语句 */ public class Demo02jdbc { public static void main(String[] args){ Statement stmt = null; Connection conn = null; try { //1.注册驱动 Class.forName("com.mysql.cj.jdbc.Driver"); //2.定义sql String sql = "insert into account values(null,'wangwu',3000)"; //3.获取sql对象 conn = DriverManager.getConnection("jdbc:mysql:///db1?useSSL=false&serverTimezone=UTC", "root", "0705zxl"); //4.获取执行sql的对象Statement stmt = conn.createStatement(); //5.执行sql int count = stmt.executeUpdate(sql);//影响的行数 //6.处理结果 System.out.println(count); if(count > 0){ System.out.println("添加成功!"); }else { System.out.println("添加失败!"); } } catch (ClassNotFoundException e) { e.printStackTrace(); }catch (SQLException e){ e.printStackTrace(); }finally { //7.释放资源 //stmt.close(); //避免空指针异常 if(stmt != null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if(conn != null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
-
account表 修改记录
import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; /** * account表 修改记录 update 语句 */ public class Demo03jdbc { public static void main(String[] args) { Connection conn = null; Statement stmt = null; try { //1.注册驱动 Class.forName("com.mysql.cj.jdbc.Driver"); //2.获取连接对象 conn = DriverManager.getConnection("jdbc:mysql:///db1?useSSL=false&serverTimezone=UTC", "root", "0705zxl"); //3.定义sql String sql = "update account set balance = 1500 where id = 3"; //4.获取执行sql的对象 stmt = conn.createStatement(); //5.执行sql int count = stmt.executeUpdate(sql);//影响的行数 //6.处理结果 System.out.println(count); if(count > 0){ System.out.println("修改成功!"); }else{ System.out.println("修改失败!"); } } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); }finally { //7.释放资源 if(stmt != null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if(conn != null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
-
account表 删除一条记录
import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; /** * account表 删除一条记录 delete 语句 */ public class Demo04jdbc { public static void main(String[] args) { Connection conn = null; Statement stmt = null; try { //1.注册驱动 Class.forName("com.mysql.cj.jdbc.Driver"); //2.获取连接对象 conn = DriverManager.getConnection("jdbc:mysql:///db1?useSSL=false&serverTimezone=UTC", "root", "0705zxl"); //3.定义sql String sql = "delete from account where id = 3"; //4.获取执行sql的对象 stmt = conn.createStatement(); //5.执行sql int count = stmt.executeUpdate(sql);//影响的行数 //6.处理结果 System.out.println(count); if(count > 0){ System.out.println("删除成功!"); }else{ System.out.println("删除失败!"); } } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); }finally { //7.释放资源 if(stmt != null){ try { stmt.close(); } catch (SQLException</
-