ロッドジョンソンて目がパッチリしているよ!
と伝えたかった(違
- テーブルとテーブルの関係を管理するテーブルをつくってみる
- IDをKeyにしてDBにインクリメントさせる。その際にnullをセットするのでIDの型をIntegerとする。
- HSQLDBの「call identity()」というものを使ってみる。ここにAOPが使えそう。
Table定義
CREATE TABLE AUTHOR (authorId INTEGER IDENTITY, name VARCHAR(20), description VARCHAR(30)); CREATE TABLE BOOK_INFO (bookInfoId INTEGER IDENTITY, isbn VARCHAR(20), title VARCHAR(50), UNIQUE (isbn)); CREATE TABLE AUTHOR_BOOK_INFO_RELATION (authorId INTEGER, bookInfoId INTEGER, FOREIGN KEY (authorId) REFERENCES AUTHOR (authorId) ON DELETE CASCADE, FOREIGN KEY (bookInfoId) REFERENCES BOOK_INFO (bookInfoId) ON DELETE CASCADE, UNIQUE (authorId, bookInfoId));
Entity
package sample.reading.entity; import java.io.Serializable; public class Author implements Serializable { public static final String TABLE = "AUTHOR"; private Integer authorId; private String name; private String description; public Author() { } //setter & getter }
package sample.reading.entity; import java.io.Serializable; public class BookInfo implements Serializable { public static final String TABLE = "BOOK_INFO"; private Integer bookInfoId; private String title; private String isbn; public BookInfo() { } //setter & getter }
package sample.reading.entity; import java.io.Serializable; public class AuthorBookInfoRelation implements Serializable{ public static final String TABLE = "AUTHOR_BOOK_INFO_RELATION"; public static final int author_RELNO = 0; public static final int bookInfo_RELNO = 1; private Integer authorId; private Integer bookInfoId; private Author author; private BookInfo bookInfo; //setter & getter
Dao
package sample.reading.dao; import java.util.List; import sample.reading.entity.*; public interface AuthorDao { public Class BEAN = Author.class; public List getAllAuthors(); public void insert(Author author); public void update(Author author); public void delete(Author author); }
package sample.reading.dao; import java.util.List; import sample.reading.entity.BookInfo; public interface BookInfoDao { public Class BEAN = BookInfo.class; public List getAllBookInfo(); public void insert(BookInfo bookInfo); public void update(BookInfo bookInfo); public void delete(BookInfo bookInfo); }
package sample.reading.dao; import sample.reading.entity.*; public interface AuthorBookInfoRelationDao { public Class BEAN = AuthorBookInfoRelation.class; public List getAll(); public void insert(AuthorBookInfoRelation authorBookInfoRelation); public void update(AuthorBookInfoRelation authorBookInfoRelation); public void delete(AuthorBookInfoRelation authorBookInfoRelation); }
Interceptor:insertのときcall identity()を実行してBeanにセットする
package sample.reading.aop; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.seasar.extension.jdbc.SelectHandler; import org.seasar.framework.beans.BeanDesc; import org.seasar.framework.beans.PropertyDesc; import org.seasar.framework.beans.impl.BeanDescImpl; public class IdentitySetInterceptor implements MethodInterceptor { private SelectHandler selectHandler; private String propertyName; public IdentitySetInterceptor() { } /** * @return Returns the selectHandler. */ public SelectHandler getSelectHandler() { return selectHandler; } /** * @param selectHandler The selectHandler to set. */ public void setSelectHandler(SelectHandler selectHandler) { this.selectHandler = selectHandler; } /** * @return Returns the propertyName. */ public String getPropertyName() { return propertyName; } /** * @param propertyName The propertyName to set. */ public void setPropertyName(String propertyName) { this.propertyName = propertyName; } public Object invoke(MethodInvocation invocation) throws Throwable { Object ret = invocation.proceed(); Object args = invocation.getArguments(); if (args.length > 1) { throw new IllegalArgumentException("invocation='" + invocation + "'"); } BeanDesc beanDesc = new BeanDescImpl(args[0].getClass()); if (beanDesc.hasPropertyDesc(propertyName)) { PropertyDesc propertyDesc = beanDesc.getPropertyDesc(propertyName); propertyDesc.setValue(args[0], getIdentity()); } return ret; } private Object getIdentity() { return selectHandler.execute(new Object{}); } }
dicon
"call identity()" "authorId" dao.interceptor dao.interceptor "bookInfoId" dao.interceptor
Client
package sample.reading.client; import java.util.List; import org.seasar.framework.container.S2Container; import org.seasar.framework.container.factory.S2ContainerFactory; import sample.reading.dao.AuthorBookInfoRelationDao; import sample.reading.dao.AuthorDao; import sample.reading.dao.BookInfoDao; import sample.reading.entity.Author; import sample.reading.entity.AuthorBookInfoRelation; import sample.reading.entity.BookInfo; public class Client { private static final String PATH = "sample/reading/dicon/dao.dicon"; private static BookInfoDao bookInfoDao; private static AuthorDao authorDao; private static AuthorBookInfoRelationDao relationDao; public static void main(String[] args) { S2Container container = S2ContainerFactory.create(PATH); container.init(); try { bookInfoDao = (BookInfoDao)container.getComponent(BookInfoDao.class); authorDao = (AuthorDao)container.getComponent(AuthorDao.class); relationDao = (AuthorBookInfoRelationDao)container .getComponent(AuthorBookInfoRelationDao.class); run(); } finally { container.destroy(); } } private static void run() { Author author = new Author(); author.setName("Rod Johnson"); author.setDescription("Springの人"); authorDao.insert(author); author.setDescription("目がパッチリ"); authorDao.update(author); BookInfo bookInfo = new BookInfo(); bookInfo.setTitle("J2EE Development without EJB"); bookInfo.setIsbn("0-7645-5831-5"); bookInfoDao.insert(bookInfo); AuthorBookInfoRelation relation = new AuthorBookInfoRelation(); relation.setAuthorId(author.getAuthorId()); relation.setBookInfoId(bookInfo.getBookInfoId()); relationDao.insert(relation); List list = relationDao.getAll(); } }
実行されるSQLなど
INSERT INTO AUTHOR (name, description, authorId) VALUES('Rod Johnson', 'Springの人', null) call identity() UPDATE AUTHOR SET name = 'Rod Johnson', description = '目がパッチリ' WHERE authorid = 28 INSERT INTO BOOK_INFO (title, isbn, bookInfoId) VALUES('J2EE Development without EJB', '0-7645-5831-5', null) call identity() INSERT INTO AUTHOR_BOOK_INFO_RELATION (authorId, bookInfoId) VALUES(28, 28) SELECT AUTHOR_BOOK_INFO_RELATION.authorId, AUTHOR_BOOK_INFO_RELATION.bookInfoId, author.name AS name_0, author.description AS description_0, bookInfo.title AS title_1, bookInfo.isbn AS isbn_1 FROM AUTHOR_BOOK_INFO_RELATION LEFT OUTER JOIN AUTHOR author ON AUTHOR_BOOK_INFO_RELATION.authorid = author.authorid LEFT OUTER JOIN BOOK_INFO bookInfo ON AUTHOR_BOOK_INFO_RELATION.bookinfoid = bookInfo.bookinfoid
idをKeyにするってやったことがないので勝手がわからない。仕事ではコードが思いっきりKeyですから。計画系なのに...。自動でincrementしたらincrementされた値をとってこないと他のTableに更新できないのでcall identity()を使う必要があると思いました。そういうものでいいの?
これを見かけた方、おかしいところは突っ込んでくださいませ。