## 使用 JDBC 工具类的原因
在使用 JDBC 连接数据库的时候, 加载驱动, 获取连接, 释放资源等代码是重复的, 所有为了提高代码的复用性, 我们可以写一个工具类, 将数据库驱动加载, 获取连接, 资源释放的代码封装起来. 同时, 为了使工具类的灵活性, 可以将数据库的驱动, url, 用户名, 密码等信息以键值对的形式存放在 properties 文件中, 工具类初始化时从配置文件中读取所要连接数据库的信息. 当需要更改连接的数据库时, 只需要更改配置文件即可, 而不必改写工具类的代码.
- ## 工具类实现
- ```
- import java.io.IOException;
- import java.io.InputStream;
- import java.sql.*;
- import java.util.Properties;
- /**
- * JDBC 工具类
- */
- // 工具类的方法应该都是静态的, 这样方便我们去调用
- public class JDBCUtils {
- private static String url;
- private static String user ;
- private static String password;
- private static String driver;
- /**
- * 文件的读取, 只需要读取一次就可以拿到值: 使用静态代码块
- */
- static {
- // 获取资源文件, 获取值
- try {
- /*// 获取 src 路径下的文件的方式: ClassLoader 类加载器 , 要获取 Classloader, 要获取他对应的字节码文件
- ClassLoader classLoader = JDBCUtils.class.getClassLoader();
- URL resource = classLoader.getResource("jdbc.properties");
- String path = resource.getPath(); // 返回字符串路径
- //System.out.println(path);
- */
- InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
- Properties pro = new Properties();
- //2 加载文件
- pro.load(is);
- //3 获取属性, 赋值
- url = pro.getProperty("url");
- user = pro.getProperty("user");
- password = pro.getProperty("password");
- driver = pro.getProperty("driver");
- // 注册驱动
- Class.forName(driver);
- } catch (IOException e) {
- e.printStackTrace();
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
- }
- /**
- * 获取连接
- * @return 连接对象释放资源
- */
- public static Connection getConnection() throws SQLException {
- return DriverManager.getConnection(url,user,password);
- }
- /**
- * 释放资源
- * @param stmt
- * @param conn
- */
- public static void close(ResultSet rs,Statement stmt, Connection conn){
- if (rs!=null){
- try {
- rs.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- 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(Statement stmt, Connection conn){
- if (stmt!=null){
- try {
- stmt.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- if (conn!=null){
- try {
- conn.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
- }
- ```
下面我们来写一个测试类:
- ## 测试类
- ```
- import util.JDBCUtils;
- import java.sql.*;
- import java.util.Scanner;
- /**
- * 通过键盘录入用户和密码
- * 判断用户是否登录成功
- */
- public class jdbcDemo9 {
- public static void main(String[] args) {
- //1. 键盘录入, 接受用户名和密码
- Scanner sc = new Scanner(System.in);
- System.out.println("请输入用户名");
- String username = sc.nextLine();
- System.out.println("请输入密码");
- String password = sc.nextLine();
- //2. 调用方法
- boolean flag = new jdbcDemo9().login2(username,password);
- //3. 判断结果输出不同语句
- if (flag){
- System.out.println("登录成功");
- }else {
- System.out.println("用户名或密码错误");
- }
- }
- /**
- * 登录方法使用 PreparedStatement 实现
- */
- public boolean login2(String username,String password){
- if (username==null || password==null){
- return false;
- }
- Connection conn =null;
- PreparedStatement pstmt = null;
- ResultSet rs =null;
- // 连接数据库判断是否登录成功
- try {
- conn = JDBCUtils.getConnection();// 在这里 debug 的时候显示 conn=null, 以及下面的变量都显示错误
- //2 定义 sql
- String sql = "select * from user where username = ? and password = ?";
- //3 获取执行 sql 的对象
- pstmt = conn.prepareStatement(sql);
- // 给? 赋值
- pstmt.setString(1,username);
- pstmt.setString(2,password);
- //4 执行查询 不需要传递参数
- rs = pstmt.executeQuery(sql);
- //5. 判断
- return rs.next(); // 如果有下一行, 返回 true
- } catch (SQLException e) {
- e.printStackTrace();
- } finally {
- JDBCUtils.close(rs,pstmt,conn);
- }
- return false;
- }
- }
- ```
- ## 配置文件
- ```
- url=jdbc:MySQL://localhost:3306/db4?useSSL=false&serverTimezone=UTC
- user=root
- password=nana980801
- driver=com.MySQL.cj.jdbc.Driver
- ```
** 注意: 这里我使用的是 MySQL8.0, 所有配置文件与之前的版本有些不同. 如果你使用的是 MySQL8.0 而配置文件是 8.0 对应版本之前的, 就会报错.**
- ## 运行结果
- ```
请输入用户名
zhangsan
请输入密码
123
登录成功
- Process finished with exit code 0
- ```
来源: https://www.cnblogs.com/lichenhui/p/11456904.html