DBアクセスのサンプル
Spring frameworkを使うとDBまわりのコードがすっきりするらしいので、練習兼メモがてらサンプルを書いてみた。
RDBMSは何でも良いのだけどPostgreSQLで。適当なテーブルを用意しておく。
sample=# \c psql (8.4.4) You are now connected to database "sample". sample=# \d users Table "public.users" Column | Type | Modifiers --------+-------------------+----------- id | integer | name | character varying | age | integer |
ValueObject(っていうの?)はこんなの。
public class User { private final int id; private final String name; private final int age; public User(int id, String name, int age) { this.id = id; this.name = name; this.age = age; } public int getId() { return id; } public String getName() { return name; } public int getAge() { return age; } }
で、肝心のDAOはこんな感じ。PreparedStatementが無いし、毎度毎度の例外処理も無くてすっきり。JdbcDaoSupport、MappingSqlQuery、SqlUpdate 辺りのクラスが鍵。
import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; import java.util.List; import javax.sql.DataSource; import org.springframework.jdbc.core.SqlParameter; import org.springframework.jdbc.core.support.JdbcDaoSupport; import org.springframework.jdbc.object.MappingSqlQuery; import org.springframework.jdbc.object.SqlUpdate; public class UserDao extends JdbcDaoSupport { private static class FindUser extends MappingSqlQuery { private static final String SQL = "SELECT id, name, age FROM users"; private FindUser(DataSource ds) { super(ds, SQL); } @Override protected User mapRow(ResultSet rs, int rowNum) throws SQLException { return new User(rs.getInt("id"), rs.getString("name"), rs.getInt("age")); } } private static class InsertUser extends SqlUpdate { private static final String SQL = "INSERT INTO users (id, name, age)" + "VALUES (NEXTVAL('seq_users_id'), ?, ?)"; private InsertUser(DataSource ds) { super(ds, SQL); declareParameter(new SqlParameter("name", Types.VARCHAR)); declareParameter(new SqlParameter("age", Types.INTEGER)); } } private FindUser fu = null; private InsertUser iu = null; protected void initDao() { this.fu = new FindUser(getDataSource()); this.iu = new InsertUser(getDataSource()); } public List<User> findUser() { @SuppressWarnings("unchecked") List<User> users = fu.execute(); return users; } public void insertUser(String name, int age) { Object[] params = { name, age }; iu.update(params); } }
で、これらを利用するコードはこちら。
import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; public class Main { public static void main(String[] argv) { Resource resource = new ClassPathResource("applicationContext.xml"); BeanFactory bf = new XmlBeanFactory(resource); UserDao udao = (UserDao) bf.getBean("userDao"); udao.insertUser("Foo", 64); udao.insertUser("Bar", 72); for (User user : udao.findUser()) { System.out.printf("%3d: %s: %3d\n", user.getId(), user.getName(), user.getAge()); } } }
あと、DIの設定はこれ。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd"> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName"> <value>org.postgresql.Driver</value></property> <property name="url"> <value>jdbc:postgresql://localhost/sample</value></property> <property name="username"> <value>komamitsu</value></property> </bean> <bean id="userDao" class="UserDao"> <property name="dataSource" ref="dataSource"></property> </bean> </beans>
これを実行すると。
1: Foo: 64 2: Bar: 72
となり成功。
ちょっと悔しいのは、UserDao.findUser()で警告を消すために@SuppressWarnings("unchecked")を使っていること。もう一回, Effective Javaのジェネリクスの章を読み直して、再挑戦したい。