ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是threadlocalvariable(线程局部变量)。线程局部变量其实功能很简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是java中一种较为特殊的线程绑定机制,是每一个线程都可以独立地改变自己的副本,而不会和其他线程的副本冲突。数据之间不会共享
下面举一个例子,我们用threadLocal 和 list作为比较
package com.atshiyou;
import java.util.ArrayList;
import java.util.List;
public class TestThread {
private ThreadLocal threadLocal = new ThreadLocal();
private List list = new ArrayList();
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的set存值的方法
Thread.currentThread(); 表示获取当前的线程 —— t,线程不同,获取的t就不同,后续的操作就是判断map是否为空,为空就创建,不为空就直接插入值。因为获取到的是当前的线程,并对当前线程的值就行操作,所以说,不同线程之间的数据不会共享
编写一个获取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 threadLocal = new ThreadLocal();
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的值,怎么获取呢?
我们在mapper的xml配置文件中
获取的结果:
在控制台中,可以查看SQL语句的语法和赋值操作是否正确
1、添加对应的依赖包
org.slf4j
slf4j-api
1.7.5
org.slf4j
slf4j-log4j12
1.7.12
log4j
log4j
1.2.17
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
运行测试