网上有一个play2+mybatis的例子,是基于scala的,经过几天的研究,总算弄出来一个java版的,放上来备忘。
环境
os:ubuntu 12.04
jdk:1.6.0_31
play framework:2.0.3
sbt:0.11.3
mysql:5.5
ide:eclipse 3.7.2
几个重要文件及包的目录结构
app/module/Dependencies.java //这是guice插件需要用到的Module定义
app/module/domain //这里是mybatis的领域对象和dao
app/module/domain/mapper //这里是mybatis的mapper包
主要看附件中完整的源码,下文只描述重要步骤。
1.首先需要设置插件
1.1.添加依赖
"com.typesafe" % "play-plugins-guice" % "2.0.3",
"mysql" % "mysql-connector-java" % "5.1.18"
1.2.设置插件优先级
在conf目录下建一个名为play.plugins的文件,内容为
1500:com.typesafe.plugin.inject.GuicePlugin
这个文件主要用于定义插件的加载顺序,一般插件的加载顺序值取值在1000到10000之间。
必须得有这个文件,否则会出错
1.3.工程导入eclipse
在play控制台执行
update
....
eclipsify with-source=true
....
最后导入工程。
2.编写dao,domain和mapper
ComputerDao.java代码
package module.domain;
import java.util.List;
public interface ComputerDao {
public Computer getById(final int id);
public List getAll();
public int save(final Computer object);
public int remove(final int id);
}
Computer.java代码
package module.domain;
import java.util.Date;
import java.util.List;
import javax.inject.Inject;
import module.domain.mapper.ComputerMapper;
public class Computer implements ComputerDao {
@Inject
private ComputerMapper mapper;
private Integer id;
private String name;
private Date introduced;
private Date discontinued;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getIntroduced() {
return introduced;
}
public void setIntroduced(Date introduced) {
this.introduced = introduced;
}
public Date getDiscontinued() {
return discontinued;
}
public void setDiscontinued(Date discontinued) {
this.discontinued = discontinued;
}
@Override
public Computer getById(int id) {
return this.mapper.getById(id);
}
@Override
public List getAll() {
return this.mapper.getAll();
}
@Override
public int save(Computer object) {
if (object.id == null || object.id == 0){
return this.mapper.append(object);
}else{
return this.mapper.update(object);
}
}
@Override
public int remove(int id) {
return this.mapper.remove(id);
}
}
ComputerMapper.java代码
package module.domain.mapper;
import java.util.List;
import module.domain.Computer;
import org.apache.ibatis.annotations.CacheNamespace;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.mybatis.caches.ehcache.EhcacheCache;
//@CacheNamespace(implementation=EhcacheCache.class)
//启用上面这样代码可以为应用带来缓存的效果,可以提升性能,但在开发阶段,修改了页面模板后刷新浏览器会出现异常。建议在开发阶段禁用缓存,仅在正式上线后开启。
public interface ComputerMapper {
@Select("select * from computer where id=#{id}")
@Options(flushCache=false, fetchSize=1)
@Results(value={
@Result(property="id", column="id"),
@Result(property="name", column="name"),
@Result(property="introduced", column="introduced"),
@Result(property="discontinuted", column="discontinuted")
})
public Computer getById(@Param("id")final int id);
@Select("select * from computer order by name asc")
@Options(flushCache=false)
@Results(value={
@Result(property="id", column="id"),
@Result(property="name", column="name"),
@Result(property="introduced", column="introduced"),
@Result(property="discontinuted", column="discontinuted")
})
public List getAll();
@Insert("insert into computer(id, name, introduced, discontinued) values(#{id}, #{name}, #{introduced}, #{discontinued})")
@Options(useGeneratedKeys=true, keyProperty="id", flushCache=true)
public int append(final Computer object);
@Update("update computer set name=#{name}, introduced=#{introduced}, discontinued=#{discontinued} where id=#{id}")
@Options(flushCache=true)
public int update(final Computer object);
@Delete("delete from computer where id=#{id}")
@Options(flushCache=true)
public int remove(@Param("id")final int id);
}
注意黑体字部分!!
Dependencies.java代码
package module;
import java.util.Properties;
import module.domain.Computer;
import module.domain.ComputerDao;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.mybatis.guice.MyBatisModule;
import org.mybatis.guice.datasource.builtin.PooledDataSourceProvider;
import com.google.inject.name.Names;
public class Dependencies extends MyBatisModule {
@Override
protected void initialize() {
final Properties properties = new Properties();
String driver = play.Configuration.root().getString("db.default.driver");
String url = play.Configuration.root().getString("db.default.url");
String user = play.Configuration.root().getString("db.default.user");
String password = play.Configuration.root().getString("db.default.password");
properties.setProperty("mybatis.environment.id", "demo1");
properties.setProperty("JDBC.driver", driver);
properties.setProperty("JDBC.url", url);
properties.setProperty("JDBC.username", user);
properties.setProperty("JDBC.password", password);
properties.setProperty("JDBC.autoCommit", "false");
bindDataSourceProviderType(PooledDataSourceProvider.class);
bindTransactionFactoryType(JdbcTransactionFactory.class);
addMapperClasses("module.domain.mapper");
bind(ComputerDao.class).to(Computer.class);
Names.bindProperties(this.binder(), properties);
}
}
3.module类
Dependencies.java
package module;
import java.util.Properties;
import module.domain.Computer;
import module.domain.ComputerDao;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.mybatis.guice.MyBatisModule;
import org.mybatis.guice.datasource.builtin.PooledDataSourceProvider;
import com.google.inject.name.Names;
public class Dependencies extends MyBatisModule {
@Override
protected void initialize() {
final Properties properties = new Properties();
String driver = play.Configuration.root().getString("db.default.driver");
String url = play.Configuration.root().getString("db.default.url");
String user = play.Configuration.root().getString("db.default.user");
String password = play.Configuration.root().getString("db.default.password");
properties.setProperty("mybatis.environment.id", "demo1");
properties.setProperty("JDBC.driver", driver);
properties.setProperty("JDBC.url", url);
properties.setProperty("JDBC.username", user);
properties.setProperty("JDBC.password", password);
properties.setProperty("JDBC.autoCommit", "false");
bindDataSourceProviderType(PooledDataSourceProvider.class);
bindTransactionFactoryType(JdbcTransactionFactory.class);
addMapperClasses("module.domain.mapper");
bind(ComputerDao.class).to(Computer.class);
Names.bindProperties(this.binder(), properties);
}
}
4.单元测试
单元测试基础类AbstractPlay2Test.java
import static play.test.Helpers.fakeApplication;
import play.Plugin;
import play.test.FakeApplication;
import scala.Option;
@SuppressWarnings("unchecked")
public abstract class AbstractPlay2Test {
public final FakeApplication fakeApplication = fakeApplication();
@SuppressWarnings("rawtypes")
public Plugin getPlugin(Class clazz){
Option option = fakeApplication.getWrappedApplication().plugin(clazz);
return option != null ? option.get() : null;
}
}
主单元测试类Test1.java
import static play.mvc.Http.Status.OK;
import static play.test.Helpers.callAction;
import static play.test.Helpers.running;
import static play.test.Helpers.status;
import module.domain.Computer;
import module.domain.ComputerDao;
import org.junit.Assert;
import org.junit.Test;
import play.mvc.Result;
import play.test.FakeApplication;
import play.test.Helpers;
import com.typesafe.plugin.inject.GuicePlugin;
public class Test1 extends AbstractPlay2Test {
@Test
public void testFakeApplication(){
running(this.fakeApplication, new Runnable() {
public void run() {
indexPage(fakeApplication);
testPage(fakeApplication);
computerTest(fakeApplication);
}
});
}
public void indexPage(FakeApplication application){
Result result = Helpers.callAction(controllers.routes.ref.Application.index());
System.out.println(result.toString());
Assert.assertEquals(OK, status(result));
String s = Helpers.contentAsString(result);
//System.out.println(s);
Assert.assertTrue(s.contains("
"));
}
public void testPage(FakeApplication application){
Result result = Helpers.callAction(controllers.routes.ref.Application.test());
System.out.println(result.toString());
Assert.assertEquals(OK, status(result));
String s = Helpers.contentAsString(result);
System.out.println(s);
Assert.assertTrue(s.contains("guice-demo"));
System.out.println("testestPage ok");
}
public void computerTest(FakeApplication application){
int id = 1;
GuicePlugin gp = (GuicePlugin)this.getPlugin(GuicePlugin.class);
Assert.assertNotNull(gp);
System.out.println("guice plugin is " + gp);
ComputerDao computerDao = gp.getInstance(ComputerDao.class);
Assert.assertNotNull(computerDao);
System.out.println(computerDao);
Computer c = computerDao.getById(id);
System.out.println("c : " + c);
Assert.assertNotNull(c);
Computer c1 = computerDao.getById(id);
System.out.println("c1 : " + c1);//这句查询实际上是从cache里取的
Computer c2 = computerDao.getById(id);
System.out.println("c2 : " + c2);//这段查询也是从cacche里取的
}
}
5.视图模板
视图模板名test.scala.html,只有一个参数title: String,模板的作用就是把显示测试页三个字
6.控制器
Application.java代码
package controllers;
import java.util.List;
import javax.inject.Inject;
import module.domain.Computer;
import module.domain.ComputerDao;
import play.*;
import play.mvc.*;
import views.html.*;
public class Application extends Controller {
@Inject
private static ComputerDao computerDao;
public static Result index() {
List computerList = computerDao.getAll();
return ok(index.render("Your new application is ready.", computerList));
}
public static Result test() {
return ok(views.html.test.render("guice-demo"));
}
}
7.运行单元测试的结果
[play2-guice-mybatis-demo2] $ test
SimpleResult(200, Map(Content-Type -> text/html; charset=utf-8, Set-Cookie -> ))
[WARN] [08/31/2012 00:40:51.890] [pool-4-thread-8] [Dispatchers] Dispatcher [akka.actor.promises-dispatcher] not configured, us
ing default-dispatcher
[WARN] [08/31/2012 00:40:51.909] [play-akka.actor.default-dispatcher-3] [Dispatchers] Dispatcher [akka.actor.actions-dispatcher
] not configured, using default-dispatcher
SimpleResult(200, Map(Content-Type -> text/html; charset=utf-8, Set-Cookie -> ))
测试页
testestPage ok
guice plugin is com.typesafe.plugin.inject.GuicePlugin@cd74b31
module.domain.Computer@a89848d
c : module.domain.Computer@11a4e5c0
c1 : module.domain.Computer@591f5ff9
c2 : module.domain.Computer@61ae0436
[info] Passed: : Total 1, Failed 0, Errors 0, Passed 1, Skipped 0
[success] Total time: 5 s, completed 2012-8-31 0:40:52
[play2-guice-mybatis-demo2] $
从上面结果看guice和mybatis都工作正常了。
8.在浏览器中显示computer列表
index.scala.html内容
@(title: String)(list: List[module.domain.Computer])
@css1={
}
@js1={
}
@body={
Computer List is :
@*960GS中,设置为14列显示*@
@*用div表格循环显示computer对象的内容*@
@for(c <- list) {
@c.getId()
@c.getName()
@c.getIntroduced().format("yy-MM-dd")
@c.getDiscontinued().format("yy-MM-dd")
@*换行*@
}
}
@default(title=title)(content=body)(css=css1)(js=js1)
9.查看运行效果
打开浏览器http://localhost:9000,可以显示出插入到computer表中的数据。