Java Web简明教程–Java篇[12]–使用连接池的MySQL操作类

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: Java Web简明教程–Java篇[12]–使用连接池的MySQL操作类

前面我们演示了一个简单的数据库连接池,我们再结合之前的mysql数据库操作类MysqlHandler修改一下,实现一个使用连接池的mysql操作类。


首先,我们先得有一个自定义的异常类,猫哥主要想用它演示下抛出特定异常。


package sql;//Java中的类可以用不同的package(包)划分,这样更加条理
public class MysqlException extends Exception{//自定义异常类,因为继承了Exception类,所以成为了异常家族的一员
  public MysqlException(String msg){//构造函数,包含一条消息,此处我们简单的以消息内容区分不同的数据库异常
  super(msg);
  }
}


注意本篇中所有的类都是在package sql下的,也就是在包sql下。如果把类比做文件,那包就是文件夹——整理类的作用,如此而已。


OK,然后我们稍微改造下我们的数据库连接池类如下:


package sql;
import java.sql.*;//这个java.sql和上面自定义的sql是一回事。名字都不一样嘛,一个叫java.sql一个叫sql。就像李老四和李四是两个人名。
import java.util.LinkedList;
public class MysqlPool {
  //使用static保证全局共享一个池子,使用LinkedList是因为经常删除、添加元素
    private static LinkedList pool = new LinkedList(); 
    //最大连接数
    private static int maxCount=20;
    static{//此处修改为使用静态代码块实现数据库连接池初始化,注意静态代码块中的语句只会执行一次,且在类初始化时候执行
      //下面的代码无需捕获异常,因为准备在MysqlHandler中捕获数据库异常
      for(int i=0;i
    MysqlHandler handler=new MysqlHandler();//此处借用MysqlHandler获取数据库连接,为啥借用?因为MysqlHandler干这些事比较方便
    //建立连接,并放于池中,不用担心这个连接找不到了,因为已经是池中之物了
    //此处应该注意,因为connection是要放入池中的,所以此处buildConnection建立的connection不用再依赖MysqlHandler类管理connection的释放问题
            Connection connection = handler.buildConnection();
            pool.add(connection);//所有连接都非常保险的在pool中放置,随时可以取用
        }    
    }
    public static Connection getConnecton() throws MysqlException{//此处将异常抛出,在外面处理。也可以选择在getConnecton内部处理,看程序员决策了
      if(pool.size()==0)//分配完了
      {
      throw new MysqlException("数据库连接池资源短缺,无连接可分配");
      }
      else{
      return pool.remove(0);//删除第一个对象并返回
      }
    }
    public static void release(Connection connection){//使用完的归还给池子
        pool.add(connection);
    }
}

需要注意两点:1是静态代码块的使用,让整个程序不用再管理数据库连接池的初始化问题,相对于手工init()初始化所有连接,静态代码块在MysqlPool类第一次加载时自动调用显得更加的牛X。2是注意我们使用MysqlHandler 的buildConnection方法拿到连接,这个方法没有什么变化,也没有变化的必要,就是建立一个数据库连接。


OK,再来看我们封装的操作类:


package sql;
import java.sql.*;//导入数据库相关类库
/**
 * MysqlHandler MySQL数据库管理类,使用数据库连接池
 * @author 猫哥
 * @date 2016.1.9
 */
public class MysqlHandler{   
  //依然是那熟悉的三个必备参数
  private Connection conn = null;
  private Statement stmt = null;
  private ResultSet rs = null;
    //建立数据库连接,此处仅用于提供原始连接,供放入池中使用
    public Connection buildConnection() {        
      String driver = "com.mysql.jdbc.Driver";//MySQL数据库的驱动程序名
         String url = "jdbc:mysql://localhost:3306/java?useUnicode=true&characterEncoding=utf-8";//数据库连接字符串
         String user = "root";//用户名
         String password = "Pass1234";//密码
         try{   
          Class.forName(driver);//加载驱动程序
          conn=DriverManager.getConnection(url,user,password);//输入必备参数,获取连接   
         }
         catch(Exception ex){
          ex.printStackTrace();//可以输出比较详细的异常信息 
         }
        return conn;
    }
    //操作1,“增删改查”中,增、删、改都是执行sql语句,无需返回ResultSet结果集,所以设置为一个方法
    public int execute(String sql){
        try {
          conn=MysqlPool.getConnecton();//用时从池中取,很爽快
          stmt=conn.createStatement();
            int affectedCount = stmt.executeUpdate(sql);//此处真正执行stmt定义的操作
            return affectedCount;//这个是收到影响的行数
        }
        catch(MysqlException myEx){//可以针对自定义的异常单独处理
          myEx.printStackTrace();
          return -2;//返回-2,表示数据库连接池分配超限,可以在外面针对性处理,其实可以直接抛到更外层处理,还是看程序员决策了
        }
        catch (Exception ex) {
            ex.printStackTrace();
            return -1;//返回-1,表示执行失败了,有异常
        }
    }
    //操作2,如果是查询,需返回结果集
    public ResultSet query(String sql)throws Exception{
      try{
         conn=MysqlPool.getConnecton();//用时从池中取,很爽快
         stmt=conn.createStatement();
         rs = stmt.executeQuery(sql);//执行pstmt中定义的查询
         return rs;//将结果集返回 
     }
      catch(MysqlException myEx){//可以针对自定义的异常单独处理
      throw new MysqlException(myEx.getMessage());//还可以往外抛,可以针对查询时数据库连接池连接不足问题单独处理(例如延迟响应用户请求以下)
        }catch(Exception ex){
          ex.printStackTrace();
      return null;
     }
    }
    //操作3,释放资源
    public void sayGoodbye(){
      //此处注意,conn在池中管理,此处无需关闭
        if(rs!=null){//关闭结果集,这个不关闭也浪费
            try {
                rs.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        if(stmt!=null){//关闭Statement,不要浪费
            try {
              stmt.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
  MysqlPool.release(conn);
    }
}

OK,最后,单独写一个测试类,测试以下:


package sql;
import java.sql.*;
public class SqlTest {
  public static void main(String[] args) throws Exception {//此处我们不处理异常
  // TODO Auto-generated method stub
   MysqlHandler hand=new MysqlHandler();  
      ResultSet rs=null;//可以使用多次
      //查
      rs=hand.query("select * from student_info");
         //展示结果
         System.out.println("\n查询结果如下:");
         while(rs.next()){
              System.out.print(rs.getInt(1) + "|");
              System.out.print(rs.getString(2) + "\t");
         }
         //增加2个
         int addCount=hand.execute("insert into student_info (student_name) values('火星人'),('水星人')");
         System.out.println("\n增加了"+addCount+"个");
         //删除一个
         int delCount=hand.execute("delete from student_info where student_name='张三'");
         System.out.println("\n删除了"+delCount+"个");
         //修改一个,把李四改造成火星人
         int changeCount=hand.execute("update student_info set student_name='火星人李四' where student_name='李四'");
         System.out.println("\n修改了"+changeCount+"个");
         //查
         rs=hand.query("select * from student_info");
         System.out.println("\n查询结果如下:");
         while(rs.next()){
             System.out.print(rs.getInt(1) + "|");
             System.out.print(rs.getString(2) + "\t");
         }
         hand.sayGoodbye();
  }
}
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
16天前
|
存储 安全 Java
java.util的Collections类
Collections 类位于 java.util 包下,提供了许多有用的对象和方法,来简化java中集合的创建、处理和多线程管理。掌握此类将非常有助于提升开发效率和维护代码的简洁性,同时对于程序的稳定性和安全性有大有帮助。
39 17
|
10天前
|
Java Maven Spring
Java Web 应用中,资源文件的位置和加载方式
在Java Web应用中,资源文件如配置文件、静态文件等通常放置在特定目录下,如WEB-INF或classes。通过类加载器或Servlet上下文路径可实现资源的加载与访问。正确管理资源位置与加载方式对应用的稳定性和可维护性至关重要。
|
8天前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
12天前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
52 4
|
12天前
|
存储 安全 搜索推荐
理解Session和Cookie:Java Web开发中的用户状态管理
理解Session和Cookie:Java Web开发中的用户状态管理
37 4
|
12天前
|
Java 编译器 开发者
Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面
本文探讨了Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面,帮助开发者提高代码质量和程序的健壮性。
29 2
|
15天前
|
XML 安全 PHP
PHP与SOAP Web服务开发:基础与进阶教程
本文介绍了PHP与SOAP Web服务的基础和进阶知识,涵盖SOAP的基本概念、PHP中的SoapServer和SoapClient类的使用方法,以及服务端和客户端的开发示例。此外,还探讨了安全性、性能优化等高级主题,帮助开发者掌握更高效的Web服务开发技巧。
|
17天前
|
存储 安全 Java
如何保证 Java 类文件的安全性?
Java类文件的安全性可以通过多种方式保障,如使用数字签名验证类文件的完整性和来源,利用安全管理器和安全策略限制类文件的权限,以及通过加密技术保护类文件在传输过程中的安全。
|
21天前
|
Java 数据格式 索引
使用 Java 字节码工具检查类文件完整性的原理是什么
Java字节码工具通过解析和分析类文件的字节码,检查其结构和内容是否符合Java虚拟机规范,确保类文件的完整性和合法性,防止恶意代码或损坏的类文件影响程序运行。
|
21天前
|
Java API Maven
如何使用 Java 字节码工具检查类文件的完整性
本文介绍如何利用Java字节码工具来检测类文件的完整性和有效性,确保类文件未被篡改或损坏,适用于开发和维护阶段的代码质量控制。