一,基本介绍
JDBC(Java Database Connectivity)是一种用于执行SQL语句的Java API,有三个作用:与数据库建立连接、发送 SQL 语句,处理结果。
二,重要类介绍
1.DriverManager
管理一组 JDBC 驱动程序的基本服务。
作为连接数据库初始化的一部分,DriverManager
类初始化驱动程序。
在调用 getConnection
方法时,DriverManager
会试着从初始化时加载的那些驱动程序以及使用与当前 applet 或应用程序相同的类加载器显式加载的那些驱动程序中查找合适的驱动程序。
API上方法摘要:
常用方法:
getConnection():从摘要中能看出这个方法名称下分为不同参数的方法。虽然参数不同,但都有一个共同点:
试图建立到给定数据库 URL 的连接。DriverManager
试图从已注册的 JDBC 驱动程序集中选择一个适当的驱动程序。
以下是API的解释,后面将实例佐证:
2.Connection
与特定数据库的连接(会话)。在连接上下文中执行 SQL 语句并返回结果。
注:在配置 Connection
时,JDBC 应用程序应该使用适当的 Connection
方法,比如setAutoCommit
或setTransactionIsolation
。
在有可用的 JDBC 方法时,应用程序不能直接调用 SQL 命令更改连接的配置。
默认情况下,Connection
对象处于自动提交模式下,这意味着它在执行每个语句后都会自动提交更改。
如果禁用了自动提交模式,那么要提交更改就必须显式调用 commit
方法;否则无法保存数据库更改。
常用方法:
close():立即释放此 Connection
对象的数据库和 JDBC 资源,而不是等待它们被自动释放。
commit():使所有上一次提交/回滚后进行的更改成为持久更改,并释放此 Connection
对象当前持有的所有数据库锁。
rollback():取消在当前事务中进行的所有更改,并释放此 Connection
对象当前持有的所有数据库锁。
rollback(Savepoint savepoint):取消所有设置给定 Savepoint
对象之后进行的更改。
setAutoCommit(boolean autoCommit):设置自动提交模式。true为自动提交,false为手动提交。
prepareStatement等方法实例介绍。
3.Statement
咱们这里说的Statement类,是指定java.sql.Statement,提供使用 JavaTM 编程语言访问并处理存储在数据源(通常是一个关系数据库)中的数据的 API。
从API中看看其子接口和方法:
常用方法:
createStatement():创建一个 Statement
对象来将 SQL 语句发送到数据库。
不同参数的用法在实例中显示。
4.PreparedStatement
表示预编译的 SQL 语句的对象。SQL 语句被预编译并存储在 PreparedStatement
对象中。然后可以使用此对象多次高效地执行该语句。
注:用于设置 IN 参数值的设置方法(setShort
、setString
等等)必须指定与输入参数的已定义 SQL 类型兼容的类型。
例如,如果 IN 参数具有 SQL 类型 INTEGER
,那么应该使用 setInt
方法。
如果需要任意参数类型转换,使用 setObject
方法时应该将目标 SQL 类型作为其参数。
在以下设置参数的示例中,con
表示一个活动连接:
PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES SET SALARY = ? WHERE ID = ?"); pstmt.setBigDecimal(1, 153833.00) pstmt.setInt(2, 110592)常用方法:
execute():在此 PreparedStatement
对象中执行 SQL 语句,该语句可以是任何种类的 SQL 语句。
executeQuery():在此 PreparedStatement
对象中执行 SQL 查询,并返回该查询生成的 ResultSet
对象。
返回:包含该查询生成的数据的 ResultSet
对象;不会返回 null
executeUpdate():在此 PreparedStatement
对象中执行 SQL 语句,该语句必须是一个 SQL 数据操作语言(Data Manipulation Language,DML)语句,
比如 INSERT
、UPDATE
或 DELETE
语句;或者是无返回内容的 SQL 语句,比如 DDL 语句。
返回:(1) SQL 数据操作语言 (DML) 语句的行数 (2) 对于无返回内容的 SQL 语句,返回 0
其它有很多方法,可以参考java API
5.ResultSet
PreparedStatement
.executeQuery() 对象中执行 SQL 查询,并返回该查询生成的ResultSet
对象;
Statement.executeQuery()执行给定的 SQL 语句,该语句返回单个ResultSet
对象。
存放结果集,ResultSet使用next方法用于移动到ResultSet中的下一行,使下一行成为当前行,通过循环,输出查询结果。
三,JDBC连接数据库步骤分析(这里Mysql为例)
1.连接数据库的jar包
mysql-connector-java-5.1.21.jar
2.连接用户名,密码,url,对应数据库驱动
String user = "root";
String password = "root123";
String url = "jdbc:mysql://192.168.200.12:3306/hbtest?useUnicode=true&characterEncoding=UTF8&allowMultiQueries=true";
String driver = "com.mysql.jdbc.Driver";
3.加载驱动
Class.forName(driver);
4.连接数据库
Connection conn = DriverManager.getConnection(url, user, password);
5.连接成功后,与数据库进行交互操作
eg.
//编写sql
Statement st = conn.createStatement();
String sql = "CREATE TABLE person ( " +
" id int(11) NOT NULL AUTO_INCREMENT COMMENT '个人信息表'," +
" name varchar(10) DEFAULT NULL COMMENT '姓名'," +
" age int(3) DEFAULT NULL COMMENT '年龄',PRIMARY KEY (id) " +
") ENGINE=InnoDB DEFAULT CHARSET=utf8;";
//执行sql
int result = st.executeUpdate(sql);
总结:用户名,密码,url,驱动--》加载驱动类--》连接数据库--》写sql执行
四,JDBC连接数据库实例
1.Statement部分
1.1 executeUpdate()使用实例
package com.lanhuigu.hibernate.util; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement; /** * JDBC简单实例演示之--statement的executeUpdate()方法使用 */ public class DBSimple { public static void main(String[] args) { String user = "root"; String password = "root123"; /* * useUnicode=true:表示使用Unicode字符集 * characterEncoding=UTF8:字符编码方式 * allowMultiQueries=true:是否允许批量处理 */ String url = "jdbc:mysql://192.168.200.12:3306/hbtest?useUnicode=true&characterEncoding=UTF8&allowMultiQueries=true"; String driver = "com.mysql.jdbc.Driver"; try { //1.加载驱动类 Class.forName(driver); //2.连接数据库 Connection conn = DriverManager.getConnection(url, user, password); //3.编写sql Statement st = conn.createStatement(); String sql = "CREATE TABLE person ( " + " id int(11) NOT NULL AUTO_INCREMENT COMMENT '个人信息表'," + " name varchar(10) DEFAULT NULL COMMENT '姓名'," + " age int(3) DEFAULT NULL COMMENT '年龄',PRIMARY KEY (id) " + ") ENGINE=InnoDB DEFAULT CHARSET=utf8;"; //4.执行sql /* * Statement的 * executeUpdate(String sql): * 执行给定 SQL 语句,该语句可能为 INSERT、UPDATE 或 DELETE 语句,或者不返回任何内容的 SQL 语句(如 SQL DDL 语句)。 * 参数: * SQL 数据操作语言(Data Manipulation Language,DML)语句,如 INSERT、UPDATE 或 DELETE;或者不返回任何内容的 SQL 语句,如 DDL 语句。 * 返回: * (1) 对于 SQL 数据操作语言 (DML) 语句,返回行计数 (2) 对于什么都不返回的 SQL 语句,返回 0。 * 抛出: * SQLException--如果发生数据库访问错误,在已关闭的 Statement 上调用此方法,或者给定的 SQL 语句生成 ResultSet 对象 */ int result = st.executeUpdate(sql);//在数据库中创建person表,注意:可以写insert,update,delete类型sql语句执行 //5.输出结果 System.out.println(result); } catch (Exception e) { // TODO: handle exception System.out.println("数据库连接失败"); } } }1.2 executeQuery()使用实例
package com.lanhuigu.hibernate.util; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; /** * JDBC简单实例演示之--statement的executeQuery()方法使用 */ public class DBSimple { public static void main(String[] args) { String user = "root"; String password = "root123"; /* * useUnicode=true:表示使用Unicode字符集 * characterEncoding=UTF8:字符编码方式 * allowMultiQueries=true:是否允许批量处理 */ String url = "jdbc:mysql://192.168.200.12:3306/hbtest?useUnicode=true&characterEncoding=UTF8&allowMultiQueries=true"; String driver = "com.mysql.jdbc.Driver"; try { //1.加载驱动类 Class.forName(driver); //2.连接数据库 Connection conn = DriverManager.getConnection(url, user, password); //3.编写sql Statement st = conn.createStatement(); String sql = "SELECT id,name,age FROM person"; //4.执行sql /* * Statement的 * ResultSet executeQuery(String sql)throws SQLException: * 执行给定的 SQL 语句,该语句返回单个 ResultSet 对象。 * 参数: * sql - 要发送给数据库的 SQL 语句,通常为静态 SQL SELECT 语句。 * 返回: * 包含给定查询所生成数据的 ResultSet 对象;永远不能为 null * 抛出: * SQLException - 如果发生数据库访问错误,在已关闭的 Statement 上调用此方法,或者给定 SQL 语句生成单个 ResultSet 对象之外的任何其他内容 */ ResultSet rs = st.executeQuery(sql);//查询person表的基本信息 //5.输出结果 while (rs.next()) { System.out.println(rs.getString("id")); System.out.println(rs.getString("name")); System.out.println(rs.getString("age")); /* * 根据查询sql语句的别名做key,拿到对应的值,可以将这些值封装到域模型对象,将对象封装到集合中等, * 然后再跟jsp页面交互等都能实现 */ } } catch (Exception e) { // TODO: handle exception System.out.println("数据库连接失败"); } } }总结:根据以上两个方法,对数据库的增、删、改、查都能实现,具体别的更高级的方法就是封装,一些特殊的场景特殊用法,参考java API方法实例。
2.PreparedStatement部分
PreparedStatement与Statement的区别与联系:
2.1 PreparedStatement接口继承Statement, PreparedStatement 实例包含已编译的 SQL 语句,所以其执行速度要快于 Statement 对象。
2.2 作为 Statement 的子类,PreparedStatement 继承了 Statement 的所有功能。三种方法execute、 executeQuery 和 executeUpdate 已被更改以使之不再需要参数。
注意:从性能和可维护性,安全性考虑,尽量避免使用Statement,应使用PreparedStatement.
execute()使用实例:
package com.lanhuigu.hibernate.util; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; /** * JDBC简单实例演示之--PreparedStatement的execute()方法使用 */ public class DBSimple { public static void main(String[] args) { String user = "root"; String password = "root123"; /* * useUnicode=true:表示使用Unicode字符集 * characterEncoding=UTF8:字符编码方式 * allowMultiQueries=true:是否允许批量处理 */ String url = "jdbc:mysql://192.168.200.12:3306/hbtest?useUnicode=true&characterEncoding=UTF8&allowMultiQueries=true"; String driver = "com.mysql.jdbc.Driver"; try { //1.加载驱动类 Class.forName(driver); //2.连接数据库 Connection conn = DriverManager.getConnection(url, user, password); //3.编写预编译sql String sql = "SELECT id,name,age FROM person"; PreparedStatement ps = conn.prepareStatement(sql); //4.执行sql /* * PreparedStatement的 * execute() throws SQLException * 一些预处理过的语句返回多个结果,execute 方法处理这些复杂的语句,executeQuery 和 executeUpdate 处理形式更简单的语句。 * execute 方法返回一个 boolean 值,指示第一个结果的形式。必须调用 getResultSet 或 getUpdateCount 方法获取该结果,必须调用 getMoreResults 获取任何后续结果。 * 返回: * 如果第一个结果是 ResultSet 对象,则返回 true;如果第一个结果是更新计数或者没有结果,则返回 false * 抛出: * SQLException - 如果发生数据库访问错误;在关闭的 PreparedStatement 上调用此方法,或者为此方法提供了参数 */ ResultSet rs = ps.executeQuery();//查询person表的基本信息 //5.输出结果 while (rs.next()) { System.out.println(rs.getString("id")); System.out.println(rs.getString("name")); System.out.println(rs.getString("age")); /* * 根据查询sql语句的别名做key,拿到对应的值,可以将这些值封装到域模型对象,将对象封装到集合中等, * 然后再跟jsp页面交互等都能实现 */ } rs.close(); ps.close(); conn.close(); } catch (Exception e) { // TODO: handle exception System.out.println("数据库连接失败"); } } }
PreparedStatement的execute(),executeQuery(),executeUpdate()无参数。
Statement的sql语句每次执行都要编译,而PreparedStatement是预编译的,每次执行,sql被DB编译器缓存起来,下次使用可直接使用,无需再次编译浪费时间。
补充:使用PreparedStatement的优点(好处):
1.代码的可读性以及可维护性。
2.PreparedStatement在最高程度上提高性能。
3.最大限度做到安全性提高。