はじめに
http://blogs.yahoo.co.jp/dk521123/36044963.htmlhttp://blogs.yahoo.co.jp/dk521123/34079202.html
http://blogs.yahoo.co.jp/dk521123/36050559.html
http://blogs.yahoo.co.jp/dk521123/36053260.html
などでORMを検討したが、その中でhttp://blogs.yahoo.co.jp/dk521123/34079202.html
で紹介したDbUtils をもう少し使いやすい形にしてみる # ぶっちゃけ上記のコードを整理しただけ。
補足
* SX DbUtilsはいうのもあるらしいが、メンテされてなさそうなので...https://osdn.jp/projects/sx-dbutils/
注意
DbUtils.commitAndCloseQuietly(connection)について
* コミットして Connection オブジェクトを解放するので、 その後、DB接続すると、例外が発生するhttp://java6.blog117.fc2.com/blog-entry-37.html
サンプル
DBデータ(MySQL)
CREATE TABLE `employee` ( `id` BIGINT(20) NOT NULL AUTO_INCREMENT, `emp_name` VARCHAR(100) NOT NULL DEFAULT '0', `birth_date` DATE NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB;
EmployeeDao.java
import java.io.Serializable; import java.util.Date; public class EmployeeDao implements Serializable { private static final long serialVersionUID = 1L; private Long id; private String empName; private Date birthDate; public Long getId() { return this.id; } public void setId(Long id) { this.id = id; } public String getEmpName() { return this.empName; } public void setEmpName(String empName) { this.empName = empName; } public Date getBirthDate() { return this.birthDate; } public void setBirthDate(Date birthDate) { this.birthDate = birthDate; } }
EmployeeBeanProcessor.java
本当はアノテーションを使って、DBの項目名とJavaのプロパティをマッピングしたいがめんどいので...import java.beans.PropertyDescriptor; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.Arrays; import org.apache.commons.dbutils.BeanProcessor; public class EmployeeBeanProcessor extends BeanProcessor { @Override protected int[] mapColumnsToProperties(ResultSetMetaData rsmd, PropertyDescriptor[] props) throws SQLException { int columns = rsmd.getColumnCount(); int columnToProperty[] = new int[columns + 1]; Arrays.fill(columnToProperty, PROPERTY_NOT_FOUND); for (int col = 1; col <= columns; col++) { // ★getColumnLabel()を使用することにより、別名(AS)でマッピングできる★ String columnName = rsmd.getColumnLabel(col); for (int i = 0; i < props.length; i++) { if (equalsColumnProperty(columnName, props[i].getName())) { columnToProperty[col] = i; break; } } } return columnToProperty; } private boolean equalsColumnProperty(String colName, String propName) { return colName.replaceAll("_", "").equalsIgnoreCase(propName); } }
DbConnector.java
import java.io.Closeable; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import org.apache.commons.dbutils.BasicRowProcessor; import org.apache.commons.dbutils.DbUtils; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.ResultSetHandler; import org.apache.commons.dbutils.RowProcessor; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; public class DbConnector implements Closeable { private Connection connection = null; private QueryRunner queryRunner = null; @Override public void close() { try { if (this.connection != null && !this.connection.isClosed()) { DbUtils.closeQuietly(this.connection); } } catch (SQLException e) { e.printStackTrace(); } } public void initialize(String dbUrl, String dbUserId, String dbPassword) throws Exception { Class.forName("com.mysql.jdbc.Driver"); this.queryRunner = new QueryRunner(); // DB接続 this.connection = DriverManager.getConnection(dbUrl, dbUserId, dbPassword); } public void beginTransaction() throws SQLException { this.connection.setAutoCommit(false); } public void commit() { DbUtils.commitAndCloseQuietly(this.connection); } public void rollback() { DbUtils.rollbackAndCloseQuietly(this.connection); } /** * BeanListHandlerのサンプル */ public <T> T selectUnique(Class<T> targetClass, String query, Object... parameters) throws SQLException { RowProcessor rp = new BasicRowProcessor(new EmployeeBeanProcessor()); BeanHandler<T> beanHandler = new BeanHandler<T>(targetClass, rp); return (T) this.queryRunner.query(this.connection, query, beanHandler, parameters); } /** * BeanListHandlerのサンプル */ public <T> List<T> selectList(Class<T> targetClass, String query, Object... parameters) throws SQLException { RowProcessor rp = new BasicRowProcessor(new EmployeeBeanProcessor()); ResultSetHandler<List<T>> resultSetHandlers = new BeanListHandler<T>(targetClass, rp); return (List<T>) this.queryRunner.query(this.connection, query, resultSetHandlers, parameters); } /** * ScalarHandlerのサンプル */ public Long selectLongValue(String query, Object... parameters) throws SQLException { ScalarHandler<Long> resultSetHandler = new ScalarHandler<Long>(1); return this.queryRunner.query(this.connection, query, resultSetHandler, parameters); } /** * QueryRunner.updateのサンプル */ public Long insert(String query, String... parameters) throws SQLException { PreparedStatement statement = this.connection.prepareStatement(query, java.sql.Statement.RETURN_GENERATED_KEYS); int index = 1; for (String parameter : parameters) { // FIXME if (parameter instanceof String) { statement.setString(index, parameter); } else { statement.setObject(index, parameter); } index++; } // 追加 statement.executeUpdate(); // auto-incrementの値取得 Long returnValue = Long.MIN_VALUE; ResultSet rs = statement.getGeneratedKeys(); if (rs.next()) { returnValue = rs.getLong(1); } return returnValue; } /** * QueryRunner.updateのサンプル */ public void update(String query, Object... parameters) throws SQLException { this.queryRunner.update(connection, query, parameters); } }
Main.java
実際の使用例import java.util.List; public class Main { public static void main(String[] args) { try (DbConnector dbConnector = new DbConnector()) { dbConnector.initialize("jdbc:mysql://localhost:3306/sampledb", "root", "password"); try { // オートコミットを無効 dbConnector.beginTransaction(); // SELECTサンプル System.out.println("---登録データ---"); List<EmployeeDao> people1 = dbConnector.selectList(EmployeeDao.class, "SELECT * FROM employee"); print(people1); // INSERTサンプル String query = "INSERT INTO employee (emp_name, birth_date) VALUES (?, ?)"; dbConnector.insert(query, "Coco", "2010/1/22"); dbConnector.insert(query, "Andy", "1991/5/12"); // UPDATEサンプル dbConnector.update("UPDATE employee SET emp_name = ? WHERE birth_date = ?", "Ken", "2000/11/21"); // 更新結果確認 System.out.println("---更新結果---"); List<EmployeeDao> people2 = dbConnector.selectList(EmployeeDao.class, "SELECT * FROM employee"); print(people2); // commit dbConnector.rollback(); } catch (Exception ex) { dbConnector.rollback(); ex.printStackTrace(); throw ex; } } catch (Exception e) { e.printStackTrace(); } } private static void print(List<EmployeeDao> employees) { for (EmployeeDao employee : employees) { System.out.println("************"); System.out.println(employee.getId()); System.out.println(employee.getEmpName()); System.out.println(employee.getBirthDate()); System.out.println("************"); } } }
参考文献
http://blog.utils.jp/2008/04/dbutils.htmlhttp://www.atmarkit.co.jp/ait/articles/0411/17/news107.html