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天,所以很多地方理解的不夠深刻,有能人希望能指點一下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章