2008年6月2日月曜日

S2JDBCでデータベースアクセスをしてみた。(更新ping受信サーバ作成その5)

前回まででRSSの情報を読み取ることが出来ましたので、読み取った内容をどうするか? ということでデータベースに登録してみることにしました。


まずデータベースの設計です。
今回想定しているのは、新着一覧のような画面を表示することです。
以下のようにしてみました。
使用データベースはPostgresqlです。


CREATE TABLE update_entry
(
id bigint NOT NULL,
title character varying(255) NOT NULL,
link character varying(255) NOT NULL,
date timestamp without time zone NOT NULL,
weblogname character varying(255) NOT NULL,
weblogurl character varying(255) NOT NULL,
CONSTRAINT update_entry_pkey PRIMARY KEY (id)
)
WITH (OIDS=FALSE);
ALTER TABLE update_entry OWNER TO postgres;


id idです。
title 最新記事の題名です。
link 最新記事のURLです。
date 最新記事の更新時間です。
weblogname ブログの名前です。
weblogurl ブログのURLです。
ブログを表すテーブルと、記事を表すテーブルは分けた方がいいかとは思ったんですがどうせ最新しか保持しないのでブログと記事が1対1になるわけですからくっつけときました。
idはシーケンスで増加させるので以下のようなシーケンスも登録します。


CREATE SEQUENCE update_entry_id
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 5
CACHE 1;
ALTER TABLE update_entry_id OWNER TO postgres;


STARTが進んでるのは気にしないでくださいw 現在の状態のSQLを取得したらこうなってただけなんで。
次にこのテーブルに対応したエンティティクラスを作成します。
net.ukauka.xmlrpc.entity.UpdateEntry
package net.ukauka.xmlrpc.entity;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity
public class UpdateEntry {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
public Integer id;
public String title;
public String link;
@Temporal(TemporalType.TIMESTAMP)
public Date date;
public String weblogname;
public String weblogurl;
}


setter,getterは用意せずpublicフィールドにしてあります。めんどくさいんで。
フィールド名はテーブルと対応しています。
@の部分はアノテーションです。
@Idで主キーであることを表しています。
@GeneratedValue(strategy = GenerationType.SEQUENCE)はシーケンスで自動増加させる設定です。
@Temporal(TemporalType.TIMESTAMP)はDate型がデータベースのどの型に対応しているのかを設定しています。
次にデータベース接続の設定です。
jdbc.dicon

<component name="xaDataSource"
class="org.seasar.extension.dbcp.impl.XADataSourceImpl">
<property name="driverClassName">
"org.postgresql.Driver"
</property>
<property name="URL">
"jdbc:postgresql://192.168.0.1/db"
</property>
<property name="user">"user"</property>
<property name="password">"password"</property>
</component>


postgresqlへの接続設定を記述します。
s2jdbc.dicon

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN"
"http://www.seasar.org/dtd/components24.dtd">
<components>
<include path="jdbc.dicon"/>
<include path="s2jdbc-internal.dicon"/>
<component name="jdbcManager"
class="org.seasar.extension.jdbc.manager.JdbcManagerImpl">
<property name="maxRows">0</property>
<property name="fetchSize">0</property>
<property name="queryTimeout">0</property>
<property name="dialect">postgre81Dialect</property>
</component>


特に説明はないんですが、dialectをpostgresql8.1以降用に変更しました。
weblogUpdates.dicon

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN"
"http://www.seasar.org/dtd/components24.dtd">
<components>
<include path="s2jdbc.dicon"/>
<component name="weblogUpdates" class="net.ukauka.xmlrpc.service.WeblogUpdatesServiceImpl">
<meta name="xmlrpc"/>
</component>
</components>

前回までの状態に<include path="s2jdbc.dicon"/>を追加したぐらいです。
で、具体的に処理を行っている部分のコードです。
今回も必要部分のみ抜粋します。

//URLで検索
UpdateEntry entryRecord = jdbcManager
.from(UpdateEntry.class)
.where("weblogurl = ?", weblogurl)
.getSingleResult();
//存在しない場合は追加
if(entryRecord == null){
entryRecord = new UpdateEntry();
entryRecord.weblogname = weblogname;
entryRecord.weblogurl = weblogurl;
entryRecord.title = title;
entryRecord.date = date;
entryRecord.link = link;
jdbcManager.insert(entryRecord).execute();
}else{
//存在する場合は更新
entryRecord.weblogname = weblogname;
entryRecord.title = title;
entryRecord.date = date;
entryRecord.link = link;
jdbcManager.update(entryRecord).execute();
}

weblogurlで検索を行い、存在していないなら新規登録
存在するなら更新を行うという処理です。
S2JDBCの場合DAOを用意しなくてもいいので楽ですね。
今回までで、更新pingを受信して、RSSを取得し、データベースへ登録する。という一連の動作は作成できました。
更新ping自体の処理はこれで完成なんですが、ユーザからすると何をやってるのかさっぱりわかりませんw
ですので、次回はデータベースの内容を表示するという普通のWebアプリケーションの処理をやってみようと思います。

0 件のコメント:

コメントを投稿