一.解决JDBC存在的问题
1.获取连接、得到statement、处理rs、关闭资源非常繁琐。
- 解决:使用SqlSession搞定一切
2.将sql语句写死到java代码中,如果修改sql语句,须要修改java代码,须要重新编译。程序可维护性不高。
- 解决:将Sql语句配置在Mapper.xml文件中与java代码分离。
3.向PreparedStatement对占位符的位置设置参数时,非常繁琐。
- 解决:Mybatis自动将java对象映射至sql语句,通过statement中的parameterType定义输入参数的类型。
4.解析结果集时需要把字段的值设置到相应的实体类属性名中。
- 解决:Mybatis自动将sql执行结果映射至java对象,通过statement中的resultType定义输出结果的类型。
二.封装工具类
1.初步封装
public class SqlSessionUtil {
private SqlSessionUtil(){}
private static SqlSessionFactory factory;
static{
//Resources:Resources 的作用是读取 Mybatis 核心配置文件,读取的方式是使用IO 流,这样的方式只执行一次就可以了。
String resource = "mybatis-config.xml";
InputStream inputStream = null;
try {
//通过加载MyBatis的主配置文件mybatis-config.xml,创建输入流
inputStream = Resources.getResourceAsStream(resource);
} catch (IOException e) {
e.printStackTrace();
}
/*
* SqlSessionFactoryBuilder是SqlSessionFactory的建造者
* 通过该建造者对象调用建造方法,为我们创建一个SqlSessionFactory对象
* SqlSessionFactory对象唯一的作用就是为我们创建SqlSession对象
* */
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//我们未来的所有操作,使用的都是SqlSession对象session来完成
SqlSession session = sqlSessionFactory.openSession();
}
}
- Resources:Resources 的作用是读取 Mybatis 核心配置文件,读取的方式是使用IO 流,这样的方式只执行一次就可以了。
SqlSessionFactory : SqlSessionFactory 是 SqlSession的工厂。这个是重量级资源,内存占用比较大。是一个线程安全的。
SqlSession : 作用是翻译接口的实现类代码,代替了 JDBC 中的 Connection 对象,需要控制事务。是一个线程不安全的,需要进行线程绑定 ThreadLocal 绑定 。
2.完善:
package com.tx.crm.utils;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class SqlSessionUtil {
private static SqlSessionFactory factory;
static{
String resource = "mybatis-config.xml";
InputStream inputStream = null;
try {
//通过加载MyBatis的主配置文件mybatis-config.xml,创建输入流
inputStream = Resources.getResourceAsStream(resource);
} catch (IOException e) {
e.printStackTrace();
}
factory = new SqlSessionFactoryBuilder().build(inputStream);
}
//ThreadLocal创建本地线程,每一个线程都有自己的副本。避免线程不安全
private static ThreadLocal<SqlSession> t = new ThreadLocal<SqlSession>();
//取得SqlSession对象
public static SqlSession getSession(){
//首先获取当前调用者线程,如果当前线程的threadLocals不为null,就直接返回当前线程绑定的本地变量值
SqlSession session = t.get();
if(session==null){
session = factory.openSession();
t.set(session);
}
return session;
}
//关闭SqlSession对象
public static void myClose(SqlSession session){
if(session!=null){
session.close();
//这句必须加,非常容易忘记,如果不加可能会存在数据混乱
t.remove();
}
}
}