strtus2.3.6+guice4+jpa(hibernate4)的配置-第三篇

上两篇文章中,基本的环境搭建好了,还需要写点代码测试一下是否真的好用。

1.实体类,在第二篇中,我配置了一个名为Test的hibernate实体类,下面是代码

   由于纯粹是为了搭建框架,实体类很简单,test表有3个字段:id,name,test_value
  @Entity
@Table(name = "test")
public class Test implements java.io.Serializable {

/**

*/
private static final long serialVersionUID = 6458575796251625995L;
// Fields
long id;
private String name;
private Long testValue;

/** default constructor */
public Test() {
}

// Property accessors
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)   
public long getId() {
return id;
} public void setId(long id){
this.id = id;
}
@Column(name = "name")
public String getName() {
return name;
}


public void setName(String name) {
this.name = name;
}

@Column(name = "test_value")
public Long getTestValue() {
return testValue;
}


public void setTestValue(Long testValue) {
this.testValue = testValue;
}

}

  2.dao 这个dao我就直接写成类了,没有用接口的形式。有需要的话可以把dao层写成接口,再搞一个dao的实现层。

  public class TestDao{
private EntityManager em;
public TestDao(){

}
@Inject
public TestDao(EntityManager em){
this.em = em;
}

public void save(Test test){
em.persist(test);
}
public List getList(){
Query q = em.createQuery("from Test");
return q.getResultList();

}
}


dao很简单,实现了2个方法,save和getList,用于插入和查询所有数据,使用标准jpa编码方式。关键点是构造方法,一个无参数构造方法,这是必须的;一个是包含EntityManager 参数的构造方法,并且使用guice的@Inject进行注入。这个EntityManager 是由guice管理的,不需要我们做其他的事。


3.创建服务

    下面我们创建一个服务接口用与调用dao层的方法,与spring标准的service层概念相同:

import java.util.List;
import com.google.inject.ImplementedBy;
import com.test.serviceimpl.TestImpl;
import com.test.vo.Test;

@ImplementedBy(TestImpl.class)
public interface TestService {
void saveObject(Test test);
List getList();
}

  为了简单,与dao层方法是对应的。@ImplementedBy(TestImpl.class)这个注解是关键,即告诉guice这个接口的实现类是com.test.serviceimpl.TestImpl。guice就这么简单!下面是TestImpl的代码:

import java.util.List;
import com.google.inject.Inject;
import com.google.inject.persist.Transactional;
import com.test.dao.TestDao;
import com.test.service.TestService;
import com.test.vo.Test;
public class TestImpl implements TestService {
@Inject
private TestDao testDao;
@Transactional
@Override
public void saveObject(Test test) {

testDao.save(test);
}
public List getList(){
return testDao.getList();
}
}

@Inject注入了testDao这个bean。@Transactional标识方法需要事务控制。

jpa的基本代码就编写完成了,用action测试一下:

插入数据的action

import com.google.inject.Inject;
import com.test.service.TestService;
import com.test.vo.Test;
public class SaveAction {


@Inject
private TestService testService;
  public String execute() {
  Test test = new Test();
    test.setName("nameguice");
     
    test.setTestValue(1025L);
    testService.saveObject(test);
    return "success";
  }
 

}

获取数据的action:

import java.util.List;
import com.google.inject.Inject;
import com.test.service.TestService;
import com.test.vo.Test;
public class ListAction {
@Inject
private TestService testService;
  public String execute() {
  
    List<Test> l = testService.getList();
    String s = "";
    for(int i=0;i<l.size();i++){
    s += l.get(i).getName();
    }
    System.out.println(s);
    return "success";
  }
}

我自己测试的情况比较满意,事务能够正常提交,而且不会锁死数据源。

配置过程中,出现了不少问题,多数还是自己没有仔细阅读官方文档导致的,也因为英语不那么灵光,多少感觉有点读起来费劲。下面列几个我遇到的主要问题,希望其他人少走弯路。

1.ServletContextListener里面,没有把install(new JpaPersistModule("unit1"));放到第一个,虽然系统启动成功,但是写入数据库的时候没有提交到数据库,手动执行flush()方法报了一个没有事务的错误。人家官方userguide写的很明白要靠前放,自己疏忽了。

2.jpa配置文件,我习惯性的放到了WebRoot/META-INF里面了,启动时报unit1和这个东西找不到,让我足足搞了好几个小时。日志里面其实在报错之前也输出了persistence.xml没找到的信息,只是我太着急没有看到。

3.TestDao类让我加了个@Singleton注解,导致提交不了,也没生成insert语句,userguide里面明确说如果是Singleton,那注入的话,要用Provider方式。最后我去掉了Singleton就可以插入数据了

4.userguide里面写了如何整合strtus,最后还写了之前版本guice如何整合,结果没注意那个“之前版本”,把那个guice的配置直接粘贴到了stutus.xml中了,导致启动失败。实际上目前版本与整合servlet一样,直接使用那个listener就可以了。

关于这个环境的配置,包括guice的学习,我也就搞了2天,所以很多地方理解的不够深刻,有能人希望能指点一下。

你可能感兴趣的:(框架,jpa,Guice)