mybatis使用官方文档已经比较好,此处边笔记边学习(大部分复制粘贴)
开发环境:SpringBoot(借用上篇开发环境)
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为中心的,通过SqlSessionFactory 创建session连接操作DB,基本使用
SqlSessionFactory 有六个方法可以用来创建 SqlSession 实例。通常来说,如何决定是你 选择下面这些方法时:
SqlSession openSession()
SqlSession openSession(boolean autoCommit)
SqlSession openSession(Connection connection)
SqlSession openSession(TransactionIsolationLevel level)
SqlSession openSession(ExecutorType execType,TransactionIsolationLevel level)
SqlSession openSession(ExecutorType execType)
SqlSession openSession(ExecutorType execType, boolean autoCommit)
SqlSession openSession(ExecutorType execType, Connection connection)
默认的 openSession()方法没有参数,它会创建有如下特性的 SqlSession:
开启自动提交, “true” 传递 给可选的 autoCommit 参数。 提供自定义的连接,传递一个 Connection 实例给 connection 参数。注意没有覆盖同时设置 Connection 和 autoCommit 两者的方法,因为 MyBatis 会使用当前 connection 对象提供的设 置。 MyBatis 为事务隔离级别调用使用一个 Java 枚举包装器, 称为 TransactionIsolationLevel, 否则它们按预期的方式来工作,并有 JDBC 支持的 5 级 ( NONE,READ_UNCOMMITTED,READ_COMMITTED,REPEA TABLE_READ,SERIALIZA BLE)
还有一个可能对你来说是新见到的参数,就是 ExecutorType。这个枚举类型定义了 3 个 值:
package mybatis;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;
import mybatis.mapper.CityMapper;
import mybatis.model.City;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
public class MybatisApplicationTests {
@Autowired
SqlSessionFactory sqlSessionFactory;
@Test
public void selectBySql() {
System.out.println("");
SqlSession session = sqlSessionFactory.openSession();
try {
CityMapper cityMapper = session.getMapper(CityMapper.class);
System.out.println(cityMapper.selectCityById(1));
// 此种不推荐
//System.out.println((City)session.selectOne("mybatis.mapper.CityMapper.selectCityById", 1));
} finally {
session.close();
}
}
}
不过我们在配置
SqlSessionFactory通过设置setMapperLocations已经实例化一批Mapper,直接注入使用即可
依赖注入框架可以创建线程安全的、基于事务的 SqlSession 和映射器(mapper)并将它们直接注入到你的 bean 中,因此可以直接忽略它们的生命周期。对于显示创建或这是需要注意其作用域与生命周期
作用域与生命周期
属性也可以被传递到 SqlSessionFactoryBuilder.build()方法中。例如:
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, props);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment, props);
加载顺序
默认关闭,开启,可自定义分隔符
每一个在包
domain.blog
中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。 比如
domain.blog.Author
的别名为
author
;若有注解,则别名为其注解值。(测试,首字母大写也可)
@Alias("author")
public class Author {
...
}
已经为许多常见的 Java 类型内建了相应的类型别名,如int -> _int, Integer ->integer
@MappedJdbcTypes(JdbcType.VARCHAR)//JDBC type,或xml的typeHandler 中配置jdbcType="VARCHAR"(xml优先级高)
@MappedTypes(String.class)// java type,或xml的typeHandler 中配置 javaType="String"
public class ExampleTypeHandler extends BaseTypeHandler {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, parameter);
}
@Override
public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
return rs.getString(columnName);
}
@Override
public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return rs.getString(columnIndex);
}
@Override
public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return cs.getString(columnIndex);
}
}
当决定在
ResultMap
中使用某一TypeHandler时,此时java类型是已知的(从结果类型中获得),但是JDBC类型是未知的。 因此Mybatis使用
javaType=[TheJavaType], jdbcType=null
的组合来选择一个TypeHandler。 这意味着使用
@MappedJdbcTypes
注解可以
限制
TypeHandler的范围,同时除非显示的设置,否则TypeHandler在
ResultMap
中将是无效的。 如果希望在
ResultMap
中使用TypeHandler,那么设置
@MappedJdbcTypes
注解的
includeNullJdbcType=true
即可。 然而从Mybatis 3.4.0开始,如果
只有一个
注册的TypeHandler来处理Java类型,那么它将是
ResultMap
使用Java类型时的默认值(即使没有
includeNullJdbcType=true
)。
// ExampleObjectFactory.java
public class ExampleObjectFactory extends DefaultObjectFactory {
public Object create(Class type) {
return super.create(type);
}
public Object create(Class type, List constructorArgTypes, List
配置
MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法调用包括:
MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中, 现实情况下有多种理由需要这么做。例如,开发、测试和生产环境需要有不同的配置;或者共享相同 Schema 的多个生产数据库, 想使用相同的 SQL 映射。许多类似的用例.
如果你想连接两个数据库,就需要创建两个 SqlSessionFactory 实例,每个数据库对应一个
${alias}.id,${alias}.username,${alias}.password
引用
通过其id进行引用
印射结果集
ResultMap属性
自动映射是默认开启(setting中设置autoMappingBehavior),指当查询列名与java类属性名一致就会自动映射(resultType就是运用自动),当查询不匹配时,我们就需要手动印射(使用resultMap)
可以设置一些自动印射的策略,如通过setting设置mapUnderscoreToCamelCase,只是查询列名与驼峰式java属性匹配
autoMappingBehavior有三种等级
通过BaseExecutor实现一级缓存,CachingExecutor实现二级缓存
mybatis除了局部的session缓存,默认是开启二级缓存,但必须xml中使用
一级缓存有session与statement,setting中通过localCacheScope设置
使用二级缓存
或(引用其他mapper的cache,夸mapper命中)
cache优先级高,配置cache,相关属性
自定义cache
其中property 相当于set方法
Collection caches =session.getConfiguration().getCaches();
当然可以使用地方缓存插件,比如 ehcache
#set
...
#where
...
prefix前缀,
prefixOverrides忽略的后缀
select seq_users.nextval from dual
select nextval for seq_users from sysibm.sysdummy1"
insert into users values (#{id}, #{name})
Mybatis内置的日志工厂提供日志功能,具体的日志实现有以下几种工具:
具体选择哪个日志实现工具由MyBatis的内置日志工厂确定。它会使用最先找到的(按上文列举的顺序查找)。 如果一个都未找到,日志功能就会被禁用。
配置
...
...