tamuraです。
今回はDropwizardでデータベースの更新を行っていきます。
DAOの修正
DAOにUPDATEメソッドを追加します。
package com.github.tamurashingo.dropwizard.helloworld.dao;
import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
import com.github.tamurashingo.dropwizard.helloworld.Saying;
import com.google.common.base.Optional;
public interface MessageDAO extends Transactional<MessageDAO> {
public Optional<Saying> getMessage(String messageId);
public void updateMessage(String messageId, String message);
}
続いてMySQL用の実装にSQLを追加します。
package com.github.tamurashingo.dropwizard.helloworld.dao.impl;
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.MessageDAO;
import com.github.tamurashingo.dropwizard.helloworld.dao.impl.mapper.SayingMapper;
import com.google.common.base.Optional;
public interface MessageDAOMySQLImpl extends MessageDAO {
@Override
@SingleValueResult(Saying.class)
@SqlQuery(
" select "
+ " message "
+ " from "
+ " m_message "
+ " where "
+ " id = :messageId "
)
@Mapper(SayingMapper.class)
public Optional<Saying> getMessage(@Bind("messageId") String messageId);
@Override
@SqlUpdate(
" update "
+ " m_message "
+ " set "
+ " message = :message "
+ " where "
+ " id = :messageId "
)
public void updateMessage(@Bind("messageId") String messageId, @Bind("message") String message);
}
Resourceの修正
POSTでデータベースを更新する処理を追加します。 今回は単純な更新なのであまりトランザクションの意味はないのですが、このようにして書くことができます。
message
というパラメータに新しいメッセージをセットします。
ID:00001のレコードを更新するようにしています。
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Saying updateHello(MultivaluedMap<String, String> formParams) {
final String message = formParams.getFirst("message");
messageDAO.inTransaction(new Transaction<Void, MessageDAO>() {
@Override
public Void inTransaction(MessageDAO transactional, TransactionStatus status) throws Exception {
messageDAO.begin();
messageDAO.updateMessage("00001", message);
messageDAO.commit();
return null;
}
});
return sayHello(Optional.of("00001"));
}
Configurationの修正
MySQLは初期モードが自動コミットになっているので、それを外しておきます。
database:
driverClass: com.mysql.jdbc.Driver
user: root
password: password
(...省略...)
autoCommitByDefault: false
実行
POSTを使うので、cUrlで実行します。
$ curl -d message=new\ message -i -L http://localhost:8080/hello-world
HTTP/1.1 200 OK
Date: Fri, 12 Jun 2015 14:50:18 GMT
Content-Type: application/json
Content-Length: 26
Cache-Control: proxy-revalidate
Proxy-Connection: Keep-Alive
Connection: Keep-Alive
{"greeting":"new message"}
無事更新できました。
また、MySQLのコマンドラインツールからトランザクションを使って更新をしている最中に動かすと、Dropwizard側の処理がストップします。
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> update m_message set message = 'hello' where id = '00001';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
この状態でcUrlを使うとMySQLコマンドラインからcommit
かrollback
を行うまで返ってこなくなります。
$ curl -d message=new\ new\ message -i -L http://localhost:8080/hello-world
返ってきません。
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
コミットすると返ってきます。
$ curl -d message=new\\ new\\ message -i -L http://localhost:8080/hello-world
HTTP/1.1 200 OK
Date: Fri, 12 Jun 2015 14:59:16 GMT
Content-Type: application/json
Content-Length: 30
Cache-Control: proxy-revalidate
Proxy-Connection: Keep-Alive
Connection: Keep-Alive
{"greeting":"new new message"}
次回予告
今回はひとつのDAOでトランザクションを制御しました。 次回は複数のDAOでトランザクション制御をやっていきます。