いちをう、
GenericDaoインターフェースとImpl
GenericsでCRUD操作の定義
package etc9.dao; import java.io.Serializable; public interface GenericDao<T, PK extends Serializable> { public T get(PK id); public PK sava(T entity); public void update(T entity); public void delete(T entity); }
GenericDaoの実装。実際の処理は hibernateTemplate に委譲。typeフィールドには、ごにゃごにゃやって、T 型のクラスを格納。
package etc9.dao; import java.io.Serializable; import java.lang.reflect.ParameterizedType; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.orm.hibernate3.HibernateTemplate; public class GenericDaoImpl <T, PK extends Serializable> implements GenericDao<T, PK> { @SuppressWarnings("unchecked") private final Class<T> type = (Class<T>)((ParameterizedType)getClass() .getGenericSuperclass()).getActualTypeArguments()[0]; protected Class<T> getType() { return type; } private HibernateTemplate hibernateTemplate; @Autowired(required=true) public void setSessionFactory(SessionFactory sessionFactory) { this.hibernateTemplate = new HibernateTemplate(sessionFactory); } public HibernateTemplate getHibernateTemplate() { return hibernateTemplate; } @Override @SuppressWarnings("unchecked") public T get(PK id) { return (T) hibernateTemplate.get(getType(), id); } @Override @SuppressWarnings("unchecked") public PK sava(T entity) { return (PK) hibernateTemplate.save(entity); } @Override public void update(T entity) { hibernateTemplate.update(entity); } @Override public void delete(T entity) { hibernateTemplate.delete(entity); } }
CustomerDaoと実装クラス
package etc9.dao; import etc9.domain.Customer; public interface CustomerDao extends GenericDao<Customer, Long> { }
package etc9.dao; import org.springframework.stereotype.Repository; import etc9.domain.Customer; @Repository public class CustomerDaoImpl extends GenericDaoImpl<Customer, Long> implements CustomerDao { }
以上ー
顧客エンティティ
では、永続化対象のCustomer
package etc9.domain; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity public class Customer { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String address; public Customer() {} public Customer(String name, String address) { this.name = name; this.address = address; } ・・・以下アクセッサー }
applicationContext.xml
勝手にspringにスキャンさせまっす
<?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:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <context:component-scan base-package="etc9.dao"/> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="org.h2.Driver"/> <property name="url" value="jdbc:h2:tcp://localhost:9092/spring"/> <property name="username" value="sa"/> <property name="password" value=""/> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="hibernateProperties"> <value> hibernate.dialect = org.hibernate.dialect.H2Dialect hibernate.show_sql = true hibernate.hbm2ddl.auto = create </value> </property> <property name="annotatedClasses"> <list><value>etc9.domain.Customer</value></list> </property> </bean> </beans>
テストケース
動作確認だけ・・
package etc9.dao; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; import org.junit.*; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import etc9.domain.Customer; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"/applicationContext.xml"}) public class CustomerDaoTest { @Autowired private CustomerDao dao; private static org.h2.tools.Server tcpServer; @BeforeClass public static void beforeClass() throws Exception { tcpServer = org.h2.tools.Server.createTcpServer( new String[] { "-baseDir", "db\\h2", "-tcpPort", "9092" }).start(); } @AfterClass public static void afterClass() throws Exception { tcpServer.shutdown(); } @Test public void sava() throws Exception { Customer c1 = new Customer("etc9", "Tokyo"); assertThat(dao.sava(c1), is(1L)); c1 = dao.get(1L); assertThat(c1.getName(), is("etc9")); c1.setAddress("NY"); dao.update(c1); dao.delete(c1); } }
こんなSQL吐きよった
Hibernate: insert into Customer (id, address, name) values (null, ?, ?) Hibernate: select customer0_.id as id0_0_, customer0_.address as address0_0_, customer0_.name as name0_0_ from Customer customer0_ where customer0_.id=? Hibernate: update Customer set address=?, name=? where id=? Hibernate: delete from Customer where id=?
ちなみに、SpringJUnit4ClassRunner とか使ってるので、「spring-test.jar」をクラスパスに追加する必要がある。
あと、Hibernateはアノテーション使うので、「ejb3-persistence.jar、hibernate-annotations.jar、hibernate-commons-annotations.jar」もクラスパスに追加する。その他こまごましたのは省略。