さわらブログ

さわら(@xhiroga)の技術ブログ

【備忘録】iBatis、log4j、依存性注入

現場で使っていて理解したことの棚卸し。

iBatis

JavaのO/Rマッパー。
勘違いしていたが、iBatisとDAOオブジェクトは直接関係ない。
iBatisは「if文などでカスタマイズ可能なSQLを」「入出力のパラメータをDTOオブジェクトにまとめてマッピング可能にし」「JDBCを意識しないで発行する」ためのライブラリーである。そうした機能は、iBatisが提供するsqlmapインスタンスのメソッドから利用可能。
ただし、アーキテクチャの問題として、SQLDTOオブジェクトをマッピングしたXMLファイルごとにデータアクセスのためのオブジェクト(内部でsqlmapインスタンスを使用)を定義することは考えられる。
そのせいでiBatisとDAOが依存していると勘違いしていた。

SqlMapConfig.xmlの設定を読み込み、アプリケーション内で一つだけのインスタンスを持つ(これは強制ではなくパターンの問題かも?)ただし、複数のDBにアクセスできるよう、SQL発行に使用するコネクションはアプリケーション起動後に変更可能である。
使用するSQLはSqlMap.xml内に定義するが、複数のXMLファイルに分散して記載することもできる。

普段生のSQLを触るので、PythonでSQLAlchemyを触った時よりも使いやすかった(そちらはSQL文をプログラマが設定することはなく、代わりに基本のSQLに相当するメソッドを組み合わせて利用する)

log4j

Javaはじめクロスプラットフォームで使用できるログ出力ライブラリー。
ログの重要度や出力先、形式を属性として持つLoggerインスタンスをアプリ内で生成し、ログを出力させる。
出力先、形式をそれぞれAppenders、Layoutsクラスとして定義しており、複数のLoggerインスタンス間で共有できる。
ログの出力先となるフォルダとその識別のためのIDをクラスパス直下のlog4j.xmlで管理しており、これをよく忘れて先輩に聞く(ログ出るのどこでしたっけ?)

依存性注入

クラス内で他のクラスのインスタンスが必要なときに、受け入れる変数の型をインターフェースで宣言し、肝心のインスタンスを呼び出し元に作らせたり、DIコンテナに作らせたりするパターンのこと。
他のクラスを直接参照しないことで、そのクラスのソースが完成していない状態でコンパイルをしても怒られないで済む。なので、複数人でプログラミングしているときに作業順を気にしないでよくなるそうだ。
(1機能のDelegateとServiceとDAOを別人がプログラミングすることってそんなにない気もするけど...逆に言えば部品の共有が進んでいないってことでもある。)
他にも、テストや開発環境の場合だけ参照する実装クラスを変えることが、ソースの修正なしにできる。これは嬉しいかも。

実装を見るとイメージが掴みやすいと思う。例はWikipediaより、DIコンテナを使った場合。

public static void main(String[] args) {
        IAutomatedStockTrader stockTrader =
            (IAutomatedStockTrader) DependencyManager.create(IAutomatedStockTrader.class);

参考資料

iBatis

iBATIS2/iBATIS3/mybatis各種アーカイブ・ドキュメント一覧 - Shinya’s Daily Report

log4j

Apache log4j 1.2 - Short introduction to log4j

依存性注入

依存性の注入 - Wikipedia

DI・DIコンテナ、ちゃんと理解出来てる・・? - Qiita