【Play Framework】Play Framework [3-1] ~ 応用編 / DBを動的に切替える ~

はじめに

http://blogs.yahoo.co.jp/dk521123/36084590.html
でDBアクセス可能なところまではいったが、
実際には、DBを動的に切り替えたい。
調査してたら、以下のサイトがあり、まさにやりたいことだったので
参考にして、サンプルソースを作ってみる
* 顧客ログイン後にEBeanのアクセスDBを切り替える
http://cs.hatenablog.jp/entry/2013/12/11/072107

サンプル

コントローラ以外

 * コントローラ以外のビューやDBデータなどは、以下の関連記事と同じなので
   以下の関連記事を参照のこと。
http://blogs.yahoo.co.jp/dk521123/36084590.html

コントローラ

package controllers;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import com.avaje.ebean.EbeanServer;
import com.avaje.ebean.EbeanServerFactory;
import com.avaje.ebean.config.DataSourceConfig;
import com.avaje.ebean.config.ServerConfig;

import models.Person;
import play.mvc.Controller;
import play.mvc.Result;
import views.html.*;

public class HelloWorldController extends Controller {

  private static final char PKG_SEPARATOR = '.';

  private static final char DIR_SEPARATOR = '/';

  private static final String CLASS_FILE_SUFFIX = ".class";

  private static final String BAD_PACKAGE_ERROR = "Unable to get resources from path '%s'. Are you sure the package '%s' exists?";

  public Result index() {
    DataSourceConfig dsConfig = new DataSourceConfig() {
      {
        setDriver("com.mysql.jdbc.Driver");
        setUrl("jdbc:mysql://localhost:3306/sampledb");
        setUsername("root");
        setPassword("password");
      }
    };

    EbeanServer server = EbeanServerFactory.create(new ServerConfig() {
      {
        setName("sampledb");
        setDataSourceConfig(dsConfig);
        setClasses(find("models"));
        setRegister(false);
        setDdlRun(false);
        setDdlGenerate(false);
        setDefaultServer(false);
      }
    });

    List<Person> people = server.find(Person.class).where().eq("id", "X0000000").findList();
    return ok(helloworld.render("Hello World!", people));
  }

  private static List<Class<?>> find(String scannedPackage) {
    String scannedPath = scannedPackage.replace(PKG_SEPARATOR, DIR_SEPARATOR);
    URL scannedUrl = Thread.currentThread().getContextClassLoader().getResource(scannedPath);
    if (scannedUrl == null) {
      throw new IllegalArgumentException(String.format(BAD_PACKAGE_ERROR, scannedPath, scannedPackage));
    }
    File scannedDir = new File(scannedUrl.getFile());
    List<Class<?>> classes = new ArrayList<Class<?>>();
    for (File file : scannedDir.listFiles()) {
      classes.addAll(find(file, scannedPackage));
    }
    return classes;
  }

  private static List<Class<?>> find(File file, String scannedPackage) {
    List<Class<?>> classes = new ArrayList<Class<?>>();
    String resource = scannedPackage + PKG_SEPARATOR + file.getName();
    if (file.isDirectory()) {
      for (File child : file.listFiles()) {
        classes.addAll(find(child, resource));
      }
    } else if (resource.endsWith(CLASS_FILE_SUFFIX)) {
      int endIndex = resource.length() - CLASS_FILE_SUFFIX.length();
      String className = resource.substring(0, endIndex);
      try {
        classes.add(Class.forName(className));
      } catch (ClassNotFoundException ignore) {
      }
    }
    return classes;
  }
}

参考文献

 * パッケージ配下のClassをListで返すサンプル
http://stackoverflow.com/questions/15519626/how-to-get-all-classes-names-in-a-package

関連記事

Play Framework [1-0] ~ 入門編 / 事前知識 ~

http://blogs.yahoo.co.jp/dk521123/36082733.html

Play Framework [1-4] ~ 入門編 / Hello World with DB ~

http://blogs.yahoo.co.jp/dk521123/36084590.html