MyBatis的非Spring体系使用

前情提要

​ 大多使用Mybatis的场景都需要将mybatis和spring体系进行整合。但是比如做一些tcp协议的项目时候就不能使用spring的ioc体系。

使用示例

1、引入依赖
<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcat-jdbc</artifactId>
</dependency>

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
</dependency>

<dependency>
    <groupId>org.reflections</groupId>
    <artifactId>reflections</artifactId>
</dependency>
2、注解接口定义
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PhyDBMapper {
}
3、定义SqlSessionFactory

本实例使用的是tomcat-jdbc作为数据源

 package com.bytebirth.bubble.db;

 import com.bytebirth.bubble.config.QProperties;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.ibatis.mapping.Environment;
 import org.apache.ibatis.session.Configuration;
 import org.apache.ibatis.session.SqlSessionFactory;
 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 import org.apache.ibatis.transaction.TransactionFactory;
 import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
 import org.apache.tomcat.jdbc.pool.DataSource;
 import org.apache.tomcat.jdbc.pool.PoolProperties;
 import org.reflections.Reflections;
 import org.reflections.scanners.SubTypesScanner;
 import org.reflections.scanners.TypeAnnotationsScanner;
 import org.reflections.util.ClasspathHelper;
 import org.reflections.util.ConfigurationBuilder;
 import java.util.Set;

 @Slf4j
 public class PhySqlSessionFactory {
     private SqlSessionFactory sqlSessionFactory;
     public static PhySqlSessionFactory INSTANCE = Single.SINGLE.sqlSessionFactory;

     public void init(Class<?> tClass,QProperties properties){
         PoolProperties p = new PoolProperties();
         p.setUrl(properties.getConfig("db.url"));
         p.setDriverClassName(properties.getConfig("db.driver"));
         p.setUsername(properties.getConfig("db.userName"));
         p.setPassword(properties.getConfig("db.password"));
         p.setJmxEnabled(properties.getBoolean("db.jmxEnable",false));
         p.setTestWhileIdle(properties.getBoolean("db.testWhileIdle",false));
         p.setTestOnBorrow(properties.getBoolean("db.testOnBorrow",true));
         p.setValidationQuery(properties.getConfig("db.validationQuery","SELECT 1"));
         p.setTestOnReturn(properties.getBoolean("db.testOnReturn",false));
         p.setValidationInterval(properties.getInt("db.validationInterval",30000));
         p.setTimeBetweenEvictionRunsMillis(
             properties.getInt("db.timeBetweenEvictionRunsMillis",30000));
         p.setMaxActive(properties.getInt("db.maxActive",100));
         p.setInitialSize(properties.getInt("db.initialSize",10));
         p.setMaxWait(properties.getInt("db.maxWait",10000));
         p.setRemoveAbandonedTimeout(
             properties.getInt("db.removeAbandonedTimeout",60));
         p.setMinEvictableIdleTimeMillis(
             properties.getInt("db.minEvictableIdleTimeMillis",30000));
         p.setMinIdle(properties.getInt("db.minIdle",10));
         p.setLogAbandoned(properties.getBoolean("db.logAbandoned",true));
         p.setRemoveAbandoned(properties.getBoolean("db.removeAbandoned",true));
         p.setJdbcInterceptors(properties.getConfig("db.jdbcInterceptors",
                 "org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"+
                         "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"));
         DataSource dataSource = new DataSource();
         dataSource.setPoolProperties(p);

         TransactionFactory transactionFactory = new JdbcTransactionFactory();
         Environment environment = 
             new Environment("development",transactionFactory,dataSource);
         Configuration configuration = new Configuration(environment);

         String packageName = tClass.getPackage().getName();
         packageName = packageName.substring(0, packageName.lastIndexOf("."));
         ConfigurationBuilder config = new ConfigurationBuilder();
         config.addUrls(ClasspathHelper.forPackage(packageName));
         config.setScanners(new TypeAnnotationsScanner(),new SubTypesScanner());

         Reflections reflections = new Reflections(config);
         //获取所有的Module的对象
         Set<Class<?>> moduleSet = reflections.getTypesAnnotatedWith(PhyDBMapper.class);
         if(moduleSet != null && moduleSet.size() > 0){
             for(Class<?> clazz : moduleSet){
                 configuration.addMapper(clazz);
             }
         }
         sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
     }

     public SqlSessionFactory getSqlSessionFactory(){
         return sqlSessionFactory;
     }

     private enum Single {
         SINGLE;
         private PhySqlSessionFactory sqlSessionFactory;
         private Single(){
             this.sqlSessionFactory = new PhySqlSessionFactory();
         }
     }
 }

注意:

(1)、调用init()方法中传入的class是调用系统的主函数的class,需要整个系统的java代码都在一个package下。

(2)、系统会自动扫描上述package下的所有java类,找出所有@PhyDBMapper注解

4、调用示例
 package com.bytebirth.popo.register;

 import com.bytebirth.bubble.config.BubbleConfig;
 import com.bytebirth.bubble.config.QProperties;
 import com.bytebirth.bubble.db.PhySqlSessionFactory;
 import com.bytebirth.popo.http.PhyHttpServer;
 import com.bytebirth.popo.register.beans.TtBean;
 import com.bytebirth.popo.register.mapper.TestMapper;
 import org.apache.ibatis.session.SqlSession;
 import java.util.List;

 public class RegisterEntry extends PhyHttpServer {

     public RegisterEntry(){
         QProperties properties = BubbleConfig.INSTANCE.getConfig(RegisterEntry.class);
         PhySqlSessionFactory.INSTANCE.init(RegisterEntry.class,properties);
         SqlSession session = 
             PhySqlSessionFactory.INSTANCE.getSqlSessionFactory().openSession();
         TestMapper mapper = session.getMapper(TestMapper.class);

         for(int i=0;i<1000;i++){
             List list = mapper.getTtList();
             System.out.println(list.get(0).getAddress());

         }

         session.clearCache();
         session.close();
     }

     public static void main(String[] args) {
         new RegisterEntry();
     }
 }