搞懂JDBC这一篇就够了!!!(二)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 搞懂JDBC这一篇就够了!!!(二)

三、JDBC工具类



目的


简化书写


分析


1.注册驱动也抽取


2.抽取一个方法获取连接对象


需求:不想传递参数(麻烦),还带保证工具类的通用新


解决:properties配置文件


url=jdbc:mysql:///db2
user=root
password=root
driver=com.mysql.jdbc.Driver


抽取一个方法释放资源


package cn.caq.utils;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
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 {
            //读取资源文件,获取值
            //1.创建Properties集合类
            Properties pro = new Properties();
            //获取src路径下的文件方式--->ClassLoader 类加载器
            ClassLoader classLoader = JDBCutils.class.getClassLoader();
            URL res = classLoader.getResource("jdbc.properties");//得到文件的绝对路径
            String path = res.getPath();//将绝对路径转化为字符串形式
            //FileReader用来读用户本地的文件
            pro.load(new FileReader(path));
            //2.加载文件
    //pro.load(new FileReader("src/jdbc.properties"));
            //3.获取数据,赋值
            url = pro.getProperty("url");
            user = pro.getProperty("user");
            password = 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, password);
    }
    /**
     * 释放资源的方法
     */
    public static void close(ResultSet rs, Statement stmt, Connection conn) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
}


使用工具类


package cn.caq.jdbc;
import cn.caq.domain.Emp;
import cn.caq.utils.JDBCutils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
public class JdbcDemo07 {
    public static void main(String[] args) {
        List<Emp> list = new JdbcDemo07().findall2();
        System.out.println(list);
    }
    /**
     * 演示JDBC工具类
     */
    public List<Emp> findall2() {
        Connection conn = null;
        Statement stmt = null;
        ResultSet res = null;
        ArrayList<Emp> list = null;
        try {
//            //1.注册驱动
//            Class.forName("com.mysql.jdbc.Driver");
//            //2.获取连接对象
//            conn = DriverManager.getConnection("jdbc:mysql:///db2", "root", "root");
            conn = JDBCutils.getConnection();
            //3.定义sql
            String sql = "select * from emp";
            //4.获取执行sql对象
            stmt = conn.createStatement();
            //5.执行sql
            res = stmt.executeQuery(sql);
            //6.处理结果
            Emp emp = null;
            list = new ArrayList<>();
            while (res.next()) {
                int id = res.getInt("id");
                String ename = res.getString("ename");
                int job_id = res.getInt("job_id");
                //创建emp对象,并赋值
                emp = new Emp();
                emp.setId(id);
                emp.setEname(ename);
                emp.setJob_id(job_id);
                //装载集合
                list.add(emp);
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            JDBCutils.close(res,stmt,conn);
        }
        return list;
    }
}


登陆练习


需求:


1.通过键盘录入用户名和密码


2.判断用户是否登录成功


select * from user where username = “” and password = “”;


如果这个sql有查询结果,则成功反之失败


数据库


image.png


代码


package cn.caq.jdbc;
import cn.caq.utils.JDBCutils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;
/**
 * 需求:
 * 1.通过键盘录入用户名和密码
 * 2.判断用户是否登录成功
 */
public class JDBCDemo08 {
    public static void main(String[]args){
        //1.键盘录入,接受用户名和密码
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入username:");
        String username = scanner.nextLine();
        System.out.println("请输入password");
        String password = scanner.nextLine();
        //2.调用方法
//        JDBCDemo08 jdbcDemo08 = new JDBCDemo08();
//        boolean login = jdbcDemo08.login(username, password);
        boolean flag = new JDBCDemo08().login(username, password);
        //3.判断结果,输出不同语句
        if (flag){
            System.out.println("Success!!!!!!");
        }else {
            System.out.println("username or passwd False!!!!!!!!");
        }
    }
    //登录方法
    public boolean login(String username,String password){
        if (username == null || password == null){
            return false;
        }
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        //1.连接数据库
        try {
            conn = JDBCutils.getConnection();
            //2.定义sql
            String sql = "select * from user where username = '"+username+"' and password = '"+password+"'";
            //3.获取执行sql的对象
            stmt = conn.createStatement();
            //4.执行sql语句
            rs = stmt.executeQuery(sql);
            //5.判断
            return rs.next();//有下一行返回true
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            JDBCutils.close(rs,stmt,conn);
        }
        return false;//如果出现异常返回false
    }
}
输出结果为:
请输入username:
zs
请输入password
123
Success!!!!!!
请输入username:
sadfa
请输入password
24323
username or passwd False!!!!!!!!


四、JDBC控制事务



1.事务:一个包含多个步骤的业务操作。如果这个业务操作被事务管理,则这多个步骤要么同时成功,要么同时失败。


2.操作:


1.开后事务


2.提交事务


3.回滚事务


3.使用connection对象来管理事务


开启事务: setAutoCommit(boolean autoCommit) :调用该方法设置参数为false,即开后事务


在执行sql之前开启事务


提交事务: commit()


当所有sql都执行完提交事务


回滚事务: rollback()


在catch中回滚事务


转账实例


package cn.caq.jdbc;
import cn.caq.utils.JDBCutils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
 * 事务操作
 */
public class JDBCDemo10 {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement pstmt1 = null;
        PreparedStatement pstmt2 = null;
        //1.获取连接
        try {
            conn = JDBCutils.getConnection();
            //开启事务
            conn.setAutoCommit(false);
            //2.定义sql
            //2.1张三 - 500
            String sql1 = "update account set balance = balance - ?  where id = ?";
            //2.1李四 + 500
            String sql2 = "update account set balance = balance + ?  where id = ?";
            //3.获取执行sql对象
            pstmt1 = conn.prepareStatement(sql1);
            pstmt2 = conn.prepareStatement(sql2);
            //4.设置参数
            pstmt1.setDouble(1, 500);
            pstmt1.setInt(2, 1);
            pstmt2.setDouble(1, 500);
            pstmt2.setInt(2, 2);
            //5.执行sql
            pstmt1.executeUpdate();
            //手动制造异常
            int i = 3 / 0;
            pstmt2.executeUpdate();
            //提交事务
            conn.commit();
        } catch (Exception throwables) {
            try {
                if (conn != null) {
                    conn.rollback();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
            throwables.printStackTrace();
        }
    }
}


如果中途出现任何异常,则触发回滚操作!


   输出结果为:


java.lang.ArithmeticException: / by zero
  at cn.caq.jdbc.JDBCDemo10.main(JDBCDemo10.java:43)
金额没有发生变化


image.png


五、数据库连接池



概念


其实就是一个容器(集合),存放数据库连接的容器


当系统初始化好后,容器被初始化,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完后,会将连接对象返回给容器


好处


节约资源


高效


实现


标准的接口:DataSource javax.sql包下的


方法:


获取连接:getConnection()


归还连接:Connection.close().如果连接对象Connection是从连接池中获取的,那么调用Connection.close()不在是关闭连接,而是归还连接


2.这个接口,一般不由人为实现,而是有数据库厂商来实现


C3P0:数据库连接池技术


Druid:数据库连接池实现技术,由阿里提供


一、C3P0:数据库连接池技术


步骤:


1.导入jar包

c3p0-0.9.5.2.jar


mchange-commons-java-0.2.12.jar


还有驱动jar包


2.定义配置文件

名称:c3p0.properties或者c3p0-config.xml


路径:直接将文件放在src目录下即可


3.创建核心对象

数据库连接池对象 ComboPoolDataSource


4.获取连接

getConnection


了解即可


二、Druid:数据库连接池实现技术


1.写入jar包

druid-1.e.9.jar


2.定义配置文件

是properties形式的(properties 性能)

可以叫任意名称,可以放在任意目录下


3.获取数据库连接池对象:通过工厂类来获取

DruidDataSourceFactory


4.获取连接

getConnection


5.实例


package com.caq.datasource.druid;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.util.Properties;
public class DruidDemo01 {
    public static void main(String[] args) throws Exception {
        //1.导入Jar包
        //2.定义配置文件
        //3.加载配置文件
        Properties pro = new Properties();
        InputStream is = DruidDemo01.class.getClassLoader().getResourceAsStream("druid.properties");//得到输出流
        pro.load(is);//获取文件的路径
        //4.获取连接池对象
        DataSource ds = DruidDataSourceFactory.createDataSource(pro);
        //5.获取连接
        Connection conn = ds.getConnection();
        System.out.println(conn);
    }
}
输出结果为:
十月 20, 2021 10:32:02 下午 com.alibaba.druid.pool.DruidAbstractDataSource error
严重: maxIdle is deprecated
十月 20, 2021 10:32:03 下午 com.alibaba.druid.pool.DruidDataSource info
信息: {dataSource-1} inited
com.mysql.jdbc.JDBC4Connection@6956de9


三、Druid工具类


1.定义一个类JDBCUtils


2.提供静态代码块加载配置文件,初始化连接池对象


3.提供方法


1.获取连接方法:通过数据库连接池获取


2.释放资源


3.获取连接池的方法


实例

详细的注释都写在代码中了!


package com.caq.datasource.utils;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
/**
 * Druid连接池工具类
 */
public class JDBCUtils {
    //1.定义成员变量  DataSource
    private static DataSource ds;
    static {
        try {
            //1.加载配置文件
            Properties pro = new Properties();
            pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
            //2.获取DataSource
            ds = DruidDataSourceFactory.createDataSource(pro);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 获取连接
     */
    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }
    /**
     * 释放资源
     */
    //第一种情况,执行DML语句,需要释放connection数据库连接对象和statementsql语句执行对象
    public static void close(Statement stmt, Connection conn) {
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close(); //归还连接,不在是释放了
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
    //第二种情况,执行DQL语句,释放三个资源,conn,stmt和resultSet结果集对象
    //这里写一个方法重载即可
    public static void close(ResultSet rs, Statement stmt, Connection conn) {
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close(); //归还连接,不在是释放了
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
    /**
     * 获取连接池的方法
     */
    public static DataSource getDataSource(){
        return ds;
    }
}
测试
package com.caq.datasource.druid;
import com.caq.datasource.utils.JDBCUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
 * 使用新的工具类
 */
public class DruidDemo02 {
    public static void main(String[] args) {
        /*
        完成添加的操作 给account表添加一条记录
         */
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            //1.获取连接
            conn = JDBCUtils.getConnection();
            //2.定义sql
            String sql = "insert into account values(null,?,?)";
            //3.获取pstmt对象
            pstmt = conn.prepareStatement(sql);
            //4.给sql赋值
            pstmt.setString(1, "王五");//给第一个参数赋值为王五
            pstmt.setDouble(2, 3000);//给第二个参数赋值为3000
            //5.执行sql
            int count = pstmt.executeUpdate();
            System.out.println(count);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            //6.释放资源
            JDBCUtils.close(pstmt,conn);
        }
    }
}
输出结果为
十月 21, 2021 8:40:18 下午 com.alibaba.druid.pool.DruidAbstractDataSource error
严重: maxIdle is deprecated
十月 21, 2021 8:40:19 下午 com.alibaba.druid.pool.DruidDataSource info
信息: {dataSource-1} inited


查看数据库


image.png


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
18天前
|
存储 弹性计算 人工智能
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
2025年9月24日,阿里云弹性计算团队多位产品、技术专家及服务器团队技术专家共同在【2025云栖大会】现场带来了《通用计算产品发布与行业实践》的专场论坛,本论坛聚焦弹性计算多款通用算力产品发布。同时,ECS云服务器安全能力、资源售卖模式、计算AI助手等用户体验关键环节也宣布升级,让用云更简单、更智能。海尔三翼鸟云服务负责人刘建锋先生作为特邀嘉宾,莅临现场分享了关于阿里云ECS g9i推动AIoT平台的场景落地实践。
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
|
9天前
|
云安全 人工智能 安全
Dify平台集成阿里云AI安全护栏,构建AI Runtime安全防线
阿里云 AI 安全护栏加入Dify平台,打造可信赖的 AI
|
12天前
|
人工智能 运维 Java
Spring AI Alibaba Admin 开源!以数据为中心的 Agent 开发平台
Spring AI Alibaba Admin 正式发布!一站式实现 Prompt 管理、动态热更新、评测集构建、自动化评估与全链路可观测,助力企业高效构建可信赖的 AI Agent 应用。开源共建,现已上线!
1062 36
|
12天前
|
机器学习/深度学习 人工智能 搜索推荐
万字长文深度解析最新Deep Research技术:前沿架构、核心技术与未来展望
近期发生了什么自 2025 年 2 月 OpenAI 正式发布Deep Research以来,深度研究/深度搜索(Deep Research / Deep Search)正在成为信息检索与知识工作的全新范式:系统以多步推理驱动大规模联网检索、跨源证据。
821 56
|
10天前
|
文字识别 测试技术 开发者
Qwen3-VL新成员 2B、32B来啦!更适合开发者体质
Qwen3-VL家族重磅推出2B与32B双版本,轻量高效与超强推理兼备,一模型通吃多模态与纯文本任务!
710 11
|
3天前
|
人工智能 数据可视化 Java
Spring AI Alibaba、Dify、LangGraph 与 LangChain 综合对比分析报告
本报告对比Spring AI Alibaba、Dify、LangGraph与LangChain四大AI开发框架,涵盖架构、性能、生态及适用场景。数据截至2025年10月,基于公开资料分析,实际发展可能随技术演进调整。
286 4
下一篇
开通oss服务