2013年10月16日水曜日

groovyとApache MetaModelでRDBとExcelのデータをJOINしたクエリーを実行する

異なるデータソース(RDBとExcelなど)のテーブルをJOINしたクエリーを実行するには、以下のようにDataContextFactory.createCompositeDataContextメソッドを使用して、CompositeDataContextを作成します。
@GrabConfig(systemClassLoader=true)
@Grab(group='postgresql', module='postgresql', version='9.1-901.jdbc4')
@Grab(group='org.eobjects.metamodel', module='MetaModel-full', version='3.4.5')
import org.eobjects.metamodel.*
import groovy.sql.Sql

def sql = Sql.newInstance(
  "jdbc:postgresql://localhost:5432/userdb",
  "postgres",
  "postgres",
  "org.postgresql.Driver")

// RDB(JDBC)
dc1 = DataContextFactory.createJdbcDataContext(sql.getConnection())
// Excel DataContext
dc2 = DataContextFactory.createExcelDataContext(new File("students.xlsx"))

// Composite DataContextを作成
cdc = DataContextFactory.createCompositeDataContext(dc1, dc2)

// スコアテーブルの取得とカラムの取得
tableScores = cdc.getDefaultSchema().getTableByName("scores")
colScoresTestId = tableScores.getColumnByName("test_id") // テストID
colScoresStudentId = tableScores.getColumnByName("student_id") // 生徒ID
colScoresScore = tableScores.getColumnByName("score")  // 点数

// 生徒マスタの取得とカラムの取得
tableStudents = dc2.getDefaultSchema().getTableByName("students")
colStudentsStudentId = tableStudents.getColumnByName("student_id") // 生徒ID
colStudentsName = tableStudents.getColumnByName("name")  // 生徒名

// 2つのテーブルをjoin。90点以上取った生徒の名前とスコア、テストIDを表示
query = cdc.query().from(tableScores)
  .leftJoin(tableStudents).on(colScoresStudentId, colStudentsStudentId)
  .select(colScoresTestId, colStudentsName, colScoresScore)
  .where(colScoresScore).gt(90)
    .or(colScoresScore).eq(90)
  .toQuery()

// Queryの表示
println query.toString()
// Queryの実行
ds = cdc.executeQuery(query)
for(row in ds){
  // test_id, 名前, 点数を表示
  println row.getValue(0) + ":" + row.getValue(1) + ":" + row.getValue(2)
}


動作環境
groovy 2.1.7, JDK7 update40

0 件のコメント:

コメントを投稿