package com.taobao.tddl.group; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; import javax.sql.DataSource; import org.junit.Test; import com.taobao.diamond.mockserver.MockServer; import com.taobao.tddl.common.model.DBType; import com.taobao.tddl.group.jdbc.DataSourceWrapper; import com.taobao.tddl.group.jdbc.TGroupDataSource; public class CrudTest extends BaseGroupTest { @Test public void 单个数据库() throws Exception { TGroupDataSource ds = new TGroupDataSource(); DataSourceWrapper dsw = new DataSourceWrapper(DSKEY0, "rw", getMySQLDataSource(), DBType.MYSQL); ds.init(dsw); testCrud(ds); } @Test public void 单个数据库_atom() throws Exception { TGroupDataSource ds = new TGroupDataSource(); ds.setDbGroupKey(GROUP0); ds.setAppName(APPNAME); MockServer.setConfigInfo(ds.getFullDbGroupKey(), DSKEY1 + ":rw"); ds.init(); testCrud(ds); } @Test public void 测试DataSourceWrapper() throws Exception { List<DataSourceWrapper> dataSourceWrappers = new ArrayList<DataSourceWrapper>(); dataSourceWrappers.add(new DataSourceWrapper(DSKEY1, "rw", getMySQLDataSource(1), DBType.MYSQL)); dataSourceWrappers.add(new DataSourceWrapper(DSKEY2, "r", getMySQLDataSource(2), DBType.MYSQL)); TGroupDataSource ds = new TGroupDataSource(); ds.setDbGroupKey(GROUP0); ds.init(dataSourceWrappers); testCrud(ds); } @Test public void 测试DataSourceWrapper_atom() throws Exception { TGroupDataSource ds = new TGroupDataSource(); ds.setDbGroupKey(GROUP0); ds.setAppName(APPNAME); MockServer.setConfigInfo(ds.getFullDbGroupKey(), DSKEY0 + ":rw" + "," + DSKEY1 + ":r"); ds.init(); testCrud(ds); } // dbGroup: db1:r10w, db2:r20, db3:r30 @Test public void 三个数据库_测试db1可读写_db2与db3只能读() throws Exception { DataSource ds0 = getMySQLDataSource(0); DataSource ds1 = getMySQLDataSource(1); DataSource ds2 = getMySQLDataSource(2); // 读库时最有可能从db3读,然后是db2,db1的权重最小 TGroupDataSource ds = new TGroupDataSource(); DataSourceWrapper dsw0 = new DataSourceWrapper(DSKEY0, "r10w", ds0, DBType.MYSQL); DataSourceWrapper dsw1 = new DataSourceWrapper(DSKEY1, "r20", ds1, DBType.MYSQL); DataSourceWrapper dsw2 = new DataSourceWrapper(DSKEY2, "r30", ds2, DBType.MYSQL); ds.init(dsw0, dsw1, dsw2); testCrud(ds); } @Test public void 三个数据库_测试db1可读写_db2与db3只能读_atom() throws Exception { TGroupDataSource ds = new TGroupDataSource(); ds.setDbGroupKey(GROUP0); ds.setAppName(APPNAME); MockServer.setConfigInfo(ds.getFullDbGroupKey(), DSKEY0 + ":r10w" + "," + DSKEY1 + ":r20" + "," + DSKEY2 + ":r30"); ds.init(); testCrud(ds); } private void testCrud(DataSource ds) throws SQLException { Connection conn = ds.getConnection(); // 测试Statement的crud Statement stmt = conn.createStatement(); assertEquals(stmt.executeUpdate("insert into tddl_test_0000(id,name,gmt_create,gmt_modified) values(10,'str',now(),now())"), 1); assertEquals(stmt.executeUpdate("update tddl_test_0000 set name='str2'"), 1); ResultSet rs = stmt.executeQuery("select id,name from tddl_test_0000"); assertEquals(true, rs.next()); assertEquals(10, rs.getInt(1)); assertEquals("str2", rs.getString(2)); assertEquals(stmt.executeUpdate("delete from tddl_test_0000"), 1); rs.close(); stmt.close(); // 测试PreparedStatement的crud String sql = "insert into tddl_test_0000(id,name,gmt_create,gmt_modified) values(?,?,now(),now())"; PreparedStatement ps = conn.prepareStatement(sql); ps.setInt(1, 10); ps.setString(2, "str"); assertEquals(ps.executeUpdate(), 1); ps.close(); sql = "update tddl_test_0000 set name=?"; ps = conn.prepareStatement(sql); ps.setString(1, "str2"); assertEquals(ps.executeUpdate(), 1); ps.close(); sql = "select id,name from tddl_test_0000"; ps = conn.prepareStatement(sql); rs = ps.executeQuery(); rs.next(); assertEquals(rs.getInt(1), 10); assertEquals(rs.getString(2), "str2"); rs.close(); ps.close(); sql = "delete from tddl_test_0000"; ps = conn.prepareStatement(sql); assertEquals(ps.executeUpdate(), 1); ps.close(); conn.close(); } // dbGroup: db1:w, db2:r20, db3:r30 @Test public void 在只写库上更新后再查询会重用写库上的连接_即使它是一个只写库也不管() throws Exception { // 不支持这种只能写的情况 DataSource ds0 = getMySQLDataSource(0); DataSource ds1 = getMySQLDataSource(1); DataSource ds2 = getMySQLDataSource(2); // 读库时最有可能从db3读,然后是db2,db1的权重最小 TGroupDataSource ds = new TGroupDataSource(); DataSourceWrapper dsw0 = new DataSourceWrapper(DSKEY0, "w", ds0, DBType.MYSQL); DataSourceWrapper dsw1 = new DataSourceWrapper(DSKEY1, "r20", ds1, DBType.MYSQL); DataSourceWrapper dsw2 = new DataSourceWrapper(DSKEY2, "r30", ds2, DBType.MYSQL); ds.init(dsw0, dsw1, dsw2); testCrud_Read(ds); } @Test public void 在只写库上更新后再查询会重用写库上的连接_即使它是一个只写库也不管_atom() throws Exception { TGroupDataSource ds = new TGroupDataSource(); ds.setDbGroupKey(GROUP0); ds.setAppName(APPNAME); MockServer.setConfigInfo(ds.getFullDbGroupKey(), DSKEY0 + ":w" + "," + DSKEY1 + ":r20" + "," + DSKEY2 + ":r30"); ds.init(); testCrud_Read(ds); } private void testCrud_Read(TGroupDataSource ds) throws SQLException { Connection conn = ds.getConnection(); Statement stmt = conn.createStatement(); assertEquals(stmt.executeUpdate("insert into tddl_test_0000(id,name,gmt_create,gmt_modified) values(100,'str',now(),now())"), 1); // 在只写库上更新后,会保留写连接, // 但是因为写连接对应的数据源被配置成只写,所以接下来的读操作不允许在写连接上进行 // 因为db2,db3都没有数据,所以rs.next()返回false ResultSet rs = stmt.executeQuery("select id,name from tddl_test_0000 where id=100"); assertFalse(rs.next()); rs.close(); assertEquals(stmt.executeUpdate("delete from tddl_test_0000 where id=100"), 1); stmt.close(); conn.close(); } }