关于SqlSession关闭的问题

关于SqlSession关闭的问题

对于视频中的SqlSession关闭,老师请问我的理解对吗?

我的理解:

在选择查看每个用户的信息时

http://img1.sycdn.imooc.com//climg/5d033f6200011db704290389.jpg

都会去访问UsersFindByIdServlet这个Servlet

http://img1.sycdn.imooc.com//climg/5d033f7d0001cd1611440620.jpg

然后,在UsersFindByIdServlet里,有一个usersDAO对象

因为我们在第一次查看用户信息的时候,调用了usersDAO对象的findById方法,然后这个方法最后会关闭

SqlSession,导致第二次查看其它用户的时候,没办法使用usersDAO中的SqlSession对象,也就没办法从数据库中查询其它用户的数据,

所以我们后来才把获取SQLSession定义成getSqlSession()这个方法来获取

http://img1.sycdn.imooc.com//climg/5d03406400018f6312200159.jpg

这样每次调用findById方法时,都会去重新获取一个SQLSession对象,就不会担心SQLSession被关闭了

请问我的理解对吗??

2:

老师,我想知道,Servlet类(如UsersFindByIdServlet
)是在web程序启动的时候就会创建,然后一直存在,直到服务器关闭才销毁吗?

如果是的话,那在UsersFindByIdServlet类中的usersDAO对象,是不是也就只跟着UsersFindByIdServlet一起存在呢?就是也只创建一次usersDAO对象呢?

正在回答

登陆购买课程后可参与讨论,去登陆

3回答

       同学你好,

       查看源码,使用ThreadLocal类,定义时需要传入变量。

       http://img1.sycdn.imooc.com//climg/5d037637000146b003120043.jpg

       当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。 

       这里是为每一个线程都提供一个SqlSession的变量副本。

       http://img1.sycdn.imooc.com//climg/5d0376240001613404650032.jpg

        当关闭SqlSession时,执行ThreadLocal.get()方法,各线程从自己的map中(存储变量副本的地方)取出放进去的对象,取出来各自线程中的对象进行关闭。
        如果我的回答解决了你的疑惑,请采纳。祝:学习愉快~

提问者 MasonM 2019-06-14 16:55:10
package com.mason.utils;

import com.mysql.cj.Session;
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.IOException;
import java.io.InputStream;

public class SqlSessionFactoryUtils {
    private static String RESOURCE="mybatis-config.xml";
    private static SqlSessionFactory sqlSessionFactory;
    private static ThreadLocal<SqlSession> threadLocal=new ThreadLocal<SqlSession>();

    /**
     * 创建一个初始化SqlSessionFactory的方法
     */
    public static void initSqlSessionFactory() {
        try {
            InputStream is = Resources.getResourceAsStream(RESOURCE);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取工厂对象的方法
     * @return
     */
    public static SqlSessionFactory getSqlSessionFactory() {
        return sqlSessionFactory;
    }

    /**
     * 关闭SqlSession的方法
     */
    public static void close() {
        SqlSession session=threadLocal.get();
        if (session != null) {
            session.close();
            threadLocal.set(null);
        }
    }
}

里面的

private static ThreadLocal<SqlSession> threadLocal=new ThreadLocal<SqlSession>();

有啥用呢?

为啥只是在关闭SqlSession的方法中才用到呢?

而且我也没看到threadLocal对象获取到了SqlSession呀,为什么能从threadLocal中获取到SqlSession对象呢?

吃吃吃鱼的猫 2019-06-14 16:47:40

       同学你好,

       1、理解正确。

       2、首先Servlet实例为一个单例对象,从头到尾只有一个,而其创建在于第一次被调用(第一次处理请求),这是一种默认行为。可以手动进行更改,修改web.xml配置文件:

<servlet>
   <load-on-startup>1</load-on-startup>
</servlet>

       通过增加<load-on-startup>1</load-on-startup>属性可以将servlet对象的创建修改为:服务器启动时就创建该对象。

       userDao对象存在于Servlet对象中,需要根据java内部的回收算法进行判断是否回收,不同的算法对此的判断不同,所以usersDao的创建次数不一定,同学目前还不用考虑这个呢~

       如果我的回答解决了你的疑惑,请采纳。祝:学习愉快~


  • 提问者 MasonM #1
    好的谢谢老师,老师我还想问一个问题,关于SqlSessionFactoryUtils类中的ThreadLocal<SqlSession> threadLocal=new ThreadLocal<SqlSession>();作用是啥?看新回答谢谢
    2019-06-14 16:53:34
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师