在本篇中小编主要对SqlSession及Configuration重点介绍,这两块知识点可以说是Mybatis中最重要的知识点,只有对
SqlSession和Configuration有清醒的认识后,学习效率就翻倍提升。以下所有知识点都是小编所学所悟。如有问题,请留言评论指出,欢迎讨论,一起学习。
①SqlSession
②Configuration
Session是会话的意思,SqlSession名字就说明了这是一个Sql的会话。
单是从代码上来看,它就是负责和数据库操作的一个抽象接口。但是从概念上来说,就是类似于JDBC中的Connection。SqlSession它的底层封装了JDBC连接,可以用SqlSession实例来直接执行被映射的SQL语句.每个线程都应该有它自己的SqlSession实例.SqlSession的实例不能被共享
不过Mybatis的SqlSession比JDBC更加强大,能提供对象关系映射(ORM)的能力。同时也支持占位符,和动态Sql(容易出现sql注入问题,要注意)。
传统JDBC方式
比较繁琐要导入驱动,获取连接,要自己拼装sql。关闭连接。
但是比较快,因为不论是Mybatis还是Hibernate都是对原生JDBC的封装。
public class JdbcTest {
static {
try {//注册驱动,反射方式加载
Class.forName("com.mysql.jdbc.Driver");
}catch (Exception e){
}
}
@Test
public void jdbcTest()throws Exception{
String url = "jdbc:mysql://127.0.0.1:3306/test?useSSL=false";
//设置用户名
String username = "root";
//设置密码
String password = "root";
//获得连接对象
Connection con = DriverManager.getConnection(url, username, password);
//获得执行者对象
String sql = "select * from t_user where id = ?";
PreparedStatement ps = con.prepareStatement(sql);
ps.setInt(1,2);
//获得结果集
ResultSet rs = ps.executeQuery();
//结果集处理,
while(rs.next()){
System.out.println(rs.getString("id")+" "+rs.getString("name"));
}
//释放资源
rs.close();
ps.close();
con.close();
}
}
Mybatis方式
能提供对象关系映射(ORM)的能力。通过代理的方式,实现我们的Mapper接口层和xml配置文件的绑定,实现通过对象实例,操作数据库。(本篇不细讲,会在《深入浅出Mybatis系列(四)Mapper方法代理篇》主要做讲解)
@Test
public void dynamicTest() {
//读取配置信息
InputStream mapperInputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("mybatisConfig.xml");
//生成SqlSession工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(mapperInputStream, "development");
//获取Mybatis配置信息
Configuration configuration = sqlSessionFactory.getConfiguration();
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//获取Mapper
TUserMapper mapper = configuration.getMapperRegistry().getMapper(TUserMapper.class, sqlSession);
TUser tUser = mapper.selectOne(1);
System.out.println(tUser);
}
另外SqlSession还提供批处理的能力,和事务的能力。
什么场景用到批处理呢?
当要处理一批sql的时候,如果是一个sql一个sql的执行,那么每一条sql的执行都会有一次网络传输的过程,将sql从本台服务器发送到数据库服务器中。那么这种情况就时候就适合使用。原理就是通过BatchExecutor
批处理执行器处理,将要批处理的sql,一次发送到数据库服务器来执行。
/**
* 批处理测试
*/
@Test
public void batchTest() {
InputStream mapperInputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("mybatisConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(mapperInputStream);
//设置执行类型为批处理ExecutorType.BATCH,
SqlSession batchSqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
TUserMapper mapper = batchSqlSession.getMapper(TUserMapper.class);
//mapper批处理操作
//成功提交...
batchSqlSession.commit();
//失败回滚
batchSqlSession.rollback();
}
说道SqlSession一起把动态sql,和Sql注入问题给说一下。
所谓动态Sql就是Sql可以不直接写死,而是通过参数的方式,动态的去拼装Sql。
那这个时候就会用到两个技术。
eg:
这个时候用到的是占位符,name = “中国”。对于占位符MyBatis不直接处理而是交个JDBC来处理,利用PreparedStatement来设置动态参数,PreparedStatement可以预编译sql,可以sql缓存,同时可以有效防止sql注入。
String sql = "select * from t_user where name = ?";
PreparedStatement ps = con.prepareStatement(sql);
ps.setString(1,"中国");
这个时候,因为是变量符,Mybatis会直接处理生成Sql,入参是什么就拼装成什么,此时name就只是一个变量,可以被赋任何值,正常情况,不会出现问题,但是遇到恶意情况,当参数等于 name = "‘中国1’ or 1 = 1,此时一定就会查到,因为就变成or操作1永远等于1,这就是利用Mybatis动态生成Sql的特征,来注入恶意的sql。
这里注意一个知识点,$变量符,是由Mybatis实现的,#占位符是由JDBC原生实现的。
从上面介绍SqlSession的例子中能看到很多都是从Configuration中获取的信息,其实Configuration就是将配置文件转换成Java类。Mybatis中的一切都是从Configuration中来的,
包括TypeHandlerRegistry
类型注册器,拦截器InterceptorChain
,别名注册器TypeAliasRegistry
,Mapper注册器 MapperRegistry
。
上面所指出的类,都是核心处理的。从起名就能看出来他是干啥的。
比如
register(Boolean.class, new BooleanTypeHandler());
register(boolean.class, new BooleanTypeHandler());
register(JdbcType.BOOLEAN, new BooleanTypeHandler());
register(JdbcType.BIT, new BooleanTypeHandler());
"byte"<==> Byte.class
"_integer" <==> int.class
"int" <==> Integer.class
MapperRegistry是非常核心的实现,主要实现对象关系的映射,将xml通过代理生成Mapper。这点要一定要注意下,看Mybatis源码最重要的就是要学这个。
SqlSession和Configuration是Mybatis中很重要的两个处理类,Configuration主要解析Mybatis的xml配置,保存Mapper代理,保存需要的配置信息,而SqlSession就只负责和数据库的交互。本篇使你对Mybatis有一个大概的认识,下一篇主要讲Mybatis如何解析xml配置信息,生成Configuration对象。
文章最后送你一个Mybatis的一个历史性错误
autoCommmit
,
多写了一个m,由此可见,在nb的程序猿也有出错的时候,告诫大家,写代码时候一定要检查好拼写。