Play Framework và cách truy cập SQL database

Cấu hình JDBC connection

Play cung cấp một plugin cho việc quản lý JDBC connection. Bạn có thể cấu hình bất kì database nào bạn cần. Để enable database plugin, hãy add javaJdbc vào build dependencies:

libraryDependencies += javaJdbc

Sau đó bạn phải cấu hình một connection pool trong file "conf/application.conf". Bởi quy ước default JDBC data source sẽ gọi default:

#Default database configuration
db.default.driver=org.h2.Driver
db.default.url="jdbc:h2:mem:play"

Để cấu hình một vài dât sources:

#Orders database
db.orders.driver=org.h2.Driver
db.orders.url="jdbc:h2:mem:orders"

#Customers database
db.customers.driver=org.h2.Driver
db.customers.url="jdbc:h2:mem:customers"

Nếu một vài thứ không được cấu hình riêng, bạn sẽ được thông báo trực tiếp trong browser:

Truy cập JDBC datasource

Package play.db cung cấp truy cập đến default datasource, chủ yếu thông quá class "play.fb.Database"

/*
 * Copyright (C) 2009-2017 Lightbend Inc. <https://www.lightbend.com>
 */
package javaguide.sql;

import javax.inject.*;

import play.db.*;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;

@Singleton
class JavaApplicationDatabase {

    private Database db;
    private DatabaseExecutionContext executionContext;

    @Inject
    public JavaApplicationDatabase(Database db, DatabaseExecutionContext context) {
        this.db = db;
        this.executionContext = executionContext;
    }

   public CompletionStage<Integer> updateSomething() {
       return CompletableFuture.supplyAsync(() -> {
           return db.withConnection(connection -> {
               // do whatever you need with the db connection
               return 1;
           });
       }, executionContext);
   }
}

Cấu hình database khác ddefault database:

/*
 * Copyright (C) 2009-2017 Lightbend Inc. <https://www.lightbend.com>
 */
package javaguide.sql;

import javax.inject.Inject;
import javax.inject.Singleton;

import play.mvc.Controller;
import play.db.NamedDatabase;
import play.db.Database;

// inject "orders" database instead of "default"
@javax.inject.Singleton
class JavaNamedDatabase {
    private Database db;
    private DatabaseExecutionContext executionContext;

    @Inject
    public JavaNamedDatabase(@NamedDatabase("orders") Database db, DatabaseExecutionContext executionContext) {
        this.db = db;
        this.executionContext = executionContext;
    }

    // do whatever you need with the db using supplyAsync(() -> { ... }, executionContext);
}

Cấu hình một CustomExecutionContext

Bạn nên luôn luôn sử dụng một execution context tùy chọn khi sử dụng JDBC, để chắc chắn rằng rendering thread pool của Play tập trung hoàn toàn vào rendering pages và sử dụng cóe để mở rộng full. Bạn có thể sử dụng "CustomExecutionContext" class để cấu hình một execution context tùy chọn để phục vụ JDBC operations. Tát cả các ví dụ templates trong Play sử dụng blocking APIs (Anorm, JPA) update để sử dụng execution contexts tùy chọn phù hợp. Đối với thread pool sizing ảnh hưởng đến JDBC connection pools, bạn muốn fix một thread pool size tương xứng với connection pool, sử dụng thread pool executor. Theo lời khuyên từ trang HikariCP's pool sizing, bạn nên cấu hình JDBC connection poll đến con số double ò physical cóe, cộng số lượng của disk spindles.

#db connections = ((physical_core_count * 2) + effective_spindle_count)
fixedConnectionPool = 9

database.dispatcher {
  executor = "thread-pool-executor"
  throughput = 1
  thread-pool-executor {
    fixed-pool-size = ${fixedConnectionPool}
  }
}

Lấy một JDBC connection

Bạn có thể lấy lại một JDBC connection theo cách sau:

/*
 * Copyright (C) 2009-2017 Lightbend Inc. <https://www.lightbend.com>
 */
package javaguide.sql;

import java.sql.Connection;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import javax.inject.Inject;

import play.mvc.Controller;
import play.db.NamedDatabase;
import play.db.Database;

class JavaJdbcConnection {
    private Database db;
    private DatabaseExecutionContext executionContext;

    @Inject
    public JavaJdbcConnection(Database db, DatabaseExecutionContext executionContext) {
        this.db = db;
        this.executionContext = executionContext;
    }

    public CompletionStage<Void> updateSomething() {
        return CompletableFuture.runAsync(() -> {
            // get jdbc connection
            Connection connection = db.getConnection();

            // do whatever you need with the db connection
            return;
        }, executionContext);
    }

}

Một việc rất quan trọng là kết quả Connections là không disposed tự động tại cuối một request cycle. Bạn có trách nhiệm gọi method close() một nơi nào đó trong code của bạn mà chúng có thể trả lại pool ngay lập tức.

Cấu hình JDBC Driver dêpndency

Paly không cung cấp bất kì database drives nào. Hậu quả là, khi deploy lên production bạn sẽ phải add database driver của bạn giống như một application dependency. Cho ví dụ, nếu bạn sử dụng MySQL5, bạn cần add một dependency cho connector: libraryDependencies += "mysql" % "mysql-connector-java" % "5.1.41"

Tài liệu tham khảo

https://www.playframework.com/documentation/2.6.x/JavaDatabase#configuring-a-customexecutioncontext


All Rights Reserved