As this has been asked on the play mailinglist this post shall guide you through the setup of MyBatis with Play2. For the integration of MyBatis and Play we’re using the MyBatis-Guice subproject, so we can inject MyBatis mappers into managed play controllers (currently only documented in Play 2.1 Highlights) - or mappers into repositories into services into controllers if you like ;-)
Check out the following steps to Play with MyBatis.
Update 2013/02/12: The source code is now also available on github.
Create new Play project
At first we create a new Play 2 java project, following the documentation - Creating a new application.
$ play new playMyBatisSample
_ _
_ __ | | __ _ _ _| |
| '_ \| |/ _' | || |_|
| __/|_|\____|\__ (_)
|_| |__/
play! 2.1.0 (using Java 1.7.0_09-icedtea and Scala 2.10.0), http://www.playframework.org
The new application will be created in /home/magro/proj/inoio/playMyBatisSample
What is the application name? [playMyBatisSample]
> play-mybatis-sample
Which template do you want to use for this new application?
1 - Create a simple Scala application
2 - Create a simple Java application
> 2
OK, application play-mybatis-sample is created.
Have fun!
After cd
‘ing to playMyBatisSample
we start the play console and check if everything’s fine so far:
$ cd playMyBatisSample/
$ play
[play-mybatis-sample] $ run
... [downloading some artifacts left out here]
--- (Running the application from SBT, auto-reloading is enabled) ---
[info] play - Listening for HTTP on /0:0:0:0:0:0:0:0:9000
(Server started, use Ctrl+D to stop and go back to the console...)
In the browser we can load http://localhost:9000/
and see s.th. like Your new application is ready. on a starting page.
Add MyBatis Guice Dependency
Next we add the mybatis and mybatis-guice dependencies to project/Build.scala
, so that appDependencies
looks like this:
val appDependencies = Seq(
"org.mybatis" % "mybatis" % "3.1.1",
"org.mybatis" % "mybatis-guice" % "3.3",
javaCore, javaJdbc
)
»> Update 2013/05/03:
Add mapper xml files to classpath
If we’re keeping mapper xml files besides the mapper java classes we also need to add the xml files to the classpath. To achieve this we have to adjust the settings in project/Build.scala
:
val main = play.Project(appName, appVersion, appDependencies).settings(
// Add app folder as resource directory so that mapper xml files are in the classpath
unmanagedResourceDirectories in Compile <+= baseDirectory( _ / "app" ),
// but filter out java and html files that would then also be copied to the classpath
excludeFilter in Compile in unmanagedResources := "*.java" || "*.html"
) **<<< END Update 2013/05/03**
To let play/sbt know about the changes to the project configuration we have to reload it:
[play-mybatis-sample] $ reload
Setup Guice + MyBatis in Global.java
The guice and mybatis setup will happen in the Global.java. The Global object allows to hook into application start and is responsible for retrieving managed controllers, so this is the right place for the guice injector.
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.mybatis.guice.MyBatisModule;
import play.Application;
import play.GlobalSettings;
import play.db.DB;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Provider;
import com.google.inject.name.Names;
public class Global extends GlobalSettings {
private Injector injector;
@Override
public void onStart(Application app) {
injector = Guice.createInjector(new MyBatisModule() {
@Override
protected void initialize() {
bindDataSourceProvider(new Provider<DataSource>() {
@Override
public DataSource get() {
// use db as configured in conf/application.conf
return DB.getDataSource();
}
});
bindTransactionFactoryType(JdbcTransactionFactory.class);
final Properties myBatisProperties = new Properties();
myBatisProperties.setProperty("mybatis.environment.id", "default");
Names.bindProperties(binder(), myBatisProperties);
}
});
}
@Override
public <A> A getControllerInstance(Class<A> clazz) throws Exception {
return injector.getInstance(clazz);
}
}
As DataSource for MyBatis we use the one provided by play, so we have to remove comments from db.default.*
in conf/application.conf
.
Notice that we don’t have setup any mappers or other MyBatis artifacts in our MyBatisModule, as we want to keep it as simple as possible. To see how to do this check out MyBatis Guice Documentation.
Inject MyBatis class into managed controller
Now that we have configured MyBatis we can use it in our managed controllers. To use the Application
controller as managed controller we have to add an @
to the relevant controller mapping in conf/routes
# Home page
GET / @controllers.Application.index
and also change the index()
method to an instance method (see below).
To use MyBatis in the Application
controller we inject some arbitrary MyBatis object and print some info on the start page - just to see that the integration is working. Normally we would inject some mapper/repository/service here. This is the very simple Application
controller:
package controllers;
import javax.inject.Inject;
import org.apache.ibatis.mapping.Environment;
import play.mvc.Controller;
import play.mvc.Result;
import views.html.index;
public class Application extends Controller {
@Inject
private Environment myBatisEnv;
public Result index() {
return ok(index.render("Your app is running with ds " + myBatisEnv.getDataSource()));
}
}
We’re done: Now we can reload the start page in the browser and see that MyBatis is integrated with Play.
Kommentare