文章目录
JDBC 阶段学习
今日内容
1 JDBC 的概念
2 JDBC基础知识
3 java调用数据库的步骤
4 DriverManager
5 Connection
6 Statement
7 释放资源
8 实操
JDBC的概念
如果我想在开发过程中使用数据库,那么不同的数据库如oracle 或者mysql 可能就会出现不兼容的情况,因此JDBC可以理解为根据java访问的标准规范设计的接口,任何数据库厂商只要实现了这个接口,创建了属于自己数据库的实现类,也就是数据库驱动,我们就可以去调用接口中的方法了。
JDBC基础知识
1 使用JDBC开发使用到的包
2 JDBC 的核心API
3 如何导入驱动jar包
主要就是两步:
1.复制mysql-connector-java-5.1.37-bin.jar到项目的libs目录下
2.右键–>Add As Library
4 加载和注册驱动
如:
Class.forName(“com.mysql.jdbc.Driver”);
那为甚么这样可以这样可以注册驱动呢?
我们查看一下Driver接口,所有数据库厂商必须必须实现的接口,表示这是一个驱动类。
可以看到,这里有一个静态方法,只要创建了这个类就会自动被调用,底层还是调用DriverManager。也就自动帮你注册数据库驱动了
java调用数据库的步骤
- 注册和加载驱动(可以省略,在mysql5版本之后,可以省略,系统会自动帮你加载驱动)
- 获取连接
- Connection 获取 Statement 对象
- 使用 Statement 对象执行 SQL 语句
- 返回结果集
- 释放资源
DriverManager
- 管理和注册驱动
- 创建数据库的连接
类中的方法
使用 JDBC 连接数据库的四个参数:
url解析:
url也有简写方式:
乱码的处理:
如果数据库出现乱码,可以指定参数: ?characterEncoding=utf8,表示让数据库以 UTF-8 编码来处理数据。
jdbc:mysql://localhost:3306/数据库?characterEncoding=utf8
Connection
Connection 接口,具体的实现类由数据库的厂商实现,代表一个连接对象。
其中的方法
Statement
代表一条语句对象,用于发送 SQL 语句给服务器,用于执行静态 SQL 语句并返回它所生成结果的对象。
其中的方法
其中executeUpdate和也可以使用DDL语句,但是不常用,我们一般在mysql中创建表。
释放资源
- 需要释放的对象:ResultSet 结果集,Statement 语句,Connection 连接
- 释放原则:先开的后关,后开的先关。ResultSet ->Statement -> Connection也就是说最先关闭resultset
- 放在哪个代码块中:finally 块(否则某一个try中的代码出现问题,就会让后面的释放资源语句不执行,造成资源浪费)
关闭资源的语句
如:statement.close();另外我们需要在前面加上一个null判断以防止没有创建出来出现空指针异常
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
还有一点需要注意!
多个释放资源的语句不能放在同一个trycatch语句中,不然可能出现try中的语句没有完全执行完毕,就直接跳到catch中了,导致资源没有释放掉
完整的执行一次DML操作
public class JDBCDemo01 {
private static Statement statement=null;
private static Connection connection=null;
public static void main(String[] args) {
try {
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/db1","root","root");
statement = connection.createStatement();
String mysql="update table1 set age=66 where name='chen'";
int i= statement.executeUpdate(mysql);
if(i>0){
System.out.println("更改成功了!");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
finally {
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
完整执行一次DQL操作
ResultSet 接口:
封装数据库查询的结果集,对结果集进行遍历,取出每一条记录。
其中的方法:
这里我们需要什么类型的数据就可以直接get就行了,值得注意的是date类型的数据:
java.sql.Date、Time、Timestamp(时间戳),三个共同父类是:java.util.Date
public class JDBCDemo02 {
public static Connection connection=null;
public static Statement statement=null;
public static ResultSet resultSet=null;
public static void main(String[] args) {
try {
connection = DriverManager.getConnection(“jdbc:mysql://localhost:3306/db1”,“root”,“root”);
statement=connection.createStatement();
String mysql=“select * from table1”;
//结果也是一个集合
resultSet=statement.executeQuery(mysql);
//遍历集合
while (resultSet.next()){
String name=resultSet.getString(“name”);
int age=resultSet.getInt(“age”);
int grade=resultSet.getInt(“grade”);
System.out.println(name+"-"+age+"-"+grade);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
finally {
try {
resultSet.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
抽取工具类
实际上我们会发现上述两次操作有很多重复代码,我们总不能每次调用数据库都写这些代码吧,这时候就考虑抽取一个工具类
我们需要这个工具类实现三个方法:
- 可以把几个字符串定义成常量:用户名,密码,URL,驱动类
- 得到数据库的连接:getConnection()
- 关闭所有打开的资源:
public class JdbcUtils {
//可以把几个字符串定义成常量:用户名,密码,URL,驱动类
private static final String USER = "root";
private static final String PWD = "root";
private static final String URL = "jdbc:mysql://localhost:3306/day24";
private static final String DRIVER= "com.mysql.jdbc.Driver";
/**
* 注册驱动
*/
static {
try {
Class.forName(DRIVER);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 得到数据库的连接
*/
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(URL,USER,PWD);
}
/**
* 关闭所有打开的资源
*/
public static void close(Connection conn, Statement stmt) {
if (stmt!=null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn!=null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 关闭所有打开的资源
*/
public static void close(Connection conn, Statement stmt, ResultSet rs) {
if (rs!=null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
13 / 21
}
}
close(conn, stmt);
} }
注意这里
这里的连接数据库的方法实际上就写的很不好
我们是手动的去把地址写在一个变量中,这样每次只要更改表,或者用户我们就要去改代码,实际上我们应该将这些信息写在一个配置文件中,调用方法的时候让它自己找到地址和用户名进行连接。具体操作是:
我们可以在src也就是根目录下创建一个jdbc.properties配置文件,然后把用户名,和url放进去
然后在工具类之中使用静态代码块读取数据然后传入连接数据库的方法之中
static {
//读取资源文件,获取值。
try {
//1. 创建Properties集合类。
Properties pro = new Properties();
//获取src路径下的文件的方式--->ClassLoader 类加载器
ClassLoader classLoader = JDBCUtil.class.getClassLoader();
URL res = classLoader.getResource("jdbc.properties");
String path = res.getPath();
// System.out.println(path);///D:/IdeaProjects/itcast/out/production/day04_jdbc/jdbc.properties
//2. 加载文件
// pro.load(new FileReader("D:\\IdeaProjects\\itcast\\day04_jdbc\\src\\jdbc.properties"));
pro.load(new FileReader(path));
//3. 获取数据,赋值
url = pro.getProperty("url");
user = pro.getProperty("user");
pwd = pro.getProperty("password");
driver = pro.getProperty("driver");
//4. 注册驱动
Class.forName(driver);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
注意看这里实际上使用的是ClassLoader的getResource方法获得一个url,然后获取它的地址,这样的话不管谁使用这段代码都能使用
这个是通用的方法,下面展示一下完整的工具类:
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.sql.*;
import java.util.Properties;
public class JDBCUtil {
private static String user = null;
private static String pwd = null;
private static String url = null;
private static String driver = null;
static {
//读取资源文件,获取值。
try {
//1. 创建Properties集合类。
Properties pro = new Properties();
//获取src路径下的文件的方式--->ClassLoader 类加载器
ClassLoader classLoader = JDBCUtil.class.getClassLoader();
URL res = classLoader.getResource("JDBC.properties");
String path = res.getPath();
System.out.println(path);
// System.out.println(path);///D:/IdeaProjects/itcast/out/production/day04_jdbc/jdbc.properties
//2. 加载文件
// pro.load(new FileReader("D:\\IdeaProjects\\itcast\\day04_jdbc\\src\\jdbc.properties"));
pro.load(new FileReader(path));
//3. 获取数据,赋值
url = pro.getProperty("url");
user = pro.getProperty("user");
pwd = pro.getProperty("password");
driver = pro.getProperty("driver");
//4. 注册驱动
Class.forName(driver);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 得到数据库的连接
*/
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, user, pwd);
}
/**
* 关闭所有打开的资源
*/
public static void close(Connection conn, Statement stmt) {
if (stmt!=null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn!=null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 关闭所有打开的资源
*/
public static void close(Connection conn, Statement stmt, ResultSet rs) {
if (rs!=null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
close(conn, stmt);
}
}
###试着用一下这个工具类
import java.sql.*;
public class JDBCDemo03 {
private static Connection connection;
private static Statement statement;
private static ResultSet resultSet;
public static void main(String[] args) {
try {
connection = JDBCUtil.getConnection();
statement=connection.createStatement();
String mysql="select * from student";
//结果也是一个集合
resultSet=statement.executeQuery(mysql);
while (resultSet.next()){
int id=resultSet.getInt("sid");
String sName=resultSet.getString("sName");
Date sAge=resultSet.getDate("sAge");
String sSex=resultSet.getString("sSex");
System.out.println(id+"-"+sName+"-"+sAge+"-"+sSex);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
finally {
JDBCUtil.close(connection,statement,resultSet);
}
}
}