Proxool是一个非常优秀的数据库连接池组件, 下面介绍如何在无spring容器的环境下让Mybatis调用Proxool管理的数据库连接.
首先,我们定义ProxoolUtils工具类,提供loadProxool方法加载数据库连接池.
package com.freestyle.common.db.proxool; /*** * Proxool工具类 * @author dgmislrh */ import java.io.File; import org.logicalcobwebs.proxool.ProxoolException; import org.logicalcobwebs.proxool.configuration.JAXPConfigurator; public class ProxoolUtils { public ProxoolUtils() { // TODO Auto-generated constructor stub } public static void loadProxool(String pvsProxoolConfigFilePath) throws ProxoolException{ try { // 获取配置文件句柄 File file = new File(pvsProxoolConfigFilePath); //单元测试未启动web service,所以要自已加载proxool configurator JAXPConfigurator.configure(pvsProxoolConfigFilePath, false); } catch (ProxoolException e) { throw e; } } public static void loadProxool() throws ProxoolException{ try { // 获取配置文件句柄 String lvsPath=Class.class.getClass().getResource("/").getPath() ; lvsPath=lvsPath+"../classes/proxool.xml"; loadProxool(lvsPath); } catch (ProxoolException e) { throw e; } } }
再定义MybatisUtils工具类,用于sessionFactory的生成/session的获取及归还.
package com.freestyle.common.db.mybatis; 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; import org.apache.ibatis.transaction.TransactionFactory; import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory; import org.apache.log4j.Logger; /**** * Mybatis工具类 * * @author dgmislrh * */ public class MybatisUtils { private static final String CONFIG_FILE = "mybatis-config.xml"; private static final Logger logger = Logger.getLogger(MybatisUtils.class); private static TransactionFactory transactionFactory = new JdbcTransactionFactory(); private static SqlSessionFactory sqlSessionFactory = null; static { buildSessionFactory(); } public MybatisUtils() { // TODO Auto-generated constructor stub } /** * 获取SqlSession * * @return SqlSession */ public static SqlSession getSession() { synchronized (logger) { if (sqlSessionFactory == null) { buildSessionFactory(); } } return sqlSessionFactory != null ? sqlSessionFactory.openSession() : null; } /** * 关闭session */ public static void closeSession(SqlSession session) { session.commit(); session.close(); } public static TransactionFactory getTransactionFactory() { return transactionFactory; } public static SqlSessionFactory getSessionFactory() { synchronized (logger) { if (sqlSessionFactory == null) { buildSessionFactory(); } } return sqlSessionFactory; } private static void buildSessionFactory() { if (sqlSessionFactory == null) { InputStream inputStream = null; try { inputStream = Resources.getResourceAsStream(CONFIG_FILE); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // addMapper(sqlSessionFactory); } catch (IOException e) { logger.error("读取mybatis-config.xml文件时出现异常,异常信息:" + e.getMessage()); e.printStackTrace(); } catch (Exception e) { logger.error("创建SessionFactory失败,异常信息:" + e.getMessage()); e.printStackTrace(); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } inputStream = null; } } } } }
下面是src文件夹下的proxool.xml配置文件:
<?xml version="1.0" encoding="UTF-8"?> <proxool> <alias>omsdb</alias> <!-- <driver-url>jdbc:postgresql://localhost:5432/omslivedbv2</driver-url> --> <driver-url>jdbc:postgresql://localhost:5432/omslivedbv2</driver-url> <driver-class>org.postgresql.Driver</driver-class> <driver-properties> <property name="user" value="postgres" /> <property name="password" value="xxxxxxxx" /> </driver-properties> <!--最少保持的空闲连接数(默认2个)--> <prototype-count>2</prototype-count> <minimum-connection-count>2</minimum-connection-count> <maximum-connection-count>20</maximum-connection-count> <!--没有空闲连接可以分配而在队列中等候的最大请求数,超过这个请求数的用户连接就不会被接受--> <simultaneous-build-throttle>20</simultaneous-build-throttle> <!--proxool自动侦察各个连接状态的时间间隔(毫秒),侦察到空闲的连接就马上回收,超时的销毁 默认30秒--> <house-keeping-sleep-time>90000</house-keeping-sleep-time> <!--在使用之前测试--> <test-before-use>true</test-before-use> <house-keeping-test-sql>select CURRENT_DATE</house-keeping-test-sql> <maximum-active-time>6000000</maximum-active-time> </proxool>
proxoolutils工具类会根据此配置文件加载proxool, 上面的配置用于创建postgresql数据库的连接.
下面是src文件夹下的mybatis-config.xml配置文件.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <typeAliases> <typeAlias type="com.freestyle.common.db.mybatis.OMSDataSourceFactory" alias="omsdbFactory" /> </typeAliases> <environments default="development"> <environment id="development"> <!-- 修改这里以后必须同步修改application.properties文件mybatis_environment属性的值 --> <transactionManager type="JDBC" /> <dataSource type="omsdbFactory"> </dataSource> </environment> </environments> <mappers> <mapper resource="com/freestyle/proxoolmybatisstudy/dao/TaUserMapper.xml" /> </mappers> </configuration>
上面的mybatis配置文件,development数据环境的dataSource的type指定为omsdbFactory, 这是自定义的DatasourceFactory,让mybatis根据omsdbFactory来产生datasource, 那么omsdbFactory又是什么? 它是OMSDataSourceFactory的简称, 而OMSDataSourceFactory是基于ProxoolDataSourceFactory的, 下面给出这两个类的代码:
package com.freestyle.common.db.proxool; import java.util.Properties; import javax.sql.DataSource; import org.apache.ibatis.datasource.DataSourceFactory; import org.logicalcobwebs.proxool.ProxoolDataSource; /*** * ProxooolDataSource数据源工厂 * 调用前先加载proxool连接池 * @author dgmislrh * */ public class ProxoolDataSourceFactory implements DataSourceFactory { protected ProxoolDataSource dataSource=null; public ProxoolDataSourceFactory(String pvsUrl) { dataSource=new ProxoolDataSource(pvsUrl); } public DataSource getDataSource() { return dataSource; } public void setProperties(Properties arg0) { } }
package com.freestyle.common.db.proxool; /*** * 构建omsdb对应的数据源工厂 * @author dgmislrh * */ public class OMSDataSourceFactory extends ProxoolDataSourceFactory { public OMSDataSourceFactory(){ super("omsdb"); } public OMSDataSourceFactory(String pvsUrl) { super(pvsUrl); // TODO Auto-generated constructor stub } }
配置算是整好了, 为了省事,我们用Mybatis generator生成ta_user的mapper及代码 . 生成的代码都是千遍一律就不贴了.
下面开一个junit 测试:
package test; import org.apache.ibatis.session.SqlSession; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.logicalcobwebs.proxool.ProxoolFacade; import com.freestyle.common.db.mybatis.MybatisUtils; import com.freestyle.common.db.proxool.ProxoolUtils; import com.freestyle.proxoolmybatisstudy.dao.TaUserMapper; import com.freestyle.proxoolmybatisstudy.entities.TaUser; public class Test1 { @Before public void setUp() throws Exception { //加载Proxool数据库连接池 ProxoolUtils.loadProxool(); } @After public void tearDown() throws Exception { ProxoolFacade.shutdown(0); } @Test public void test() { SqlSession lvSqlSession=MybatisUtils.getSession(); try { TaUserMapper lvTaUerMapper=lvSqlSession.getMapper(TaUserMapper.class); TaUser lvUser=lvTaUerMapper.selectByPrimaryKey("admin"); Assert.assertNotNull(lvUser); lvUser.setFaPhone("8888"); lvTaUerMapper.updateByPrimaryKey(lvUser); //lvSqlSession.rollback(); } finally{ MybatisUtils.closeSession(lvSqlSession); } } }
脱离spring的依赖, 用junit进行功能测试,启动速度非常快:
09:37:37,450 DEBUG selectByPrimaryKey:54 - ==> Preparing: select fa_login, fa_phone, fa_name, fa_status, fa_type, fa_create_by, fa_create_dt, fa_update_by, fa_update_dt, fa_email, fa_passwd, fa_remark, fa_staff_id, fa_last_notify from public.ta_user where fa_login = ? 09:37:37,455 DEBUG ProxyFactory:209 - Implementing interface java.sql.Statement 09:37:37,455 DEBUG ProxyFactory:209 - Implementing interface org.postgresql.PGStatement 09:37:37,456 DEBUG ProxyFactory:209 - Implementing interface java.sql.PreparedStatement 09:37:37,456 DEBUG ProxyFactory:209 - Implementing interface org.postgresql.core.BaseStatement 09:37:37,456 DEBUG ProxyFactory:209 - Implementing interface java.sql.Wrapper 09:37:37,456 DEBUG ProxyFactory:209 - Implementing interface java.lang.AutoCloseable 09:37:37,493 DEBUG selectByPrimaryKey:54 - ==> Parameters: admin(String) 09:37:37,515 DEBUG selectByPrimaryKey:54 - <== Total: 1 09:37:37,519 DEBUG ProxyFactory:209 - Implementing interface java.sql.DatabaseMetaData 09:37:37,519 DEBUG ProxyFactory:209 - Implementing interface java.sql.Wrapper com.freestyle.proxoolmybatisstudy.entities.TaUser@33f676f6 09:37:37,544 DEBUG updateByPrimaryKey:54 - ==> Preparing: update public.ta_user set fa_phone = ?, fa_name = ?, fa_status = ?, fa_type = ?, fa_create_by = ?, fa_create_dt = ?, fa_update_by = ?, fa_update_dt = ?, fa_email = ?, fa_passwd = ?, fa_remark = ?, fa_staff_id = ?, fa_last_notify = ? where fa_login = ? 09:37:37,547 DEBUG updateByPrimaryKey:54 - ==> Parameters: 8888(String), 管理员(String), A(String), A(String), test1(String), 2016-09-19 15:24:40.594(Timestamp), supuser1(String), 2016-10-14 15:47:35.312(Timestamp), (String), d1841df9a9ead353f339dd239a1b4676(String), (String), (String), 9711(Long), admin(String) 09:37:37,548 DEBUG updateByPrimaryKey:54 - <== Updates: 1 09:37:37,548 DEBUG JdbcTransaction:54 - Committing JDBC Connection [98826337(org.postgresql.jdbc.PgConnection@2fb0623e)] 09:37:37,551 DEBUG JdbcTransaction:54 - Resetting autocommit to true on JDBC Connection [98826337(org.postgresql.jdbc.PgConnection@2fb0623e)] 09:37:37,552 DEBUG JdbcTransaction:54 - Closing JDBC Connection [98826337(org.postgresql.jdbc.PgConnection@2fb0623e)]
代码下载: https://download.csdn.net/download/rocklee/10441780