package jef.database.pooltest; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import jef.common.log.LogUtil; import jef.database.DbClient; import jef.database.DbClientBuilder; import jef.database.DbUtils; import jef.database.DebugUtil; import jef.database.NativeQuery; import jef.database.innerpool.IConnection; import jef.database.test.DataSource; import jef.database.test.DataSourceContext; import jef.database.test.DatabaseInit; import jef.database.test.JefJUnit4DatabaseTestRunner; import jef.jre5support.ProcessUtil; import jef.orm.multitable2.model.Child; import jef.orm.onetable.model.TestEntity; import jef.tools.ThreadUtils; import jef.tools.string.RandomData; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; /** */ @RunWith(JefJUnit4DatabaseTestRunner.class) @DataSourceContext({ @DataSource(name = "mysql", url = "${mysql.url}", user = "${mysql.user}", password = "${mysql.password}"), @DataSource(name="oracle",url="${oracle.url}",user="${oracle.user}",password="${oracle.password}"), @DataSource(name="postgresql",url="${postgresql.url}",user="${postgresql.user}",password="${postgresql.password}"), @DataSource(name="derby",url="jdbc:derby:./db;create=true"), @DataSource(name = "hsqldb", url = "jdbc:hsqldb:mem:testhsqldb", user = "sa", password = ""), @DataSource(name = "sqlite", url = "jdbc:sqlite:test.db"), @DataSource(name = "sqlserver", url = "${sqlserver.url}",user="${sqlserver.user}",password="${sqlserver.password}") }) public class ConnectionPoolTest { private DbClient db; @DatabaseInit public void setup() throws SQLException{ db.createTable(TestEntity.class,Child.class); //使用createNativeQuery后,在MySQL下,会自动为建表语句加上`xx`这样的修饰符 if (!db.getMetaData(null).existTable("DUAL")) { db.createNativeQuery("create table dual(X char(1))").executeUpdate(); } if (db.loadBySql("select count(*) from DUAL",Integer.class) != 1) { db.createNativeQuery("delete from DUAL").executeUpdate(); db.createNativeQuery("insert into DUAL values('X')").executeUpdate(); } } /** * 测试连接池自动重连功能,在网线断开造成连接实效后,下次能自动重连。该集成案例需要人工干预,故自动测试不进行 * @throws SQLException */ @Test @Ignore public void testPoolReconnect() throws SQLException{ DbClient db=new DbClientBuilder("oracle", "oel1246.hz.asiainfo.com", 1521, "oel1246", "XG", "XG").setMaxPoolSize(1).build(); NativeQuery<Integer> config=db.createNativeQuery("select count(*) from JEF_NAMED_QUERIES",Integer.class); LogUtil.show(config.getSingleResult()); System.out.println("请拔掉网线。"); ThreadUtils.doSleep(4000); try{ LogUtil.show(config.getSingleResult()); }catch(Exception e){ System.out.println("查询失败。"); } System.out.println("请插上网线。"); ThreadUtils.doSleep(4000); LogUtil.show(config.getSingleResult()); } private static class Readthread extends Thread{ private IConnection conn; @Override public void run() { try{ for(int i=0;i<20;i++){ doReadTasdk(); } }catch(Exception e){ e.printStackTrace(); } } private void doReadTasdk() throws SQLException { System.out.println("[查询线程]操作开始"); PreparedStatement st=conn.prepareStatement("select * from test_entity"); ResultSet rs=st.executeQuery(); int n=0; while(rs.next()){ n++; rs.getObject(1); rs.getObject(2); if(n%500==0){ ThreadUtils.doSleep(50); System.out.println("目前结果遍历已经达到"+n+"次"); } } DbUtils.close(rs); DbUtils.close(st); System.out.println("结果遍历完成:共计"+n); } } private static class TransactiionThread extends Thread{ private IConnection conn; @Override public void run() { try{ doTransactionTasdk(); }catch(Exception e){ e.printStackTrace(); } } private void doTransactionTasdk() throws SQLException { System.out.println("[事务]操作开始"); conn.setAutoCommit(false); // System.out.println("[事务]===2==="); for(int i=0;i<100;i++){ doInsert(i); doSelect(i); doUpdate(i); conn.commit(); System.out.println("[事务]第"+i+"次事务完成"); // ThreadUtils.doSleep(400); } System.out.println("[事务]事务操作全部完成。"); } private void doUpdate(int i) { //做一次更新操作 PreparedStatement st=null; try{ st=conn.prepareStatement("update child set parentid=? where id=?"); st.setInt(1, i); st.setInt(2, 1); int n=st.executeUpdate(); }catch(SQLException e){ e.printStackTrace(); }finally{ DbUtils.close(st); } } private void doSelect(int i) { PreparedStatement st=null; //做一次查询操作 ResultSet rs=null; try{ st=conn.prepareStatement("select * from child where id=?"); st.setInt(1, 1); rs=st.executeQuery(); int count=0; while(rs.next()){ count++; } // if(count!=1){ // System.out.println("[事务]问题?没有查到记录"+count);//整个处理过程中,id是不变的因此查不到是不正常的 // } }catch(SQLException e){ e.printStackTrace(); }finally{ DbUtils.close(rs); DbUtils.close(st); } } private void doInsert(int i) { //做一次插入操作 PreparedStatement st=null; try{ st=conn.prepareStatement("insert into B(ID,NAME) values (?,?)"); st.setInt(1, 100+i+RandomData.randomInteger(1, 10000)); st.setString(2, RandomData.randomChineseName()); int n=st.executeUpdate(); }catch(SQLException e){ e.printStackTrace(); }finally{ DbUtils.close(st); } } } /** * TODO 测试太耗时 * @throws SQLException */ @Test @Ignore public void testConnectionPoolMultiThread() throws SQLException{ System.out.println("进程号:"+ ProcessUtil.getPid()); IConnection conn=DebugUtil.getConnection(db.getSqlTemplate(null)); db.executeSql("delete from B"); //////////////////////////////////////////// Readthread t1=new Readthread(); t1.setName("测试读取线程"); t1.conn=conn; conn.setAutoCommit(true); TransactiionThread t2=new TransactiionThread(); // TransactiionThread t3=new TransactiionThread(); t2.setName("事务线程1"); t2.conn=conn; t1.start(); ThreadUtils.doSleep(200); t2.start(); // t3.start(); int n=0; for(int i=0;i<50;i++){ Statement st=conn.createStatement(); ResultSet rs=null; try{ rs=st.executeQuery("select 1 from dual"); }catch(SQLException e){ e.printStackTrace(); }finally{ DbUtils.close(rs); DbUtils.close(st); } n++; if(n%10==0){ System.out.println("心跳已经执行"+n+"次"); } ThreadUtils.doSleep(100); } System.out.println("主线程执行完毕,总共"+n+"次心跳检测完成。"); } }