Mybatis框架之单例模式 (Singleton Pattern)

devtools/2024/11/23 12:48:30/

MyBatis 框架中也使用到了单例模式 (Singleton Pattern),主要体现在 SqlSessionFactory 的创建和管理上。通过单例模式,MyBatis 可以确保整个应用程序中只创建一个 SqlSessionFactory 实例,从而有效地管理数据库连接资源并提高性能。下面将详细介绍 MyBatis 中的单例模式的应用原理和实现方式。

1. 什么是单例模式 (Singleton Pattern)?

单例模式 是一种创建型设计模式,确保一个类在整个应用程序中只有一个实例,并提供一个全局访问点来访问该实例。这种模式通常用于需要被频繁访问且只能存在一个实例的对象,例如数据库连接池、线程池、配置管理器等。

单例模式的特点:

  • 唯一性:整个应用程序中只存在一个实例。
  • 全局访问:提供一个全局访问点供其他代码使用。
  • 延迟加载 (Lazy Initialization)(可选):可以在第一次使用时创建实例,从而节省资源。

2. MyBatis 中的单例模式应用

在 MyBatis 中,SqlSessionFactory 就是一个典型的单例模式的实现。SqlSessionFactory 是创建 SqlSession 对象的工厂,它负责解析 MyBatis 配置文件,并管理数据库连接资源。

2.1 为什么 SqlSessionFactory 需要单例模式
  • 性能考虑:创建 SqlSessionFactory 是一个相对耗时的操作,需要解析配置文件、初始化连接池等。因此,确保 SqlSessionFactory 只被创建一次,可以减少重复的资源开销,提高性能。
  • 资源管理:使用单例模式可以确保整个应用程序中只有一个 SqlSessionFactory 实例,从而有效地管理数据库连接资源。
  • 线程安全SqlSessionFactory 本身是线程安全的,可以在多个线程中安全地共享。

3. SqlSessionFactory单例模式实现

通常,我们会通过封装一个工具类来实现 SqlSessionFactory单例模式。下面是一个基于单例模式SqlSessionFactory 实现示例:

3.1 MyBatis 配置文件 (mybatis-config.xml)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mydatabase"/><property name="username" value="root"/><property name="password" value="password"/></dataSource></environment></environments><mappers><mapper resource="com/example/mapper/UserMapper.xml"/></mappers>
</configuration>
3.2 创建单例模式MyBatisUtil 工具类
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;public class MyBatisUtil {// 静态变量,用于存储唯一的 SqlSessionFactory 实例private static SqlSessionFactory sqlSessionFactory;// 私有构造函数,防止外部实例化private MyBatisUtil() {}// 获取 SqlSessionFactory 的方法public static SqlSessionFactory getSqlSessionFactory() {if (sqlSessionFactory == null) {synchronized (MyBatisUtil.class) {if (sqlSessionFactory == null) {try {String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);} catch (Exception e) {e.printStackTrace();}}}}return sqlSessionFactory;}
}
3.3 使用 MyBatisUtil 获取 SqlSession
import org.apache.ibatis.session.SqlSession;
import com.example.mapper.UserMapper;
import com.example.model.User;
import java.util.List;public class MyBatisExample {public static void main(String[] args) {// 通过单例模式获取 SqlSessionFactorySqlSessionFactory sqlSessionFactory = MyBatisUtil.getSqlSessionFactory();try (SqlSession session = sqlSessionFactory.openSession()) {// 获取 Mapper 接口的实现UserMapper userMapper = session.getMapper(UserMapper.class);// 调用方法执行 SQLList<User> users = userMapper.getAllUsers();users.forEach(user -> System.out.println(user.getName()));}}
}

4. 解析单例模式实现细节

  1. 私有化构造方法

    • 通过将构造函数设为 private,防止外部创建实例,从而确保类的唯一实例性。
  2. 双重检查锁 (Double-Checked Locking)

    • 使用 synchronized 关键字和双重检查锁机制确保 SqlSessionFactory 的线程安全。这可以避免在多线程环境下重复创建实例的问题。
  3. 延迟加载 (Lazy Initialization)

    • 只有在第一次调用 getSqlSessionFactory() 方法时,才会创建 SqlSessionFactory 实例,这样可以节省系统资源。

5. 单例模式的优缺点

优点:
  • 节省资源:避免重复创建 SqlSessionFactory 实例,节省内存和 CPU 资源。
  • 全局访问:提供了一个全局访问点,方便使用。
  • 线程安全:通过双重检查锁机制,可以确保在多线程环境下的安全性。
缺点:
  • 生命周期管理:由于单例对象在整个应用程序生命周期中都存在,可能会导致资源不能及时释放,从而增加内存消耗。
  • 不易测试单例模式会增加代码的耦合度,可能会给单元测试带来一定困难。

6. 总结

MyBatis 通过单例模式管理 SqlSessionFactory 的创建和访问,从而提高了系统性能并简化了数据库连接的管理。在实际项目中,SqlSessionFactory 通常是单例的,因为它是线程安全的,且创建过程相对耗时。

使用单例模式可以确保 SqlSessionFactory 只被创建一次,从而避免重复创建造成的资源浪费。这种设计模式在 MyBatis 的实际应用中非常常见,是数据库访问层优化的一个重要手段。


http://www.ppmy.cn/devtools/136294.html

相关文章

uView开发笔记

1.富文本框输入 <u-input input-alignright type"textarea" height"100" v-model"value" /> ​ return{textarea:textarea} 2.页面下拉刷新 onPullDownRefresh(){ } 3.swiper轮播图图片展示不全问题 增加属性&#xff1a; :img-mode&…

c与c++比较

实现将十六进制字符串转换为字节数组 c实现 - #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h>unsigned char* hexStringToByteArray(const char* hex_str, size_t* out_len) {size_t len = strlen(hex_str);size_…

原生微信小程序在顶部胶囊左侧水平设置自定义导航兼容各种手机模型

无论是在什么手机机型下&#xff0c;自定义的导航都和右侧的胶囊水平一条线上。如图下 以上图iphone12&#xff0c;13PRo 以上图是没有带黑色扇帘的机型 以下是调试器看的wxml的代码展示 注意&#xff1a;红色阔里的是自定义导航&#xff08;或者其他的logo啊&#xff0c;返回之…

气象指数推进光伏“靠天吃饭”?

随着可再生能源在电力系统中占比的不断提升&#xff0c;光伏发电“靠天吃饭”的特性引发看发电企业、用电企业及电网等主体对天气风险的关注。据小编所知&#xff0c;鹧鸪云光伏气象仿真系统采用Meteonorm作为气象数据源&#xff0c;真实可靠&#xff0c;助力新能源体系建设。 …

JavaWeb-表格标签-06

表格标签 table code: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>表格标签</title><…

TCP 三次握手和四次挥手

一、三次握手 (Three-Way Handshake) 概念&#xff1a; 三次握手用于在 TCP 连接建立时&#xff0c;确保客户端和服务器之间的通信信道可靠&#xff0c;并同步双方的初始序列号。 三次握手过程 第一次握手&#xff1a;客户端向服务器发送 SYN (synchronize) 报文&#xff0c;…

yolo基础---Labelimg工具安装与使用

前言 今后的一段时间&#xff0c;会慢慢更新yolo的使用&#xff0c;基础版本以yolov5为主&#xff0c;选yolov5主要是这个很经典&#xff0c;比较适合入门&#xff0c;后面会重点更新yolov10的使用与创新 文章目录 1、安装1、labelimg工具介绍2、labelimg工具下载3、安装 2、使…

Kafka 2.8 源码导读

Kafka 是一个分布式流处理平台&#xff0c;广泛用于实时数据流的处理和传输。Kafka 2.8 版本引入了一些新特性和改进。 以下是 Kafka 2.8 源码的导读&#xff0c;帮助你理解其核心组件和实现机制。 1. 源码结构 Kafka 的源码主要分布在以下几个模块中&#xff1a; clients/…