一、JDBC概述
1.1 简介
JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序。
JDBC可以在各种平台上使用Java,如Windows,Mac OS和各种版本的UNIX。
JDBC库包括与数据库使用相关的API。
- 连接数据库。
- 创建SQL或MySQL语句。
- 在数据库中执行SQL或MySQL查询。
- 查看和修改生成的记录。
1.2 JDBC体系结构
JDBC API支持用于数据库访问的两层和三层处理模型,但通常,JDBC体系结构由两层组成(Java程序中包含了API):
- JDBC:提供了应用程序到数据库连接规范,接口,需要实现类。
- JDBC驱动程序: 连接数据库的驱动程序的实现,对应不同的数据库公司的驱动程序,接口实现类。
JDBC API使用驱动程序管理器和特定于数据库的驱动程序来提供与异构数据库的透明连接。
1.3 JDBC核心组件
DriverManager: 此类管理数据库驱动程序列表。使用通信协议将来自java应用程序的连接请求与适当的数据库驱动程序匹配。
Driver:此接口处理与数据库服务器的通信,我们很少会直接与Driver对象进行交互。而是使用DriverManager对象来管理这种类型的对象。
Connection:该接口具有用于连接数据库的所有方法。连接对象表示通信上下文,数据库的所有通信仅通过连接对象。
Statement:使用从此接口创建的对象将SQL语句提交到数据库。除了执行存储过程之外,一些派生接口还接受参数【常用的是更安全的PreparedStatement】
ResultSet:在使用Statement对象执行SQL查询后,这些对象保存从数据库检索的数据。它作为一个迭代器,允许我们移动其数据。
SQLException:此类处理数据库应用程序中发生的任何异常。
二、JDBC相关的SQL语法
2.1 使用步骤
构建JDBC应用程序涉及以下六个步骤:
- 导入JDBC驱动包:需要下载包含数据库编程所需的JDBC的jar包。
- 注册JDBC驱动程序:要求您初始化驱动程序,以便您可以打开与数据库的通信通道。
- 创建连接:需要使用 DriverManager.getConnection() 方法创建一个Connection对象,该对象表示与数据库的物理连接。
- 执行查询:需要使用类型为Statement的对象来构建和提交SQL语句到数据库。
- 从结果集中提取数据:需要使用相应的ResultSet.getXXX() 方法从结果集中检索数据。
- 释放资源:需要明确地关闭所有数据库资源,而不依赖于JVM的垃圾收集。
2.2 标准格式代码
public class Deo1 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
/*1.导入jar包
* 2.项目下新建lib文件夹
* 3.将jar包导入 mysql-connector-java-5.1.48-bin.jar
* 4.右键jar包 Add As Library
* */
/*2.注册驱动,现在可以不用写,自动注册*/
Class.forName("com.mysql.jdbc.Driver");
/*3.获取连接对象*/
//jdbc:mysql: 协议
//localhost IP地址
//3306 端口号
//useSSL=true&charatcerEncoding=utf8 使用安全协议连接并规定编码
String url = "jdbc:mysql://localhost:3306/homework3?useSSL=true&charatcerEncoding=utf8";
Connection conn = DriverManager.getConnection(url, "root", "123456");
if (null != conn) {
System.out.println("连接成功");
}
//4.释放资源,【建议在finally中使用】
conn.close();
}
}
实际上,Class.forName()并不是注册驱动,而是通过反射调用了Driver类,通过静态代码块,类加载的时候就执行注册。如下为Driver源码,很明显通过静态代码块注册驱动。
//Driver源码
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
public Driver() throws SQLException {
}
static {
try {
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}
}
但是我们不建议使用静态DriverManager.registerDriver() 方法直接进行注册,原因:
- 驱动程序注册两次
- java程序依赖mysql驱动包
2.3 关于其他链接方式,以及其他数据库链接字符串格式
加载驱动程序后,可以使用DriverManager.getConnection() 方法建立连接。为了方便参考,让我列出三个重载的DriverManager.getConnection()方法 :
- getConnection(String url)
- getConnection(String url,Properties prop)
- getConnection(String url,String user,String password)
RDBMS | JDBC驱动程序名称 | 连接字符串格式 |
---|---|---|
MySQL | com.mysql.jdbc.Driver | jdbc:mysql:// hostname:3306 / 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.4 JDBC执行SQL语句
一旦获得了连接,我们可以与数据库进行交互。JDBC Statement和PreparedStatement接口定义了使您能够发送SQL命令并从数据库接收数据的方法和属性。
接口 | 使用 |
---|---|
Statement | 用于对数据库进行通用访问。在运行时使用静态SQL语句时很有用。Statement接口不能接受参数。 |
PreparedStatement(推荐使用) | 当您计划多次使用SQL语句时使用。PreparedStatement接口在运行时接受输入参数。 |
注意:在java中使用sql语句,不能忘记标点符号,如【;】【,】等
SQL语句注入导致的安全问题
就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意的)SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。比如先前的很多影视网站泄露VIP会员密码大多就是通过WEB表单递交查询字符暴出的,这类表单特别容易受到SQL注入式攻击。
所以这里建议使用【PreparedStatement】,它会要求使用占位符,导致不能注入,从而保证安全性。
三个执行方法
创建Statement对象后,您可以使用它来执行一个SQL语句,其中有三个执行方法:
- boolean execute(String SQL):如果可以检索到ResultSet对象,则返回一个布尔值true; 否则返回false。使用此方法执行SQL DDL语句或需要使用真正的动态SQL时。
- int executeUpdate(String SQL):返回受SQL语句执行影响的行数。使用此方法执行预期会影响多个行的SQL语句,例如INSERT,UPDATE或DELETE语句,以及DDL语句。
- ResultSet executeQuery(String SQL):返回一个ResultSet对象。当您希望获得结果集时,请使用此方法,就像使用SELECT语句一样,需要while循环进行遍历。
以上方法执行的时候都会有返回值,该值是SQL语句中的影响行数,比如,创建数据库成功,影响了一行语句;创建表成功,影响0行语句;对表数据增删改查,影响的是多行数据,返回就是大于0。
案例一:使用statement
public class Demo2 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//1.导入jar包
//2.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//3.建立连接
String url = "jdbc:mysql://localhost:3306/Demo2" +
"?useSSL=true&characterEncoding=utf8";
Connection conn = DriverManager.getConnection(url, "root", "123456");
/*4.创建命令*/
Statement statement = conn.createStatement();
/*5.执行命令*/
//5.1创建表
statement.executeUpdate("" +
"create table stu(" +
"id int primary key ," +
"name varchar(20), " +
"address varchar (20))");
//5.2插入数据
statement.executeUpdate("insert into stu(id,name,address) value " +
"(1,'张三','北京')," +
"(2,'李四','上海')," +
"(3,'王五','广州')," +
"(4,'赵六','深圳');");
//5.3修改数据
statement.executeUpdate("update stu set address='北京昌平' where id=1");
//先关掉命令
statement.close();
conn.close();
System.out.println("执行完毕");
}
}
案例二:ResultSet executeQuery,结果集的正序和逆序遍历
public class Demo3 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/Demo2?useSSL=true&characterEncoding=utf8";
Connection conn = DriverManager.getConnection(url, "root", "123456");
PreparedStatement pstatement = conn.prepareStatement("select * from stu");
ResultSet resultSet = pstatement