jdbc设计模式之单例模式

单例模式

作为一种常见的设计模式,单例模式的设计概念是"两个私有,一个公有",即私有属性/成员变量和私有构造,以及公有方法,常用于在整个程序中仅调用一次的代码。

具体操作

描述

从单例模式的描述来看,单例模式并不能用于多次频繁调用的设计中,而更适用于程序开头,用于读取资源作启动作用的设计,在这里我们使用读取数据库的使用实例做例子。

例代码

package com.mannoroth.utils;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;




public class ConfigManager {
    //创建私有属性及成员变量
    private static ConfigManager configManager;
    private static Properties properties ;
    //创建私有构造
    private ConfigManager(){
        InputStream is = null;
        try {
                        //创建·properties·做Properties对象
            properties = new Properties();
            is =  ConfigManager.class.getClassLoader().getResourceAsStream("database.properties");
            properties.load(is);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            try {
                if (is != null) {
                    is.close();
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    //公有方法,开启一个口使外部程序得以调用
    public static ConfigManager getInstance(){

        if (configManager == null) {
            configManager = new ConfigManager();
        }
        return configManager;
    }
    //通过输入key的值,从文件中获得对应的值
    public static String getValues(String key){

        return properties.getProperty(key);
    }
}

单例模式的公有方法存在两个模式,分别为:

1.懒汉模式

//在第一次调用的使用(configManager==null),使自己实例化
public static synchronized ConfigManager getInstance(){

            if (configManager==null) {
                configManager=new ConfigManager();
            }

        return configManager;
    }
上述模式存在缺点,当该模式被多线程同时使用的时候,有可能会因此出现混乱,使两者交错,这时候我们可以通过使用再添加一重锁定(synchronized)的属性来保证线程安全。

解决方法:使用双重锁定

//在方法调用中再加入一重synchronized属性
public static synchronized ConfigManager getInstance(){
        synchronized (ConfigManager.class) {
            if (configManager==null) {
                configManager=new ConfigManager();
            }
        }
        return configManager;
    }

2.饿汉模式

public static ConfigManager getInstance(){
        if (configManager==null) {
            configManager=new ConfigManager();
        }
        return configManager;
    }
饿汉模式在创建的同时就提供了一个静态对象供程序调用,不会再发生变化,足矣保证现成安全。

两种模式的区别:

饿汉模式:类一旦加载,就把单例初始化完成,保证getInstance的时候,单例是已经存在 
懒汉模式:只有当调用getInstance的时候,才会去初始化这个单例。
在企业级开发中,为了高效管理数据库连接这一宝贵且耗时的资源,可基于JDBC设计开发单例模式的数据库连接池程序。以下是实现步骤及示例代码: ### 实现思路 - **资源池模式与单例模式结合**:使用资源池模式在内存中统一管理数据库连接,同时利用单例模式确保整个应用中只有一个数据库连接池实例,从而节省内存和资源,提高性能,也有利于Java垃圾回收 [^1][^5]。 - **单例模式设计**:创建一个类来表示数据库连接池,该类包含一个私有构造函数,防止外部直接实例化;一个私有静态实例,作为自身的单一实例;一个公共静态方法,允许外部获取这个静态实例 [^4]。 ### 代码示例 ```java import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; // 数据库连接池类 public class DatabaseConnectionPool { // 私有静态实例 private static DatabaseConnectionPool instance; // 连接池 private List<Connection> connectionPool; // 数据库连接信息 private String dbUrl; private String dbUser; private String dbPassword; // 私有构造函数 private DatabaseConnectionPool() { connectionPool = new ArrayList<>(); dbUrl = "jdbc:mysql://localhost:3306/mydatabase"; dbUser = "root"; dbPassword = "password"; init(); } // 初始化连接池 private void init() { try { // 加载驱动 Class.forName("com.mysql.cj.jdbc.Driver"); // 初始化一定数量的连接 for (int i = 0; i < 5; i++) { Connection connection = DriverManager.getConnection(dbUrl, dbUser, dbPassword); connectionPool.add(connection); } } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); } } // 公共静态方法,获取单例实例 public static DatabaseConnectionPool getInstance() { if (instance == null) { instance = new DatabaseConnectionPool(); } return instance; } // 从连接池获取连接 public Connection getConnection() { if (!connectionPool.isEmpty()) { return connectionPool.remove(0); } return null; } // 将连接放回连接池 public void releaseConnection(Connection connection) { connectionPool.add(connection); } } ``` ### 使用示例 ```java public class Main { public static void main(String[] args) { // 获取连接池实例 DatabaseConnectionPool pool = DatabaseConnectionPool.getInstance(); // 从连接池获取连接 Connection connection = pool.getConnection(); if (connection != null) { try { // 执行数据库操作 System.out.println("成功获取连接,进行数据库操作..."); // 操作完成后释放连接 pool.releaseConnection(connection); } catch (Exception e) { e.printStackTrace(); } } } } ``` ### 代码解释 - `DatabaseConnectionPool` 类使用单例模式,通过私有构造函数和公共静态方法 `getInstance()` 确保只有一个实例。 - `init()` 方法负责加载数据库驱动并初始化一定数量的连接。 - `getConnection()` 方法从连接池中获取连接,`releaseConnection()` 方法将使用完的连接放回连接池。 ### 注意事项 - 上述代码只是一个简单示例,实际应用中可能需要考虑连接池的动态扩展、连接的有效性检查等问题。 - 不同的数据库驱动和版本可能需要调整驱动类名和连接URL。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值