■domaの特徴など
doma公式サイト
SQLファイルからSQLを読み込んで使える
SQLに必要なパラメータはコメントとして書くので
実行可能なSQLを書いておくことができる
マッピングファイルを書かなくてもいい
DBの接続情報などは設定クラスに書く
ファイルに書くことができるのかは調べてない
Daoの実装クラスなどaptを使ってコンパイル時に自動生成
実行時に動的生成するよりもレスポンスがいいとの事
そんなに変更のないクラスを実行時に毎回動的生成することに疑問を感じていたので
これはいいかも
aptについては別途調べる予定
日本語の説明が豊富
実にありがたい
■環境等
doma 1.38
sqlite 3.8.7
java 1.7
■サンプル
本家のクイックスタートを元にして
sqlite用に作ります。
●aptの設定など
aptを使ってビルド時にソースコードの生成をするので
eclipseの設定をします
1.プロジェクトのプロパティ > Javaコンパイラー > 注釈処理
注釈処理を使用可能にするにチェックを入れる
2.ファクトリーパスにdomaのjarを指定する
3.ビルドパスの設定も忘れずに
●作成するファイル
設定クラス
エンティティ
Dao
SQLファイル
●設定クラス
利用するDBの情報と接続文字列を指定します。
この例では sqlite を使うので
DialectにSqliteDialect
DataSourceのurlに jdbc:sqlite:sample.db
を指定しています
Dialectには以下が使えます
| データベース | 方言クラスの名前 |
|---|---|
| DB2 | org.seasar.doma.jdbc.dialect.Db2Dialect |
| H2 Database Engine 1.2.126 | org.seasar.doma.jdbc.dialect.H212126Dialect |
| H2 Database Engine | org.seasar.doma.jdbc.dialect.H2Dialect |
| HSQLDB | org.seasar.doma.jdbc.dialect.HsqldbDialect |
| Microsoft SQL Server 2008 | org.seasar.doma.jdbc.dialect.Mssql2008Dialect |
| Microsoft SQL Server | org.seasar.doma.jdbc.dialect.MssqlDialect |
| MySQL | org.seasar.doma.jdbc.dialect.MySqlDialect |
| Oracle Database | org.seasar.doma.jdbc.dialect.OracleDialect |
| PostgreSQL | org.seasar.doma.jdbc.dialect.PostgresDialect |
| SQLite | org.seasar.doma.jdbc.dialect.SqliteDialect |
AppConfig.java
package sample.doma;
import javax.sql.DataSource;
import org.seasar.doma.jdbc.DomaAbstractConfig;
import org.seasar.doma.jdbc.SimpleDataSource;
import org.seasar.doma.jdbc.dialect.Dialect;
import org.seasar.doma.jdbc.dialect.SqliteDialect;
import org.seasar.doma.jdbc.tx.LocalTransaction;
import org.seasar.doma.jdbc.tx.LocalTransactionalDataSource;
public class AppConfig extends DomaAbstractConfig {
protected static final LocalTransactionalDataSource
dataSource = createDataSource();
protected static final Dialect dialect = new SqliteDialect();
@Override
public DataSource getDataSource() {
return dataSource;
}
@Override
public Dialect getDialect() {
return dialect;
}
protected static LocalTransactionalDataSource createDataSource() {
SimpleDataSource dataSource = new SimpleDataSource();
dataSource.setUrl("jdbc:sqlite:sample.db");
return new LocalTransactionalDataSource(dataSource);
}
public static LocalTransaction getLocalTransaction() {
return dataSource.getLocalTransaction(defaultJdbcLogger);
}
}
●エンティティクラスSQLの結果に対応するクラスを作ります。
サンプルでは単一テーブルを検索するので
テーブルと一致するクラスを作ります
本家のサンプルはhiredateがDate型ですが
sqliteにはDateは無いのでStringにしてあります
コンパイル時に
.apt_generated\sample\doma\_Employee.java
が自動生成されます
package sample.doma;
import org.seasar.doma.Entity;
import org.seasar.doma.Id;
import org.seasar.doma.Version;
import org.seasar.doma.jdbc.entity.NamingType;
@Entity(naming = NamingType.SNAKE_UPPER_CASE)
public class Employee {
@Id
public Integer employeeId;
public String employeeName;
// public Date hiredate;
public String hiredate;
public Integer salary;
@Version
public Integer versionNo;
}
●Dao一覧の取得や更新、削除などは、このクラスを使います
selectをするSQLを使うメソッドには@Selectアノテーションを付けます
更新をするメソッドは@Update
@Scriptというのがあって、これはパラメータを渡せない代わりに
create table してデータを insert するようなSQLファイルを書いておいて
これを実行できます。
各メソッド名と同じ名前のSQLファイルを用意します。
パラメーターがある場合はSQLファイルにパラメーターを書かないとエラーになります。
コンパイル時に
.apt_generated\sample\doma\EmployeeDaoImpl.java
が自動生成されます
EmployeeDao.java
package sample.doma;
import java.util.List;
import org.seasar.doma.Dao;
import org.seasar.doma.Script;
import org.seasar.doma.Select;
import org.seasar.doma.Update;
@Dao(config = AppConfig.class)
public interface EmployeeDao {
@Select
int countTable(String tableName);
@Script
void createTable();
@Select
Employee selectById(Integer employeeId);
@Update
int update(Employee employee);
@Select
List selectAll();
}
●SQLファイル
・拡張子sqlのファイルにSQLを書きます。
パラメータはコメントとして書きます。
例えばこんな風に書きます。
select * from EMPLOYEE where EMPLOYEE_ID = /* employeeId */99
この場合/* employeeId */99 の部分がemployeeIdというパラメータで書き換えられます
Daoの説明を見るともう少し分かるかも
・SQLファイルの配置
META-INF以下に対象Daoのパッケージと同じフォルダ構成でファイル名はメソッド名同じにする
例
srcにあるsample.doma.EmployeeDaoのselectAll()の場合
src\META-INF\sample\doma\EmployeeDao\selectAll.sql
実際のファイルはDaoに書いたメソッドの分だけ作成します。
countTable.sql
select count(*) from sqlite_master where type = 'table' and tbl_name = /* tableName */'hoge'
createTable.script
/*
* テーブル定義(SQLステートメント)
*/
create table EMPLOYEE (
EMPLOYEE_ID integer,
EMPLOYEE_NAME text,
HIREDATE text,
SALARY integer,
VERSION_NO integer
);
/*
* データの追加(SQLステートメント)
*/
insert into EMPLOYEE values(1, 'SMITH', '1980-12-17', 800, 1);
insert into EMPLOYEE values(2, 'ALLEN', '1981-02-20', 1600, 1);
insert into EMPLOYEE values(3, 'WARD', '1981-02-22', 1250, 1);
selectById.sql
select * from EMPLOYEE where EMPLOYEE_ID = /* employeeId */99
updateは書かなくてもOKみたい
selectAll.sql
select * from EMPLOYEE
最後にこれらを確認するクラスを作成します。
Main.java
import java.util.List;
import org.seasar.doma.jdbc.tx.LocalTransaction;
import sample.doma.AppConfig;
import sample.doma.Employee;
import sample.doma.EmployeeDao;
import sample.doma.EmployeeDaoImpl;
public class Main {
public static void main(String[] args) {
LocalTransaction tx = AppConfig.getLocalTransaction();
try {
tx.begin();
EmployeeDao dao = new EmployeeDaoImpl();
// テーブル情報を検索して存在しなければ作成します
int tableCount = dao.countTable("EMPLOYEE");
if (tableCount == 0) {
dao.createTable();
}
// Employeeから1レコード分取得します
Employee employee = dao.selectById(1);
System.out.println(employee.employeeName);
Integer salary = employee.salary;
System.out.println(salary);
// 値を変えて
employee.salary = salary + 50;
// 更新します
dao.update(employee);
// 一覧取得
List list = dao.selectAll();
for (Employee emp : list) {
System.out.print(emp.employeeId);
System.out.print(" : ");
System.out.print(emp.employeeName);
System.out.print(" : ");
System.out.print(emp.hiredate);
System.out.print(" : ");
System.out.println(emp.salary);
}
} catch (Exception e) {
tx.rollback();
} finally {
tx.commit();
}
}
}
ソース一式ダウンロード
0 件のコメント:
コメントを投稿