【MyBatis】使用说明:SqlSessionFactory+SqlSession

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/coralime/article/details/88988133

【问题描述】

单独使用了MyBatis框架,没有结合Spring框架,单独在SQL server Manager中查询数据的时候反应很快,但是在程序中查询特别慢,总是卡在查询的准备阶段。数据库那边能看到创建了很多个连接没有及时释放掉。

【分析原因】

上网查询了一些资料,一部分可能是查询语句本身的查询效率问题,一部分是MyBatis链接数据库的时候SqlSessionFactory创建了多个链接或者SqlSession没有及时关闭。

【解决方法】

1. 将创建SqlSessionFactory的方式改成单例模式,即只允许有且只有一个SqlSessionFactory实例存在。

2. SqlSession一旦创建需要及时关闭。

#-1->SqlSessionFactory的两种创建方式

#-1.1->静态模式创建SqlSessionFactory

单独创建一个名为【SessionFactory.java】文件。

放在static静态块中执行的代码只会执行一次,保证只创建了一个SqlSessionFactory。

package com.demo.tools;

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

import java.io.Reader;

public class DBtools {

    public static SqlSessionFactory sessionFactory;

    static {
        try{
            //配置文件地址
            String resources = "com/demo/confg/mybatisconfg.xml";
            //使用MyBatis提供的Resources类加载mybatis的配置文件
            Reader reader = Resources.getResourceAsReader(resources);
            //构建sqlSession的工厂
            sessionFactory = new SqlSessionFactoryBuilder().build(reader);

            System.out.println("静态创建了一次SqlSessionFactory!");
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    //创建能执行映射文件中sql的sqlSession
    public static SqlSession getSession()
    {
        return sessionFactory.openSession();
    }
}

#-1.2->单例模式创建SqlSessionFactory

单独创建一个名为【SessionFactory.java】文件。

package com.slspt.tools;

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

import java.io.Reader;

public class SessionFactory {

    private static SqlSessionFactory sqlSessionFactory;

    private static SqlSessionFactory getSqlSessionFactory(){
        //采用单例模式创建SqlSessionFactory
        if(sqlSessionFactory == null){
            try{
                //配置文件地址
                String resources = "com/slspt/confg/mybatisconfg.xml"; 
                //使用MyBatis提供的Resources类加载mybatis的配置文件
                Reader reader = Resources.getResourceAsReader(resources);
                //构建sqlSession的工厂
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
                System.out.println("创建了一个sessionFactory!");
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        return sqlSessionFactory;
    }

    //创建能执行映射文件中sql的sqlSession
    public static SqlSession getSession()
    {
        return getSqlSessionFactory().openSession();
    }
}

 #-2->SqlSession创建以后必须关闭

创建一个Service类来管理数据操作,注意session.commit() session.rollback() session.close()分别放在try-catch-finally块中

package com.services.Service;

import com.beans.DataBean;
import com.mappers.Mapper;

import com.tools.SessionFactory;
import org.apache.ibatis.session.SqlSession;

import java.util.ArrayList;

public class Service {

    private SqlSession session;
    private Mapper mapper;

    public Service() {
        super();
        session = SessionFactory.getSession();
        this.mapper = session.getMapper(Mapper.class);
        System.out.println("创建了一个session链接!^_^");
    }

    public ArrayList<DataBean> selectAllCity(String DateString){

        ArrayList<DataBean> listdata = new ArrayList<>();
        session = SessionFactory.getSession();
        try{
            listdata = mapper.selectAllCity(DateString);
            session.commit();
            System.out.println("session提交!");
        }catch (Exception e){
            e.printStackTrace();
            session.rollback();
        }finally {
            session.close();
            System.out.println("session关闭!");
        }

        return listdata;
    }

}

#-3->Bug记录:

Cause:org.apache.ibatis.executor.ExcutorException: Executor was closed.

原因:使用了已经关闭的session!通过打印输出可以看见session关闭的情况下,还在打印输出session关闭。 

 出现这种情况的原因是service里面一个session对应有多个Mapper:

构造函数中:

    this.session = SessionFactory.getSession();
    this.mapper = session.getMapper(YKSaleMapper.class);
    this.datemapper = session.getMapper(YKSaleDateMapper.class);

解决办法:注意每个单独的函数给session初始化一遍,添加如下代码(如果单独 一个session对一个Mapper文件,加不加无所谓)

session = SessionFactory.getSession(); 

  public ArrayList<String> getOperatorList(String Branch_no,String salechannel){
        ArrayList<String> operatorList = new ArrayList<String>();
        //每次给session初始化,避免出现bug【Executor was closed.】
        session = SessionFactory.getSession(); 
        //去数据库取list
        try{
            operatorList = mapper.selectDistOperator(Branch_no,salechannel);
            session.commit();
            System.out.println("session提交!");
        }catch (Exception e){
            e.printStackTrace();
            session.rollback();
        }finally {
            session.close();
            System.out.println("session关闭!");
        }
        return operatorList;
    }

完整代码如下:

package com.sys.dao;

import com.sys.beans.PremiumBean;
import com.sys.beans.YKSaleBean;
import com.sys.mapper.YKSaleDateMapper;
import com.sys.mapper.YKSaleMapper;
import com.sys.tools.SessionFactory;
import org.apache.ibatis.session.SqlSession;

import java.util.ArrayList;
import java.util.HashMap;

public class YKSaleCityDao {

    private SqlSession session;
    private YKSaleMapper mapper;
    private YKSaleDateMapper datemapper;

    //构造函数
    public YKSaleCityDao(){
        super();
        this.session = SessionFactory.getSession();
        this.mapper = session.getMapper(YKSaleMapper.class);
        this.datemapper = session.getMapper(YKSaleDateMapper.class);
    }

    private PremiumBean selectWithLike(String salechannel){

        PremiumBean data = new PremiumBean();
        //给session初始化避免出现使用已经关闭的session问题
        session = SessionFactory.getSession();
        try{

            data = mapper.selectWithLike(salechannel);
            session.commit();
            System.out.println("session提交!");
        }catch (Exception e){
            e.printStackTrace();
            session.rollback();
        }finally {
            session.close();
            System.out.println("session关闭!");
        }
        return data;
    }

    //返回需要展示的list数据
    public ArrayList<YKSaleBean> getUIList(String salechannel){

        ArrayList<YKSaleBean> listdata = new ArrayList<YKSaleBean>();

        for (int i = 0; i < insitutions.length; i++) {

            YKSaleBean bean = new YKSaleBean();

            //依次给Bean赋值

            //将bean添加到list中
            listdata.add(bean);
        }
        return listdata;
    }

}

猜你喜欢

转载自blog.csdn.net/coralime/article/details/88988133