MyBatis :工厂类封装与简化

1.工厂类

在Java中,工厂类是一种设计模式,主要用于创建对象的过程。工厂类的目的是将对象的创建逻辑封装在一个类中,以便客户端代码无需了解具体的实现细节,只需要通过工厂类获取所需的实例。

工厂类的主要作用包括:

  1. 封装对象创建逻辑: 将对象的创建过程和细节封装在工厂类中,使客户端代码无需关心如何创建对象,降低了代码的耦合性。

  2. 统一接口: 工厂类提供了一个统一的接口或方法来创建对象,客户端代码只需要调用这个接口或方法,而无需关心具体的实现类。

  3. 简化实例化过程: 对于某些复杂的对象创建过程,工厂类可以隐藏创建对象的复杂性,简化了客户端代码。

  4. 灵活切换实现: 如果需要更改或替换某个类的实现,只需修改工厂类的实现,而无需修改客户端代码。这种方式支持更灵活的实现替换。

2.对工厂类再封装

这是我们之前的代码:

package Mybatis;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.List;

/**
 * 我们已经配置好了myBatis,当我们希望使用myBatis的时候,
 * 我们就会创建一个SqlSessionFactory类,在这个类里使用myBatis的各种功能。
 */
public class Main {
    public static void main(String[] args) throws FileNotFoundException {
        //寻找配置文件,参数就是配置文件的路径,这里是相对路径
        SqlSessionFactory sqlSessionFactory =
                new SqlSessionFactoryBuilder().build(new FileInputStream("myBatis_config.xml"));

        //sqlSession就像之前的statement一样,创建一个连接,执行sql语句,它也需要关闭,所以写进try
        //参数true代表开启自动提交,如果不自动提交,就类似与之前说的mysql的事务模式
        try (SqlSession sqlSession = sqlSessionFactory.openSession(true)){

            //这里的参数是mapper里指定的那个sql语句的名称
            //也就是UserMapper.xml里的id字段的名称
            List<User> student = sqlSession.selectList("selectUser");

            //这行代码使用了 Java 8 引入的新特性之一,称为方法引用(Method Reference)。
            // 具体来说,System.out::println 是一个静态方法引用,用于将 println 方法关联到 System.out 对象上。
            //在这里,System.out::println 等效于 lambda 表达式 (s) -> System.out.println(s)。
            // 它表示将遍历 student 集合的每个元素,并将每个元素传递给 System.out.println 方法,实现在控制台上打印每个元素的效果。
            student.forEach(System.out::println);
        }
    }
}

我们发现在之前的代码中,我们首先新建了一个工厂类,然后执行查询。

但是很这里的代码逻辑有些不清晰,我们希望的是  连接->查询

我们希望:

MybatisUtil.getSession(true)

而不是:

 SqlSessionFactory sqlSessionFactory =
                new SqlSessionFactoryBuilder().build(new FileInputStream("myBatis_config.xml"));

工厂类虽然封装对象创建逻辑,但在这里还有些臃肿,所以我们新建一个工具类,来封装这个工厂类。

package Mybatis;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.FileInputStream;
import java.io.IOException;


public class MyBatisUtil {
    private static SqlSessionFactory sqlSessionFactory;
    static {
        try{
            sqlSessionFactory=new SqlSessionFactoryBuilder().build(new FileInputStream("myBatis_config.xml"));
        }catch (IOException e){
            e.printStackTrace();
        }
    }
    /**
     * 获取一个新的会话
     * @param autoCommit 是否开启自动提交(跟JDBC是一样的,如果不自动提交,则会变成事务操作)
     * @return SqlSession对象
     */
    public static SqlSession getSession(boolean autoCommit){
        return sqlSessionFactory.openSession(autoCommit);
    }
}

在这段代码里,有一个静态段和静态变量。静态段和静态变量会在类加载的过程中执行,并且只执行一次。(无论你new多少个MyBatisUtil对象,都只会执行一i,不会重复执行)

这样的MyBatisUtil写法有几个好处:

  1. 单例模式: SqlSessionFactory 是一个比较重量级的对象,包含了对数据库的配置信息、映射信息等,创建和初始化它可能是一个相对耗时的操作。这样写确保在整个应用程序生命周期内只创建了一个 SqlSessionFactory 对象,提高了性能。

  2. 全局唯一性: SqlSessionFactory 对象在整个应用程序中是唯一的,保证了全局唯一性。这意味着在应用程序中的任何地方,都可以通过 MyBatisUtil 获取到相同的 SqlSessionFactory 实例。

  3. 资源共享: SqlSessionFactory 是一个比较重的资源,通过单例模式,可以确保所有的 SqlSession 对象都共享同一个 SqlSessionFactory。这样,在应用程序中多个地方需要访问数据库时,共享的 SqlSessionFactory 可以提高资源利用效率。

  4. 简化使用: 封装了 SqlSessionFactory 的创建过程,对客户端代码提供了简单的接口,通过 MyBatisUtilgetSession 方法,客户端可以方便地获取到一个新的 SqlSession 实例,而无需关心 SqlSessionFactory 的创建和初始化过程。

所以现在,我们的Main类变成了:

package Mybatis;

import org.apache.ibatis.session.SqlSession;

import java.util.List;

public class MainWithUtil {
    public static void main(String args[]){
        //用MyBatisUtil来包装之前MainWithoutUtil的工厂类,更简单地得到连接
        try(SqlSession sqlSession = MyBatisUtil.getSession(true)){

            //这里的参数是mapper里指定的那个sql语句的名称
            //也就是UserMapper.xml里的id字段的名称
            List<User> student = sqlSession.selectList("selectUser");

            //这行代码使用了 Java 8 引入的新特性之一,称为方法引用(Method Reference)。
            // 具体来说,System.out::println 是一个静态方法引用,用于将 println 方法关联到 System.out 对象上。
            //在这里,System.out::println 等效于 lambda 表达式 (s) -> System.out.println(s)。
            // 它表示将遍历 student 集合的每个元素,并将每个元素传递给 System.out.println 方法,实现在控制台上打印每个元素的效果。
            student.forEach(System.out::println);
        }
    }
}

  • 11
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值