什么是JDBC
- Java数据库连接,(Java Database Connectivity,简称JDBC)
- 它是用于执行SQL语句的Java API
什么是数据库驱动
- 驱动:两个设备之间通信的桥梁
为什么要引入JDBC
- 因为不同种类的数据库(MySQL、Oracle)在其内部处理数据的方式是不同的,为了统一规范,SUN公司就提供了这套接口JDBC。
mysql的java驱动包下载
MySQL驱动包官网下载
我下载的版本5.1.49
导入jar包
右键选择Build Path下的Add to Build Path
JDBC的开发步骤
- 加载驱动
- 获得连接
- 基本操作
- 释放资源
代码如下:
public void demo1() throws Exception {
//1.加载mysql驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获得连接
//这里前面一样后面需要改成你的数据库名test
String url = "jdbc:mysql://localhost:3306/test";
//root用户
String user = "root";
//数据库密码
String password = "*****";
Connection conn = DriverManager.getConnection(url,user,password);
//3.基本操作:执行SQL
//3.1获得执行SQL语句的对象
Statement statement = conn.createStatement();
//3.2编写SQL语句
String sql = "select * from student";
//3.3执行SQL
ResultSet rs = statement.executeQuery(sql);
//3.4遍历结果集
while(rs.next()) {
String sno = rs.getString("sno");
String sname = rs.getString("sname");
String ssex = rs.getString("ssex");
int sage = rs.getInt("sage");
String sdept = rs.getString("sdept");
System.out.println(sno + "|" + sname + "|" + ssex
+ "|" + sage + "|" + sdept);
}
//4.释放资源
rs.close();
statement.close();
conn.close();
}
如果您出现这样的红色警报:
内容如下:
Thu Apr 29 15:37:45 CST 2021 WARN: Establishing SSL connection without server’s identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn’t set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to ‘false’. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
翻译翻译(什么叫惊喜):
Thu Apr 29 15:37:45 CST 2021 WARN:不建议在没有服务器身份验证的情况下建立SSL连接。MySQL 5.5.45+、5.6.26+和5.7.6+要求如果没有设置显式选项,则默认需要建立SSL连接。为了符合未使用SSL的现有应用程序,verifyServerCertificate属性被设置为“false”。您需要通过设置useSSL=false显式禁用SSL,或者设置useSSL=true并为服务器证书验证提供信任库。
为了不影响咱们学习JDBC,就在url后面加一个?useSSL=false
JDBC的API之DriverManager
DriverManager:驱动管理类
- 作用一:注册驱动
DriverManager.registerDriver(new Driver());来注册驱动很可,但是实际开发不回应,因为当注册的同时Driver()里面又注册了一次.
因此,用
//1.加载mysql驱动
Class.forName("com.mysql.jdbc.Driver");
- 作用二:获得连接
jdbc:mysql://localhost:3306/test
- jdbc:连接数据库的协议
- mysql:jdbc的子协议
- localhost:连接的MySQL数据库服务器的主机地址
- 若不是本机,需要写上连接主机的IP地址
- 3306:MySQL数据库服务器的端口号
- test:数据库的名称
若连接的是本机的路径,可以简化为:
jdbc:mysql:///test
JDBC的API之Connection
Connection:与数据库连接对象
- 作用一:创建执行SQL语句的对象
createStatement()
创建用于向数据库发送SQL语句的一个Statement对象。
conn.createStatement();
- Statement:执行SQL
- prepareStatement:执行SQL进行预处理,解决SQL注入漏洞
- 作用二:管理事务
JDBC的API之Statement
Statement:执行SQL
- 作用一:执行SQL
boolean execute(String sql)
- 执行查询,修改,添加,删除的SQL语句
常用:
ResultSet executeQuery(String sql)
- 执行查询(执行select语句)
int executeUpdate(String sql)
- 执行修改,添加,删除的SQL语句
- 作用二:批量处理
void addBatch(String sql)
void clearBatch()
JDBC的API之ResultSet
ResultSet:结果集
通过select语句的查询结果
结果集的遍历
//3.3执行SQL
ResultSet rs = statement.executeQuery(sql);
//3.4遍历结果集
while(rs.next()) {
String sno = rs.getString("sno");
String sname = rs.getString("sname");
String ssex = rs.getString("ssex");
int sage = rs.getInt("sage");
String sdept = rs.getString("sdept");
System.out.println(sno + "|" + sname + "|" + ssex
+ "|" + sage + "|" + sdept);
}
结果集的获取
getXXX():方法通常都会有一个重载的方法
JDBC的资源释放
- JDBC程序执行结束后,将与数据库进行交互的对象释放掉,通常是:ResultSet,Statement,Connection
- 这几个对象尤其是Connection对象是稀有的,尽量晚创建,早释放
- 将资源的释放代码写入到finally代码块中
标准代码:
@Test
public void demo1(){
Statement stmt = null;
Connection conn = null;
ResultSet rs = null;
//1.加载mysql驱动
try {
Class.forName("com.mysql.jdbc.Driver");
//2.获得连接
String url = "jdbc:mysql://localhost:3306/test?useSSL=false";
String user = "root";
String password = "****";
conn = DriverManager.getConnection(url,user,password);
//3.基本操作:执行SQL
//3.1获得执行SQL语句的对象
stmt = conn.createStatement();
//3.2编写SQL语句
String sql = "select * from student";
//3.3执行SQL
rs = stmt.executeQuery(sql);
//3.4遍历结果集
while(rs.next()) {
String sno = rs.getString("sno");
String sname = rs.getString("sname");
String ssex = rs.getString("ssex");
int sage = rs.getInt("sage");
String sdept = rs.getString("sdept");
System.out.println(sno + "|" + sname + "|" + ssex
+ "|" + sage + "|" + sdept);
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//4.释放资源
if(rs != null) {
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
rs = null;
}
if(stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
stmt = null;
}
if(conn != null) {
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
conn = null;
}
}
}
创建JDBC的工具类
- 因为每次操作数据库时,都需要注册驱动、获得连接、释放资源,为了把这些重复的代码进行整合,用一个类来实现它们。
public class JDBCUtils {
private static final String dirverClassName;
private static final String url;
private static final String username;
private static final String password;
static {
dirverClassName = "com.mysql.jdbc.Driver";
url = "jdbc:mysql:///test?useSSL=false";
username = "root";
password = "***";
}
/**
* 注册驱动的方法
*/
public static void loadDriver() {
try {
Class.forName(dirverClassName);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 获得连接的方法
*/
public static Connection getConnection() {
Connection conn = null;
loadDriver();
try {
conn = DriverManager.getConnection(url, username, password);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return conn;
}
/**
* 释放资源的方法
*/
public static void release(Statement stmt,Connection conn) {
if(stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
stmt = null;
}
if(conn != null) {
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
conn = null;
}
}
public static void release(ResultSet rs,Statement stmt,Connection conn) {
if(rs != null) {
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
rs = null;
}
if(stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
stmt = null;
}
if(conn != null) {
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
conn = null;
}
}
}
JDBC的配置信息提取到配置文件
- 配置文件:
- 属性文件
- 格式:扩展名是.properties
- 内容:key = value
- xml文件
- 属性文件
1、创建db.properties
dirverClassName = com.mysql.jdbc.Driver
url = jdbc:mysql:///test?useSSL=false
username = root
password = ****
2、提取文件的内容
static {
//获取属性文件中的内容:
Properties properties = new Properties();
try {
properties.load(new FileInputStream("src/db.properties"));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
dirverClassName = properties.getProperty("dirverClassName");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
}
JDBC的API之PreparedStatement
- SQL语句的执行是通过Statement对象实现的,每次执行SQL语句的时候,都会对其编译,当相同的SQL语句多次执行,会降低数据库的访问效率。
- 因此,Statement提供了一个子类PreparedStatement,它可以对SQL语句进行预编译,预编译的信息会存储在PreparedStatement对象中,当相同的SQL语句再次执行时,程序会使用这个对象存储的数据,而不需要对SQL语句再次编译去查询数据库。
插入一条数据
preStmt = conn.prepareStatement();
String sql = "insert into student values('?','?','?',?,'?')";
//一共5个参数
preStmt.setString(1,'121');
preStmt.setString(2,'dwj');
preStmt.setInt(3,12);
preStmt.setString(4,'121');
preStmt.setString(5,'121');