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 编程中,单例模式是一种常见的设计模式,用于确保某个类仅有一个实例,并提供全局访问点。当涉及到数据库连接管理时,使用单例模式可以有效地控制资源消耗,减少频繁创建和销毁连接带来的性能开销。 #### 饿汉式单例模式实现 饿汉式单例模式会在类加载时立即初始化实例,因此它是线程安全的,但可能会浪费内存资源,尤其是在实例化成本较高的情况下。以下是基于 JDBC 的饿汉式单例模式实现: ```java public class JDBCSingleton { private static final JDBCSingleton instance = new JDBCSingleton(); private Connection connection; // 私有构造函数,防止外部实例化 private JDBCSingleton() { try { Class.forName("com.mysql.cj.jdbc.Driver"); this.connection = DriverManager.getConnection( "jdbc:mysql://127.0.0.1:3306/question?useUnicode=true&characterEncoding=utf8", "root", "123456" ); } catch (Exception e) { e.printStackTrace(); } } // 提供全局访问点 public static JDBCSingleton getInstance() { return instance; } // 获取数据库连接 public Connection getConnection() { return connection; } } ``` 此代码展示了如何通过静态变量 `instance` 和私有构造函数来实现单例模式[^2]。 --- #### 懒汉式单例模式实现 懒汉式单例模式会延迟实例化的时机,直到第一次调用 `getInstance()` 方法时才创建实例。为了保证线程安全性,通常需要使用同步机制(synchronized 关键字)。以下是一个典型的懒汉式单例模式实现: ```java public class LazyJDBCSingleton { private static volatile LazyJDBCSingleton instance = null; // 使用 volatile 确保可见性 private Connection connection; // 私有构造函数,防止外部实例化 private LazyJDBCSingleton() { try { Class.forName("com.mysql.cj.jdbc.Driver"); this.connection = DriverManager.getConnection( "jdbc:mysql://127.0.0.1:3306/question?useUnicode=true&characterEncoding=utf8", "root", "123456" ); } catch (Exception e) { e.printStackTrace(); } } // 双重检查锁定机制 public static LazyJDBCSingleton getInstance() { if (instance == null) { synchronized (LazyJDBCSingleton.class) { if (instance == null) { instance = new LazyJDBCSingleton(); } } } return instance; } // 获取数据库连接 public Connection getConnection() { return connection; } } ``` 在此示例中,双重检查锁定(Double-Checked Locking)技术被用来优化性能,同时保持线程安全性[^1]。 --- #### 枚举方式实现单例模式 枚举类型的单例模式被认为是最简单且最安全的方式之一,能够天然抵抗反射和序列化攻击。以下是基于枚举的单例模式实现: ```java public enum EnumSingleton { INSTANCE; private Connection connection; EnumSingleton() { try { Class.forName("com.mysql.cj.jdbc.Driver"); this.connection = DriverManager.getConnection( "jdbc:mysql://127.0.0.1:3306/question?useUnicode=true&characterEncoding=utf8", "root", "123456" ); } catch (Exception e) { e.printStackTrace(); } } public Connection getConnection() { return connection; } } ``` 这种实现方式不仅简洁明了,而且完全不需要额外的同步逻辑即可保证线程安全[^3]。 --- ### 最佳实践建议 1. **选择合适的单例模式变体**:如果应用程序启动时间不敏感,推荐使用饿汉式;对于按需加载场景,优先考虑懒汉式或枚举方式。 2. **异常处理**:始终捕获可能抛出的 SQLException 或 ClassNotFoundException 并记录日志以便调试。 3. **资源释放**:尽管单例模式减少了重复创建连接的成本,但仍应合理关闭不再使用的连接以避免泄漏。 4. **配置文件支持**:将数据库 URL、用户名和密码存储到独立的配置文件中而非硬编码于源码内[^4]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值