tamuraです。
今回はDropwizardで複数のDAOを使った場合のトランザクション制御をやって行きます。
構成の変更
AbstractDAOの作成
DAOの中で別のDAOを生成できるように、基底クラスを作ります。 またトランザクション制御を行えるようにしてあります。
package com.github.tamurashingo.dropwizard.helloworld.dao;
import org.skife.jdbi.v2.sqlobject.CreateSqlObject;
import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
public abstract class AbstractDAO implements Transactional<AbstractDAO> {
@CreateSqlObject
public abstract MessageDAO createMessageDAO();
}
MessageDAOの変更
今まであったMessageDAO
をinterface
からabstract class
に変更します。
あと、今まで実装(?)はMessageDAOMySQLImpl
で行っていたのですが、ちょっとうまくできなかったのでこのクラスでSQLを実装しています。
package com.github.tamurashingo.dropwizard.helloworld.dao;
import org.skife.jdbi.v2.sqlobject.Bind;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
import org.skife.jdbi.v2.sqlobject.customizers.Mapper;
import org.skife.jdbi.v2.sqlobject.customizers.SingleValueResult;
import com.github.tamurashingo.dropwizard.helloworld.Saying;
import com.github.tamurashingo.dropwizard.helloworld.dao.mapper.SayingMapper;
import com.google.common.base.Optional;
public abstract class MessageDAO extends AbstractDAO {
@SingleValueResult(Saying.class)
@SqlQuery(
" select "
+ " message "
+ " from "
+ " m_message "
+ " where "
+ " id = :messageId "
)
@Mapper(SayingMapper.class)
public abstract Optional<Saying> getMessage(@Bind("messageId") String messageId);
@SqlUpdate(
" update "
+ " m_message "
+ " set "
+ " message = :message "
+ " where "
+ " id = :messageId "
)
public abstract void updateMessage(@Bind("messageId") String messageId, @Bind("message") String message);
}
HelloWorldResourceの変更
まずはコンストラクタでAbstractDAO
を受け取ります。
@Path("/hello-world")
@Produces(MediaType.APPLICATION_JSON)
public class HelloWorldResource {
private AbstractDAO dao;
private Saying defaultValue = new Saying("hello world");
public HelloWorldResource(AbstractDAO dao) {
this.dao = dao;
}
つぎにsayHello
メソッドを変更します。
今までMessageDAO
をそのまま使っていましたが、AbstractDAO#createMessageDAO
でMessageDAO
を生成するようにします。
@GET
public Saying sayHello(@QueryParam("messageid") Optional<String> messageId) {
if (messageId.isPresent()) {
MessageDAO messageDAO = dao.createMessageDAO();
return messageDAO.getMessage(messageId.get()).or(defaultValue);
}
else {
return defaultValue;
}
}
updateHello
も同じように変更します。
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Saying updateHello(MultivaluedMap<String, String> formParams) {
final String message = formParams.getFirst("message");
dao.inTransaction(new Transaction<Void, AbstractDAO>() {
@Override
public Void inTransaction(AbstractDAO transactional, TransactionStatus status) throws Exception {
transactional.begin();
MessageDAO messageDAO = transactional.createMessageDAO();
messageDAO.updateMessage("00001", message);
transactional.commit();
return null;
}
});
return sayHello(Optional.of("00001"));
}
HelloWorldApplicationの変更
HelloWorldResource
の呼び出し方を変更します。
具体的にはAbstractDAO
を渡すように変更しています。
@Override
public void run(HelloWorldConfiguration configuration, Environment environment) throws Exception {
final DBIFactory factory = new DBIFactory();
final DBI jdbi = factory.build(environment, configuration.getDataSourceFactory(), "helloworlddb");
final AbstractDAO dao = jdbi.onDemand(AbstractDAO.class);
environment.jersey().register(new HelloWorldResource(dao));
}
これで実行すると、前回と同じ結果が得られます。
テーブルの追加
migrations.xmlを使ってテーブルを追加します。
M_MESSAGE
を更新した際にバックアップを格納するテーブルです。
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<changeSet id="1" author="tamura.shingo">
<createTable tableName="m_message">
<column name="id" type="char(5)">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="message" type="varchar(255)" />
</createTable>
</changeSet>
<changeSet id="2" author="tamura.shingo">
<insert tableName="m_message">
<column name="id" value="00001" />
<column name="message" value="hello" />
</insert>
<insert tableName="m_message">
<column name="id" value="00002" />
<column name="message" value="こんにちは" />
</insert>
<insert tableName="m_message">
<column name="id" value="00003" />
<column name="message" value="bonjour" />
</insert>
</changeSet>
<changeSet id="3" author="tamura.shingo">
<createTable tableName="h_message">
<column name="history_id" type="BIGINT" autoIncrement="true">
<constraints primaryKey="true" nullable="false" />
</column>
<column name="id" type="char(5)" />
<column name="message" type="varchar(255)" />
<column name="updateDate" type="datetime" />
</createTable>
</changeSet>
</databaseChangeLog>
これをマイグレーションします。
$ java -jar target/helloworld-0.0.1-SNAPSHOT.jar db migrate hello-world.yml
INFO [2015-06-12 15:16:17,876] liquibase: Successfully acquired change log lock
INFO [2015-06-12 15:16:18,351] liquibase: Reading from helloworld.DATABASECHANGELOG
INFO [2015-06-12 15:16:18,384] liquibase: migrations.xml: 3::tamura.shingo: Table h_message created
INFO [2015-06-12 15:16:18,385] liquibase: migrations.xml: 3::tamura.shingo: ChangeSet migrations.xml::3::tamura.shingo ran successfully in 9ms
INFO [2015-06-12 15:16:18,395] liquibase: Successfully released change log lock
DAOの追加
このH_MESSAGE
を処理するDAOを作っていきます。
こんな感じです。
package com.github.tamurashingo.dropwizard.helloworld.dao;
import org.skife.jdbi.v2.sqlobject.Bind;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
public abstract class HistoryDAO extends AbstractDAO {
@SqlUpdate(
" insert into "
+ " h_message "
+ " ( "
+ " id, "
+ " message, "
+ " updateDate "
+ " ) "
+ " values ( "
+ " :messageId, "
+ " :message, "
+ " now() "
+ " ) "
)
public abstract void backupMessage(@Bind("messageId") String messageId, @Bind("message") String message);
}
また、AbstractDAO
にこのHistoryDAO
を生成する処理を追加しておきます。
package com.github.tamurashingo.dropwizard.helloworld.dao;
import org.skife.jdbi.v2.sqlobject.CreateSqlObject;
import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
public abstract class AbstractDAO implements Transactional<AbstractDAO> {
@CreateSqlObject
public abstract MessageDAO createMessageDAO();
@CreateSqlObject
public abstract HistoryDAO createHistoryDAO();
}
メインロジック
以下の要領で作っていきます。
00001
のmessage
を更新m_message
に既存の値があった場合は、h_message
に入れるexception
という更新値がきた場合は例外を発生させる(rollbackの確認用)@POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public Saying updateHello(MultivaluedMap<String, String> formParams) { final String message = formParams.getFirst("message"); dao.inTransaction(new Transaction<Void, AbstractDAO>() { @Override public Void inTransaction(AbstractDAO transactional, TransactionStatus status) throws Exception { transactional.begin(); MessageDAO messageDAO = transactional.createMessageDAO(); Optional<Saying> oldMessage = messageDAO.getMessage("00001"); if (oldMessage.isPresent()) { Saying oldMessageContent = oldMessage.get(); HistoryDAO historyDAO = transactional.createHistoryDAO(); historyDAO.backupMessage("00001", oldMessageContent.getGreeting()); } messageDAO.updateMessage("00001", message); if (Objects.equal(message, "exception")) { throw new Exception("このタイミングで例外かよ。。。。"); } transactional.commit(); return null; } }); return sayHello(Optional.of("00001")); }
これで完成です。
実行
起動します。
$ java -jar target/helloworld-0.0.1-SNAPSHOT.jar server hello-world.yml
INFO [2016-07-13 17:48:58,904] org.eclipse.jetty.util.log: Logging initialized @798ms
INFO [2016-07-13 17:48:59,032] io.dropwizard.server.ServerFactory: Starting HelloWorldApplication
INFO [2016-07-13 17:48:59,073] org.eclipse.jetty.setuid.SetUIDListener: Opened application@ab7a938{HTTP/1.1}{0.0.0.0:8080}
INFO [2016-07-13 17:48:59,074] org.eclipse.jetty.setuid.SetUIDListener: Opened admin@3faf2e7d{HTTP/1.1}{0.0.0.0:8081}
INFO [2016-07-13 17:48:59,076] org.eclipse.jetty.server.Server: jetty-9.2.z-SNAPSHOT
INFO [2016-07-13 17:48:59,674] io.dropwizard.jersey.DropwizardResourceConfig: The following paths were found for the configured resources:
GET /hello-world (com.github.tamurashingo.dropwizard.helloworld.HelloWorldResource)
POST /hello-world (com.github.tamurashingo.dropwizard.helloworld.HelloWorldResource)
INFO [2016-07-13 17:48:59,678] org.eclipse.jetty.server.handler.ContextHandler: Started i.d.j.MutableServletContextHandler@359b650b{/,null,AVAILABLE}
INFO [2016-07-13 17:48:59,683] io.dropwizard.setup.AdminEnvironment: tasks =
POST /tasks/log-level (io.dropwizard.servlets.tasks.LogConfigurationTask)
POST /tasks/gc (io.dropwizard.servlets.tasks.GarbageCollectionTask)
INFO [2016-07-13 17:48:59,687] org.eclipse.jetty.server.handler.ContextHandler: Started i.d.j.MutableServletContextHandler@46d9aec8{/,null,AVAILABLE}
INFO [2016-07-13 17:48:59,739] org.eclipse.jetty.server.ServerConnector: Started application@ab7a938{HTTP/1.1}{0.0.0.0:8080}
INFO [2016-07-13 17:48:59,752] org.eclipse.jetty.server.ServerConnector: Started admin@3faf2e7d{HTTP/1.1}{0.0.0.0:8081}
INFO [2016-07-13 17:48:59,752] org.eclipse.jetty.server.Server: Started @1647ms
更新
$ curl -d message=GoodAfternoon -i -L http://localhost:8080/hello-world
HTTP/1.1 200 OK
Date: Wed, 13 Jul 2016 17:51:48 GMT
Content-Type: application/json
Content-Length: 28
{"greeting":"GoodAfternoon"}
ログ
0:0:0:0:0:0:0:1 - - [13/7/2016:17:51:48 +0000] "POST /hello-world HTTP/1.1" 200 28 "-" "curl/7.30.0" 10
MySQL
mysql> select * from m_message;
+-------+---------------+
| id | message |
+-------+---------------+
| 00001 | GoodAfternoon |
| 00002 | こんにちは |
| 00003 | bonjour |
+-------+---------------+
3 rows in set (0.00 sec)
mysql> select * from h_message;
+------------+-------+---------+---------------------+
| history_id | id | message | updateDate |
+------------+-------+---------+---------------------+
| 1 | 00001 | hello | 2016-07-14 02:51:48 |
+------------+-------+---------+---------------------+
1 row in set (0.00 sec)
例外発生
exception
というキーワードを与えて、内部で例外を発生させてみます。
$ curl -d message=exception -i -L http://localhost:8080/hello-world
HTTP/1.1 500 Internal Server Error
Date: Wed, 13 Jul 2016 17:53:12 GMT
Content-Type: application/json
Content-Length: 110
{"code":500,"message":"There was an error processing your request. It has been logged (ID 1cf9824636cfbf6c)."}
ログ
0:0:0:0:0:0:0:1 - - [13/7/2016:17:53:12 +0000] "POST /hello-world HTTP/1.1" 500 110 "-" "curl/7.30.0" 11
ERROR [2016-07-13 17:53:12,657] io.dropwizard.jersey.errors.LoggingExceptionMapper: Error handling a request: 1cf9824636cfbf6c
! java.lang.Exception: このタイミングで例外かよ。。。。
! at com.github.tamurashingo.dropwizard.helloworld.HelloWorldResource$1.inTransaction(HelloWorldResource.java:66) ~[helloworld-0.0.1-SNAPSHOT.jar:na]
! at com.github.tamurashingo.dropwizard.helloworld.HelloWorldResource$1.inTransaction(HelloWorldResource.java:50) ~[helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.skife.jdbi.v2.sqlobject.InTransactionHandler$1.inTransaction(InTransactionHandler.java:37) ~[helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.skife.jdbi.v2.tweak.transactions.LocalTransactionHandler.inTransaction(LocalTransactionHandler.java:184) ~[helloworld-0.0.1-SNAPSHOT.jar:na]
! ... 62 common frames omitted
! Causing: org.skife.jdbi.v2.exceptions.TransactionFailedException: Transaction failed do to exception being thrown from within the callback. See cause for the original exception.
! at org.skife.jdbi.v2.tweak.transactions.LocalTransactionHandler.inTransaction(LocalTransactionHandler.java:195) ~[helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.skife.jdbi.v2.BasicHandle.inTransaction(BasicHandle.java:327) ~[helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.skife.jdbi.v2.sqlobject.InTransactionHandler.invoke(InTransactionHandler.java:32) ~[helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.skife.jdbi.v2.sqlobject.SqlObject.invoke(SqlObject.java:175) ~[helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.skife.jdbi.v2.sqlobject.SqlObject$1.intercept(SqlObject.java:75) ~[helloworld-0.0.1-SNAPSHOT.jar:na]
! at com.github.tamurashingo.dropwizard.helloworld.dao.AbstractDAO$$EnhancerByCGLIB$$631a84fe.inTransaction(<generated>) ~[helloworld-0.0.1-SNAPSHOT.jar:na]
! at com.github.tamurashingo.dropwizard.helloworld.HelloWorldResource.updateHello(HelloWorldResource.java:50) ~[helloworld-0.0.1-SNAPSHOT.jar:na]
! at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_31]
! at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_31]
! at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_31]
! at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_31]
! at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81) ~[helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:164) ~[helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:181) ~[helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:203) ~[helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:101) ~[helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389) ~[helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347) ~[helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102) ~[helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:305) ~[helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.glassfish.jersey.internal.Errors.process(Errors.java:315) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.glassfish.jersey.internal.Errors.process(Errors.java:297) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.glassfish.jersey.internal.Errors.process(Errors.java:267) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:288) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1110) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:401) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:386) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:335) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:222) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at io.dropwizard.jetty.NonblockingServletHolder.handle(NonblockingServletHolder.java:49) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.eclipse.jetty.servlets.UserAgentFilter.doFilter(UserAgentFilter.java:83) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.eclipse.jetty.servlets.GzipFilter.doFilter(GzipFilter.java:300) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at io.dropwizard.jetty.BiDiGzipFilter.doFilter(BiDiGzipFilter.java:134) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at io.dropwizard.servlets.ThreadNameFilter.doFilter(ThreadNameFilter.java:29) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at io.dropwizard.jersey.filter.AllowedMethodsFilter.handle(AllowedMethodsFilter.java:44) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at io.dropwizard.jersey.filter.AllowedMethodsFilter.doFilter(AllowedMethodsFilter.java:39) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at com.codahale.metrics.jetty9.InstrumentedHandler.handle(InstrumentedHandler.java:240) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at io.dropwizard.jetty.RoutingHandler.handle(RoutingHandler.java:51) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.eclipse.jetty.server.handler.RequestLogHandler.handle(RequestLogHandler.java:95) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.eclipse.jetty.server.handler.StatisticsHandler.handle(StatisticsHandler.java:159) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.eclipse.jetty.server.Server.handle(Server.java:497) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555) [helloworld-0.0.1-SNAPSHOT.jar:na]
! at java.lang.Thread.run(Thread.java:745) [na:1.8.0_31]
MySQL
ちゃんとrollbackされていました。
mysql> select * from m_message;
+-------+---------------+
| id | message |
+-------+---------------+
| 00001 | GoodAfternoon |
| 00002 | こんにちは |
| 00003 | bonjour |
+-------+---------------+
3 rows in set (0.00 sec)
mysql> select * from h_message;
+------------+-------+---------+---------------------+
| history_id | id | message | updateDate |
+------------+-------+---------+---------------------+
| 1 | 00001 | hello | 2016-07-14 02:51:48 |
+------------+-------+---------+---------------------+
1 row in set (0.00 sec)
まとめ
以下の方法でDropwizard JDBIで複数のDAOを扱うことができました。
AbstractDAO
で各DAOを生成するメソッドを宣言する- 各DAOは
AbstractDAO
を基底クラスにする