關於Java中分層中遇到的一些問題

鐮鼬貓發表於2018-04-15

Java分層中遇到的問題

陸陸續續寫了一些Java的專案,用了Spring系列和Hibernate這樣的框架。在設計Service層和Dao層的時候碰到了一些想不清楚的問題。
以一個簡單的使用者資訊管理功能為例,如果不用Spring Data之類的東西。那麼我一般會這麼寫程式碼
controller往上沒什麼好說的,controller呼叫service就好了,service呼叫dao。
關鍵在於service這裡。我可能會這麼寫

...
@Autowired
UserDao userDao;

public void saveUser(String userName){
    userDao.save(userName);
}
public User findUser(String userName){
    return userDao.findUser(userName);
}
...

然後在整個service的實現類上面註解@Transaction
Dao實現的程式碼就是

...
@Autowired
SessionFactory sessionFactory;

public void save(String userName){
    Session session=sessionFactory.getCurrentSession();
    session.save(userName);
}
...

問題就來了,如果按照這樣的寫法,那麼首先Hibernate的一級快取似乎就沒有起到作用了
因為在Dao中,每一個方法都獲取一個Session來進行操作,方法間並不共享Session。也就是說如果Service的一個方法中呼叫了Dao的兩個方法,這兩個方法的Session不一樣,一級快取根本沒用。

其次就是Service層中查詢出來的物件是遊離態的
在Service的方法中如果find了一個物件然後呼叫這個的物件的Set方法,資料庫中是不會更新的。因為呼叫Dao的find方法後Session關閉,物件從持久態變成了遊離態,所以這時候要更新物件的資訊只能手動再寫一句update(User u),就是這樣:

public void update(String userName,String password){
    User u=userDao.findUser(userName);
    u.setPassword(password);
    userDao.update(u);
}

這顯然是不好的一種方式。
但是如果想改掉前面兩個缺點,就必須把Session提到Service層,讓Service的一個方法用一個Session,這樣上面提到的兩個問題就都能解決。可是Session本應該是Dao層的東西,提升到Service層似乎也是不好的做法。

不知道這裡頭的矛盾到底怎麼解決?

相關文章