介绍Java单例模式,附加小案例:使用单例模式的饿汉式封装Mybatis的 SqlSessionFactory会话工厂

1 篇文章 0 订阅
1 篇文章 0 订阅

什么是单例模式

单例模式:
指在整个应用中只有一个实例
满足条件:
1.构造方法私有化,为了避免外部通过new来创建对象。
2.提供静态方法,用于返回本类的一个实例。
3.在类的内部,声明一个本类的实例,如果实例为null,则创建,否则返回。
实现方式:
1.饱汉式:类的实例只有调用时才会创建。
2.饿汉式:类的实例在类的加载时直接创建。

记得引入相关依赖:mybatis mysql junit

创建SqlSessionFactoryUtils类(单例模式:饱汉式)

public class SqlSessionFactoryUtils {
    /**
     * 声明本类的实例
     */
    private  static  SqlSessionFactoryUtils instance = null;

    /**
     * 构造方法私有化
     */
    private  SqlSessionFactoryUtils(){

    }
      /**
     * 提供静态方法
     * 饱汉式:类的实例只有类在调用的时才会创建
     * @return 本类的实例
     */
     
    public  static SqlSessionFactoryUtils getInstance(){
        if (null == instance){
            instance   =  new SqlSessionFactoryUtils();
        }
        return instance;
    }
}

使用测试类来测试

   @Test
    public void testInstance(){
        SqlSessionFactoryUtils s1 = SqlSessionFactoryUtils.getInstance();
        SqlSessionFactoryUtils s2 = SqlSessionFactoryUtils.getInstance();
        System.out.println(s1  == s2);
    }

执行结果为true

执行流程
在饱汉模式下,实例在首次使用时创建,并在后续调用时重复使用。
执行流程如下:
1.首次调用getInstance()方法。
2.当前instance变量为null,进入if语句块。
3.在if语句块中,创建SqlSessionFactoryUtils的新实例,并将其赋值给instance变量。
3.返回instance对象。
4.后续再次调用getInstance()方法。
5.当前instance变量不为null,直接返回之前创建的instance对象。
通过这种方式,可以确保在整个应用程序生命周期中,只创建一个SqlSessionFactoryUtils的实例,供全局使用。这种单例模式的实现方式适用于无需考虑多线程并发访问的情况下。如果需要考虑线程安全性,可以在getInstance()方法中添加同步控制,或者使用其他单例模式的实现方式,如双重检查锁定模式、静态内部类模式等。

创建SqlSessionFactoryUtils2类(单例模式:饿汉式)

public class SqlSessionFactoryUtils2 {

    /**
     * 声明本类的实例
     */
    private  static  SqlSessionFactoryUtils2 instance  = null;

    /**
     * 静态代码块,类在加载的时候首先执行静态代码块
     * 饿汉式:类的实例在类的加载时直接创建。
     */
    static {
        instance = new SqlSessionFactoryUtils2();
    }
    /**
     * 构造方法私有化
     */
  private  SqlSessionFactoryUtils2(){}


    /**
     * 提供静态方法,返回本类的实例
     */
    public  static SqlSessionFactoryUtils2  getInstance(){
        return instance;
    }
}

使用测试类来测试

@Test
    public  void testInstance2(){
        SqlSessionFactoryUtils2 s1 =SqlSessionFactoryUtils2.getInstance();
        SqlSessionFactoryUtils2 s2 =SqlSessionFactoryUtils2.getInstance();
        System.out.println(s1 == s2);

    }

执行结果为true

在饿汉模式下,实例在类加载时就被创建,无论是否被使用。
执行流程如下:
1.类加载时,创建SqlSessionFactoryUtils2的静态变量instance,并将其实例化。
2.静态变量instance被赋初值,即创建了SqlSessionFactoryUtils2的实例。
3.调用getInstance()方法。
4.直接返回之前创建的instance对象,由于实例已经在类加载时被创建,因此无需再次创建。
由于在类加载时就创建了实例,所以无论后续是否使用该实例,都会存在于内存中。这种实现方式适用于在应用程序启动时就需要创建好的实例,且无需考虑多线程并发访问的情况。需要注意的是,饿汉式实现可能会造成资源浪费,因为实例在类加载时就被创建,无论是否被使用。因此,在某些场景下可能更适合使用懒汉式实现方式。

附加小案例:使用单例模式的饿汉式封装Mybatis的 SqlSessionFactory会话工厂

创建SqlSessionFactory会话工厂封装类 FactoryUtils

public class FactoryUtils {
    /**
     *声明本来的实例
    */
    private  static  FactoryUtils instance;
    private  static  SqlSessionFactory sqlSessionFactory;
    /**
     *静态代码块
    */
    static {
        instance = new FactoryUtils();
    }
       /**
     *构造方法
     */
    private FactoryUtils(){
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        InputStream is = this.getClass().getClassLoader().getResourceAsStream("mybatis-config.xml");
        sqlSessionFactory = builder.build(is);
        }

    /**
     *
     * @return 返回会话工厂
     */
    public static  SqlSessionFactory sqlSessionFactory(){
        return  sqlSessionFactory;
    }

}

代码执行流程如下:
1.创建FactoryUtils类。
2.声明静态变量instance和sqlSessionFactory。
3.在静态代码块中,将instance实例化为FactoryUtils的新实例。
4.在构造方法中,创建SqlSessionFactoryBuilder对象,用于构建SqlSessionFactory实例。
5.使用类加载器获取mybatis-config.xml配置文件的输入流。
6.使用SqlSessionFactoryBuilder的build()方法,根据配置文件的输入流创建SqlSessionFactory实例,赋值给sqlSessionFactory变量。
7.提供静态方法sqlSessionFactory(),用于返回静态变量sqlSessionFactory。

基础的mybatis-config.xml配置

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <!-- 开启日志 -->
        <setting name="logImpl" value="STDOUT_LOGGING" />
    </settings>
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
      <!--更改value值,或者自己加入db.properties文件配置数据库链接-->
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>
  </environments>
  <mappers>
    <!--用来指定Mapper.xml配置文件的位置,根据需求更改-->
    <mapper resource="org/mybatis/example/BlogMapper.xml"/>
  </mappers>
</configuration>

mybatis-config.xml详细配置请参考mybatis官网:https://mybatis.org/mybatis-3/zh/index.html

创建Mapper接口

public interface DbMapper {

    @Select("select * from  t_student where id = #{id}")
    public Map  getById(int id);

}

创建TestStudent测试类

public class TestStudent {
    @Test
    public void  getById(){
     try (SqlSession sqlSession = FactoryUtils.sqlSessionFactory().openSession()){
         DbMapper dbMapper = sqlSession.getMapper(DbMapper.class);
         System.out.println(dbMapper.getById(2));
     }
    }
}

测试运行结果如图:
运行结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值