SpringMVC、MongoDBを使って簡単なWebアプリを作ってます。
まだ全部作ってはないけど、最初にハマったところをメモ。
下のようなサイトを参考にさせて頂きました。
http://journal.mycom.co.jp/articles/2010/04/09/spring5/index.html
http://d.hatena.ne.jp/fits/20110205/1296888257
あと、ソースはGitHubへUP
https://github.com/hachi7/spring-mvc-sample
前提条件(プラグインとかDBとか)は以下のとおり
- EclipseのSpringSource Tool SuiteプラグインとWTPプラグイン、M2Eプラグインをインストールする
- Mavenをインストールする
- MongoDBはDotCloudを使用。
- Spring Frameworkのバージョンは3.0.5(このへんはGitHubのpom.xmlに記載)
データアクセス周りを作る
実データの作成
データは以下のような構造を想定。コレクション名はserversとしました。
{name:'server1',
ips:['127.0.0.1', '192.168.0.1'],
os:'redhat',
soft:[ {apache:'2.2'},{java: 'update21'},{MySQL: '5.5'} ],
created: new Date(), updated:new Date()
}
{name:'server2',
ips:['127.0.0.1', '192.168.0.2'],
os:'redhat',
soft:[{apache:'2.2'} ],
created: new Date(),
updated:new Date()
}
{name:'server3',
ips:['127.0.0.1', '192.168.0.3'],
os:'Windows',
soft:[{IIS:'6.0'},{SQLServer:'2008'}],
created: new Date(),
updated:new Date()
}
DBアクセスの共通クラスを作成
以下のようなクラスを作成しました。(import文などは除く)
ポイントは以下の3つです。このようにすることで起動時にgetDataSource処理が実行されます。
- @Configuration
- このクラスをBeanに定義
- @Value
- #{db.host}でプロパティファイルから読み込み。
- @Bean
- @Autowiredした結果を設定(後述)
プロパティを読み込むようにWEB-INF/springにxmlを記述
<util:properties id="db" location="classpath:db.properties" />
DB情報を取得するクラス(クラス名はこれでいいのだろうか??)
@Configuration public class DataSource { private static final Logger logger = LoggerFactory.getLogger(DataSource.class); private static final Marker marker = MarkerFactory.getMarker(DataSource.class.getName()); private @Value("#{db.host}") String host; private @Value("#{db.port}") String port; private @Value("#{db.dbname}") String dbName; private @Value("#{db.user}") String user; private @Value("#{db.password}") String password; @Bean public DB getDataSource(){ try { Mongo m = new Mongo(host, Integer.parseInt(port)); DB db = m.getDB(dbName); boolean isAuth = db.authenticate(user, password.toCharArray()); if(!isAuth){ logger.error("can't auth mongodb"); return null; }else{ logger.debug("can auth mongodb"); } return db; } catch (NumberFormatException e) { logger.error(marker, e.getMessage(), e); } catch (UnknownHostException e) { logger.error(marker, e.getMessage(), e); } catch (MongoException e) { logger.error(marker, e.getMessage(), e); } return null; } }
getDataSourceで取得した結果をdbへ設定しています。
各Controllerクラスはこれらを継承することにより、楽にDBに接続できます。
@Component public class DBController { @Autowired private DB db; public DB getDb(){ return db; } }
(2011/08/24追記 MongoDBからデータを取得するクラスを書いてなかったです。)
データアクセス周りその2 MongoDBからデータを取得する
MongoDBからデータを取得するDAOクラスのポイントは、
com.mongodb.DBクラスからgetCollectionで対象のコレクション(RDBMSでいうテーブル)を選択して、
findメソッドの結果をDBCursorへ入れています。
DBCollection collection = db.getCollection(COLLECTION_NAME); DBCursor cursor = collection.find().sort(new BasicDBObject("created", 1));
collection.find().sort()のコードだけ見ると、よくよく考えたら、カーソル(ポインタ)しかJVMへは持ってないから、ソートコストもDBにかかるのか。
これってfindの結果をJVMメモリ上へいれて、その中でソートをやってるのでしょうか?
RDBMSだとソートコストはDBサーバになるけど、ソートのコストはどこにかかるのかなぁ?
教えてえらい人