Java tutorial
/* * Copyright 2008 Pavel Syrtsov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and limitations * under the License. */ package com.sf.ddao; import com.google.inject.Guice; import com.google.inject.Injector; import com.mockrunner.jdbc.BasicJDBCTestCaseAdapter; import com.mockrunner.jdbc.PreparedStatementResultSetHandler; import com.mockrunner.mock.jdbc.MockConnection; import com.mockrunner.mock.jdbc.MockResultSet; import com.sf.ddao.chain.ChainModule; import com.sf.ddao.chain.UseContext; import com.sf.ddao.factory.param.ThreadLocalParameter; import com.sf.ddao.orm.RSMapper; import com.sf.ddao.orm.UseRSMapper; import com.sf.ddao.orm.rsmapper.rowmapper.BeanRowMapperFactory; import com.sf.ddao.orm.rsmapper.rowmapper.RowMapper; import org.apache.commons.chain.Context; import org.mockejb.jndi.MockContextFactory; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.Map; import static com.sf.ddao.chain.CtxHelper.context; /** * JDBCDaoTest is testing basic DDao functionality executed upon simple JDBC connection created by JDBC DriverManager call. * <p/> * Created by: Pavel Syrtsov * Date: Apr 6, 2007 * Time: 7:00:11 PM */ public class JDBCDaoTest extends BasicJDBCTestCaseAdapter { Injector injector; private static final String PART_NAME = "partName"; @JDBCDao(value = "jdbc://test", driver = "com.mockrunner.mock.jdbc.MockDriver") public static interface TestUserDao extends TransactionableDao { /** * in this statement we assume that 1st method arg is Java Bean * and refer to property by name. It works same way for Map. * * @param userBean - parameter object * @return - TestUserBean created using data from SQL */ @Select("select id, name from user where id = #id#") TestUserBean getUser(TestUserBean userBean); @Select("select id, name from user") List<TestUserBean> getUserList(); @Select("select id, name from user") List<Map<String, Object>> getMapList(); /** * 1st parametter passed by value (by injecting result of toString() into SQL), 2nd parametter passed by reference, * added underscore to column name to verify that it gets stripped * * @param tableName - paramter object * @param size - max size of return array * @return array of TestUserBeans created using data returned by SQL query */ @Select("select id, _Name from $0$ limit #1#") TestUserBean[] getUserArray(String tableName, int size); @Select("select id, name from user") void processUsers(@UseRSMapper RSMapper selectCallback); /** * values that have '()' assumed to be call to static function, * at this point we have only function that allows to pass value thrue ThreadLocal * * @param name - query parameter * @return id */ @Select("select id from user where part = '$ctx:" + PART_NAME + "$' and name = #0#") int getUserIdByName(String name, @UseContext Context ctx); @SelectThenInsert({ "select nextval from userIdSequence", "insert into user(id,name) values(#threadLocal:id#, #name#)" }) int addUser(TestUserBean user); @Insert("insert into user (id, name) values #fwd:0#") int insertDynamic(DynamicQuery dq); } protected void setUp() throws Exception { super.setUp(); injector = Guice.createInjector(new ChainModule(TestUserDao.class)); } protected void tearDown() throws Exception { super.tearDown(); MockContextFactory.revertSetAsInitial(); } private void createResultSet(Object... data) { MockConnection connection = getJDBCMockObjectFactory().getMockConnection(); PreparedStatementResultSetHandler handler = connection.getPreparedStatementResultSetHandler(); MockResultSet rs = handler.createResultSet(); for (int i = 0; i < data.length; i++) { Object colName = data[i++]; Object colValues = data[i]; rs.addColumn(colName.toString(), (Object[]) colValues); } handler.prepareGlobalResultSet(rs); } public void testSingleRecordGet() throws Exception { // create dao object TestUserDao dao = injector.getInstance(TestUserDao.class); // ruse it for multiple invocations getUserOnce(dao, 1, "foo", true); getUserOnce(dao, 2, "bar", true); } private void getUserOnce(TestUserDao dao, int id, String name, boolean connShouldBeClosed) { // setup test TestUserBean data = new TestUserBean(true); data.setId(id); data.setName(name); createResultSet("id", new Object[] { data.getId() }, "name", new Object[] { data.getName() }); // execute dao method TestUserBean res = dao.getUser(data); // verify result assertNotNull(res); assertEquals(res.getId(), data.getId()); assertEquals(res.getName(), data.getName()); verifySQLStatementExecuted("select id, name from user where id = ?"); verifyAllResultSetsClosed(); verifyAllStatementsClosed(); if (connShouldBeClosed) { verifyConnectionClosed(); } } public void testGetRecordList() throws Exception { // setup test createResultSet("id", new Object[] { 1, 2 }, "name", new Object[] { "foo", "bar" }); // execute dao method TestUserDao dao = injector.getInstance(TestUserDao.class); List<TestUserBean> res = dao.getUserList(); // verify result assertNotNull(res); assertEquals(res.size(), 2); assertEquals(res.get(0).getId(), 1); assertEquals(res.get(0).getName(), "foo"); assertEquals(res.get(1).getId(), 2); assertEquals(res.get(1).getName(), "bar"); verifySQLStatementExecuted("select id, name from user"); verifyAllResultSetsClosed(); verifyAllStatementsClosed(); verifyConnectionClosed(); } public void testGetMapList() throws Exception { // setup test createResultSet("id", new Object[] { 1, 2 }, "name", new Object[] { "foo", "bar" }); // execute dao method TestUserDao dao = injector.getInstance(TestUserDao.class); List<Map<String, Object>> res = dao.getMapList(); // verify result assertNotNull(res); assertEquals(res.size(), 2); assertEquals(res.get(0).get("id"), 1); assertEquals(res.get(0).get("name"), "foo"); assertEquals(res.get(1).get("id"), 2); assertEquals(res.get(1).get("name"), "bar"); verifySQLStatementExecuted("select id, name from user"); verifyAllResultSetsClosed(); verifyAllStatementsClosed(); verifyConnectionClosed(); } public void testGetUserArray() throws Exception { // setup test createResultSet("id", new Object[] { 1, 2 }, "name", new Object[] { "foo", "bar" }); // execute dao method TestUserDao dao = injector.getInstance(TestUserDao.class); TestUserBean[] res = dao.getUserArray("user", 2); // verify result assertNotNull(res); assertEquals(res.length, 2); assertEquals(res[0].getId(), 1); assertEquals(res[0].getName(), "foo"); assertEquals(res[1].getId(), 2); assertEquals(res[1].getName(), "bar"); verifySQLStatementExecuted("select id, _name from user limit ?"); verifySQLStatementParameter("select id, _name from user limit ?", 0, 1, 2); verifyAllResultSetsClosed(); verifyAllStatementsClosed(); verifyConnectionClosed(); } public void testSelectCallback() throws Exception { // setup test createResultSet("id", new Object[] { 1, 2 }, "name", new Object[] { "foo", "bar" }); final List<TestUserBean> res = new ArrayList<TestUserBean>(); // execute dao method TestUserDao dao = injector.getInstance(TestUserDao.class); dao.processUsers(new RSMapper() { RowMapper rowMapper = new BeanRowMapperFactory(TestUserBean.class).get(); public Object handle(Context context, ResultSet rs) throws SQLException { while (rs.next()) { res.add((TestUserBean) rowMapper.map(rs)); } return null; } }); // verify result assertNotNull(res); assertEquals(res.size(), 2); assertEquals(res.get(0).getId(), 1); assertEquals(res.get(0).getName(), "foo"); assertEquals(res.get(1).getId(), 2); assertEquals(res.get(1).getName(), "bar"); verifySQLStatementExecuted("select id, name from user"); verifyAllResultSetsClosed(); verifyAllStatementsClosed(); verifyConnectionClosed(); } public void testGetUserId() throws Exception { // setup test final int id = 77; final String testName = "testName"; final String testPart = "testPart"; createResultSet("id", new Object[] { id }); // execute dao method TestUserDao dao = injector.getInstance(TestUserDao.class); int res = dao.getUserIdByName(testName, context(PART_NAME, testPart)); // verify result ThreadLocalParameter.remove(PART_NAME); assertEquals(id, res); verifySQLStatementExecuted("select id from user where part = '" + testPart + "' and name = ?"); verifyPreparedStatementParameter(0, 1, testName); verifyAllResultSetsClosed(); verifyAllStatementsClosed(); verifyConnectionClosed(); } public void testNullParameter() throws Exception { // setup test final int id = 77; final String testName = null; final String testPart = "testPart"; createResultSet("id", new Object[] { id }); // execute dao method TestUserDao dao = injector.getInstance(TestUserDao.class); int res = dao.getUserIdByName(testName, context(PART_NAME, testPart)); // verify result ThreadLocalParameter.remove(PART_NAME); assertEquals(id, res); verifySQLStatementExecuted("select id from user where part = '" + testPart + "' and name = ?"); verifyPreparedStatementParameter(0, 1, testName); verifyAllResultSetsClosed(); verifyAllStatementsClosed(); verifyConnectionClosed(); } public void testTx() throws Exception { final int id = 77; final String testName = "testName"; // execute dao method final TestUserDao dao = injector.getInstance(TestUserDao.class); final TestUserBean user = new TestUserBean(true); user.setName(testName); //noinspection unchecked TxHelper.execInTx(dao, new Runnable() { public void run() { try { createResultSet("nextval", new Object[] { id }); final int res = dao.addUser(user); final Connection connection1 = TxHelper.getConnectionOnHold(); assertNotNull(connection1); assertFalse(connection1.isClosed()); verifyNotCommitted(); getUserOnce(dao, 11, "user11", false); final Connection connection2 = TxHelper.getConnectionOnHold(); assertSame(connection1, connection2); assertFalse(connection2.isClosed()); verifyNotCommitted(); assertEquals(id, res); } catch (SQLException e) { throw new RuntimeException(e); } } }); final Connection connection = TxHelper.getConnectionOnHold(); assertNull(connection); verifyCommitted(); verifySQLStatementExecuted("select nextval from userIdSequence"); verifySQLStatementExecuted("insert into user(id,name) values(?, ?)"); verifyPreparedStatementParameter(1, 1, id); verifyPreparedStatementParameter(1, 2, testName); verifyAllResultSetsClosed(); verifyAllStatementsClosed(); verifyConnectionClosed(); } public void testDynamicQuery() throws Exception { // create dao object TestUserDao dao = injector.getInstance(TestUserDao.class); DynamicQuery dq = new DynamicQuery(); dq.add("(?,?)", 1, "foo"); dq.add("(?,?)", 2, "bar"); dao.insertDynamic(dq); final String sql = "insert into user (id, name) values (?,?)(?,?)"; verifySQLStatementExecuted(sql); verifySQLStatementParameter(sql, 0, 1, 1); verifySQLStatementParameter(sql, 0, 2, "foo"); verifySQLStatementParameter(sql, 0, 3, 2); verifySQLStatementParameter(sql, 0, 4, "bar"); verifyAllResultSetsClosed(); verifyAllStatementsClosed(); verifyConnectionClosed(); } }