前言:
今天看官们对“ibatis判断字符串if test”大概比较关心,各位老铁们都需要学习一些“ibatis判断字符串if test”的相关内容。那么小编同时在网摘上汇集了一些关于“ibatis判断字符串if test””的相关文章,希望看官们能喜欢,兄弟们一起来了解一下吧!前言
使用Mybatis执行数据库操作,首先要获取SqlSession,通过它进一步获取Mapper接口代理对象,最后通过代理对象发起数据库操作
这是使用Mybatis进行数据库操作的一个Demo,通过构建DataSource、TransactionFactory、Environment、Configuration并将它们组装在一起获得SqlSessionFactory,此后就可以通过它获取SqlSession
sqlSessionFactory.openSession();通过会话工厂开启一个会话
@Testpublic void readerTest() throws IOException { PageUtil.setPagingParam(1,11); //得到一个Reader处理类(字符流) try (Reader reader = Resources.getResourceAsReader("org/apache/ibatis/mytest/mybatis-config.xml")) { // environment:数据源ID 在mybatis-config.xml <environments> 标签里面配置的 id 为development的数据源信息(非必传) // properties :配置文件信息。一般是数据库配置信息。可以在这里进行配置 也可以在mybatis-config.xml 通过<properties> 标签进行引入properties配置文件 sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader,"development", Resources.getResourceAsProperties("org/apache/ibatis/mytest/db.properties")); } SqlSession sqlSession = sqlSessionFactory.openSession(); StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); mapper.insertStudent(new StudentDto(11, "12", 24, Arrays.asList(1, 2, 3, 4, 5))); sqlSession.commit(); List<StudentDto> rs = mapper.getStudentsByAlias(); System.out.println(rs.toString());}复制代码看下openSession里面是怎么实现的
1.得到配置的环境数据源信息
2.根据数据源信息得到一个事务工厂
3.新建一个事务
4.根据事务得到执行器(代表一个事务对应一个执行器)
5.创建默认的SqlSession对象
/** * 打开一个session 来自 数据源 * * @param execType 执行器类型 默认ExecutorType是 ExecutorType.SIMPLE * @param level 事务隔离级别 * @param autoCommit 是否自动提交事务 * * @return SqlSession会话对象 */private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) { /* 之前sqlSessionFactoryBuilder.build(InputStream inputStream) ===》 xMLConfigBuilder.parse() ====》 将配置文件中的数据源和sql语句封装赋值给了Configuration对象 所以,这边可以直接获取对象中的相关信息 */ Transaction tx = null; try { // 获取环境配置 final Environment environment = configuration.getEnvironment(); // 事务工厂 final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment); // 新建一个事务 tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit); // 拿到执行器Executor final Executor executor = configuration.newExecutor(tx, execType); // 创建默认的SqlSession对象 return new DefaultSqlSession(configuration, executor, autoCommit); } catch (Exception e) { closeTransaction(tx); // may have fetched a connection so lets call close() throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e); } finally { ErrorContext.instance().reset(); }}复制代码看下执行器的创建过程
public Executor newExecutor(Transaction transaction, ExecutorType executorType) { executorType = executorType == null ? defaultExecutorType : executorType; executorType = executorType == null ? ExecutorType.SIMPLE : executorType; Executor executor; if (ExecutorType.BATCH == executorType) { // 批处理执行器 executor = new BatchExecutor(this, transaction); } else if (ExecutorType.REUSE == executorType) { // 复用执行器 executor = new ReuseExecutor(this, transaction); } else { // 默认执行器 executor = new SimpleExecutor(this, transaction); } /* 1、一级缓存默认是开启的 2、二级缓存默认是关闭的 3、先执行一级缓存还是二级缓存,先执行二级缓存 */ // cacheEnabled一级缓存默认是开启的,为true的话代表开启二级缓存 // 二级缓存通过装饰器模式的方式加载进执行器中 if (cacheEnabled) { executor = new CachingExecutor(executor); } // 重点:插件拦截器过滤链 把执行器怼到里面去 executor = (Executor) interceptorChain.pluginAll(executor); return executor;}复制代码看下插件的植入过程
mybatis会遍历所有配置的插件来进行代理。多个插件会重复代理
/** * 简化动态代理创建的方法 * * @param target * @param interceptor * * @return */public static Object wrap(Object target, Interceptor interceptor) { // 获取自定义插件中,通过@Intercepts注解指定的方法 Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor); // 获取目标对象的类型 Class<?> type = target.getClass(); // 根据类型获取所有拦截的接口 Class<?>[] interfaces = getAllInterfaces(type, signatureMap); if (interfaces.length > 0) { // 如果需要拦截,则用JDK动态代理生成一个代理对象 return Proxy.newProxyInstance( type.getClassLoader(), interfaces, new Plugin(target, interceptor, signatureMap)); } return target;}复制代码看下Plugin
Plugin有三个参数
target:目标对象Executor、ParameterHandler、ResultSetHandler、StatementHandler实例 或者另一个插件代理对象。
interceptor:对应插件类加载对象
signatureMap:插件注解生效的方法
package org.apache.ibatis.plugin;import org.apache.ibatis.reflection.ExceptionUtil;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.util.HashMap;import java.util.HashSet;import java.util.Map;import java.util.Set;/** * @author Clinton Begin */public class Plugin implements InvocationHandler { /** 目标对象Executor、ParameterHandler、ResultSetHandler、StatementHandler实例 或者另一个插件代理对象*/ /**多个插件的加载采用在target里面传入代理对象实现的*/ private final Object target; /** 用户自定义拦截器实例 */ private final Interceptor interceptor; /** Intercepts注解指定的方法 */ private final Map<Class<?>, Set<Method>> signatureMap; private Plugin(Object target, Interceptor interceptor, Map<Class<?>, Set<Method>> signatureMap) { this.target = target; this.interceptor = interceptor; this.signatureMap = signatureMap; } /** * 简化动态代理创建的方法 * * @param target * @param interceptor * * @return */ public static Object wrap(Object target, Interceptor interceptor) { // 获取自定义插件中,通过@Intercepts注解指定的方法 Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor); // 获取目标对象的类型 Class<?> type = target.getClass(); // 根据类型获取所有拦截的接口 Class<?>[] interfaces = getAllInterfaces(type, signatureMap); if (interfaces.length > 0) { // 如果需要拦截,则用JDK动态代理生成一个代理对象 return Proxy.newProxyInstance( type.getClassLoader(), interfaces, new Plugin(target, interceptor, signatureMap)); } return target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { Set<Method> methods = signatureMap.get(method.getDeclaringClass()); // 如果是@Intercepts注解指定的方法,就调用拦截的逻辑 if (methods != null && methods.contains(method)) { // 将目标方法信息封装成Invocation给拦截器的intercept()方法使用 return interceptor.intercept(new Invocation(target, method, args)); } return method.invoke(target, args); } catch (Exception e) { throw ExceptionUtil.unwrapThrowable(e); } } private static Map<Class<?>, Set<Method>> getSignatureMap(Interceptor interceptor) { // 获取@Intercepts注解信息 Intercepts interceptsAnnotation = interceptor.getClass().getAnnotation(Intercepts.class); // issue #251 if (interceptsAnnotation == null) { throw new PluginException("No @Intercepts annotation was found in interceptor " + interceptor.getClass().getName()); } // 获取@Signature注解信息 Signature[] sigs = interceptsAnnotation.value(); Map<Class<?>, Set<Method>> signatureMap = new HashMap<>(); for (Signature sig : sigs) { // 把所有@Signature指定拦截的组件、方法添加到map中去 Set<Method> methods = signatureMap.computeIfAbsent(sig.type(), k -> new HashSet<>()); try { Method method = sig.type().getMethod(sig.method(), sig.args()); methods.add(method); } catch (NoSuchMethodException e) { throw new PluginException("Could not find method on " + sig.type() + " named " + sig.method() + ". Cause: " + e, e); } } return signatureMap; } private static Class<?>[] getAllInterfaces(Class<?> type, Map<Class<?>, Set<Method>> signatureMap) { Set<Class<?>> interfaces = new HashSet<>(); while (type != null) { for (Class<?> c : type.getInterfaces()) { if (signatureMap.containsKey(c)) { interfaces.add(c); } } type = type.getSuperclass(); } return interfaces.toArray(new Class<?>[0]); }}复制代码
可以看出,创建sqlsession经过了以下几个主要步骤:
从配置中获取Environment;从Environment中取得DataSource;从Environment中取得TransactionFactory;从DataSource里获取数据库连接对象Connection;在取得的数据库连接上创建事务对象Transaction;创建Executor对象(该对象非常重要,事实上sqlsession的所有操作都是通过它完成的);创建sqlsession对象。
原文链接:
标签: #ibatis判断字符串if test