KKB : 初始ThreadLocal、ThreadLocal实现的原理、threadLocal优化SQLsession、给类起别名、获得新增数据id、log4j显示SQL语句

ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是threadlocalvariable(线程局部变量)。线程局部变量其实功能很简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是java中一种较为特殊的线程绑定机制,是每一个线程都可以独立地改变自己的副本,而不会和其他线程的副本冲突。数据之间不会共享

 

下面举一个例子,我们用threadLocal 和 list作为比较

package com.atshiyou;

import java.util.ArrayList;
import java.util.List;

public class TestThread {
    private ThreadLocal<String> threadLocal = new ThreadLocal<String>();
    private List<String> list =  new ArrayList<String>();
    class A extends Thread{
        @Override
        public void run() {
            System.out.println("A线程开始存值");
            threadLocal.set("thread内容");
            System.out.println("A----->threadLocal="+threadLocal.get());
            list.add("list内容");
        }
    }
    class B extends Thread{
        @Override
        public void run() {
            try {
                Thread.sleep(1000);//让B先休眠,确保A存值成功
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("B线程开始取值");
            System.out.println("threadLocal="+threadLocal.get());
            System.out.println("list="+list.get(0));
        }
    }

    public static void main(String[] args) {
        TestThread testThread = new TestThread();
        TestThread.A a = testThread.new A();
        TestThread.B b = testThread.new B();
        a.start();
        b.start();
    }
}

 

如果threadLocal是线程共享的话,那么B线程在取值的时候,一定能取到值。

运行结果为:B线程取到的threadLocal为null,list的值却取到了。说明了threadLocal变量和list的区别。threadLocal保证了不同线程之间,资源不共享

 

 


ThreadLocal实现的原理?

查看ThreadLocal的set存值的方法

Thread.currentThread(); 表示获取当前的线程 —— t,线程不同,获取的t就不同,后续的操作就是判断map是否为空,为空就创建,不为空就直接插入值。因为获取到的是当前的线程,并对当前线程的值就行操作,所以说,不同线程之间的数据不会共享

threadLocal优化SQLsession

 

编写一个获取sqlsession的工具类

package com.atshiyou.util;

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.Reader;


public class SqlSessionUtil {
    // ThreadLocal管理SQLSession
    private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>();
    private static SqlSessionFactory sqlSessionFactory;

    // 配置文件只加载一遍
    static{
        try {
            Reader reader = Resources.getResourceAsReader("mybatis.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    //打开session方法
    public static SqlSession getSession(){
        //类似于单例的模式,获取sqlsession对象
        SqlSession session = threadLocal.get();
        if(session==null){
            session = sqlSessionFactory.openSession();
            threadLocal.set(session);
        }
        return session;
    }

    //关闭session
    public static void closeSession(){
        SqlSession session = threadLocal.get();
        if(session!=null) {
            session.close();
            threadLocal.remove();//清除数据
        }
    }
}

注意查看get的代码,使用的是单例模式的思想


给类起别名

需求,在mapper.xml文件映射中,我们删除了com这个包,那么我们是不是要修改很多的类名,有没有一种简单的方法可以实现删除包名的操作呢

我们可以给全类名起别名,在哪配置呢?

在mybatis.xml中配置

然后修改mapper.xml

我们还可以给包起别名,然后我们就使用类的小写就可以指定类

 


获得新增数据id

需求,在数据库中添加的数据的id是按照自增的方式进行的,我们添加数据的时候不需要添加数据的id,那么我们想获取添加的数据的id的值,怎么获取呢?

我们在mapper的xml配置文件中

获取的结果:

                       


log4j显示SQL语句

 

在控制台中,可以查看SQL语句的语法和赋值操作是否正确

1、添加对应的依赖包

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.5</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.12</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

2、创建log4j.properties

log4j.rootLogger=DEBUG, Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender 
log4j.appender.Console.layout=org.apache.log4j.PatternLayout 
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n 
 
log4j.logger.java.sql.ResultSet=INFO 
log4j.logger.org.apache=INFO 
log4j.logger.java.sql.Connection=DEBUG 
log4j.logger.java.sql.Statement=DEBUG 
log4j.logger.java.sql.PreparedStatement=DEBUG

 

运行测试

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你在狗叫什么、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值