<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    新的起點 新的開始

    快樂生活 !

    JPA 設計模式系列一 DAO Pattern in JPA

             作為JavaEE5 規范一部分的JPA,已經有眾多的實現,比如:Hiberante,TopLink, EclipseLink和OpenJPA 等許多ORM框架。JPA不僅僅應用于EJB3中,你也可以應用EJB3之外的應用,比如Spring 中。甚至Gavin King Hiberante的作者 在Hiberante in Action 的第二版書中也推薦使用JPA。很明顯,JPA將被廣泛的應用。

            
    一旦你熟悉annotation,并嘗試過Hello world之類的程序后,你會感覺,恩 JPA確實不錯。然后,當你在你的項目中開始應用JPA時,你會發現其實并不那么簡單,你需要考慮如何處理事務,惰性加載,移除對象實例, 繼承等等。這些問題會在本系列中給你答案。

          
    首先進入第一的設計模式 DAO。


     我們需要DAO嗎?

           
    在二年前,我們已經討論了這個問題了,討論的結果是:是否使用DAO依賴于你的應用,類似于GOF的設計模式,如果是很簡單的應用程序,應用設計模式,只能增加你的復雜度。 而對于復雜應用程序,正因為其復雜,應用設計模式可以減低復雜度,提高可維護性。 

           
    應用了DAO我們可以得到如下好處:

           1. 
    避免在任何存取數據的代碼中引入EntityManager,減少了依賴。

           2. 
    對某些實體Bean操作增加限制。比如你不想對LogEntry提供刪除操作,應用DAO,你僅僅做的是不要在LogEntry DAO中不要添加remove的方法。

           3. 
    理論上,應用DAO層,你一個自由切換其他的持久機制比如純JDBC或者Ibatis.而實際上,JPA已經是一個抽象層,這種切 換是沒有意義的。

          4. 
    你可以在一個實體中集中所有的查詢避免這些查詢在其他代碼中出現。你可以使用named queries 在實體類中查詢,但是您仍然需要正確的參數被設置。對應這種查詢,你可以在DAO中設置參數,然后轉換成正確的返回類型,比如:

        
    public List<ChangePlan> findExecutingChangePlans() {

          Query query = entityManager.createQuery(
                "SELECT plan FROM ChangePlan plan where plan.state = 'EXECUTING'");
          return (List<ChangePlan>) query.getResultList();
    }

    然后,但你決定使用DAO時,如何正確合理的使用它呢? SpringJpaTemplateJavaDoc中建議,不要使用類似特殊的類,類似JpaDaoSupport 而是你應該自己通過@PersistenceContext注釋獲取EntityManger來維護你的DAO。這種方式可以在EJB3的容器中工作,并且如果你在Springcontext 加入PersistenceAnnotationBeanpostProcessor Bean的話,在Spring2.0里也是沒有問題的。

    類型安全且泛化的DAO pattern

        因為每一個DAO都包含一些相同的邏輯,所以我們應該抽取這些邏輯放入到父類中。

    實體類

    比如,我們想實例化OrderClass

    @Entity
    @Table(name = "ORDERS")
    public class Order {
            @Id
            @GeneratedValue
            private int id;
            private String customerName;
            private Date date;
     
            public int getId() { return id; }
            public void setId(int id) { this.id = id; }
     
            public String getCustomerName() { return customerName; }
            public void setCustomerName(String customerName) { this.customerName = customerName; }
     
            public Date getDate() { return date; }
            public void setDate(Date date) { this.date = date;}

    DAO 接口

    首先我們定義一個泛化的DAO接口,包括最常用的方法,比如:

    public interface Dao<K, E> {
          void persist(E entity);
          void remove(E entity);
          E findById(K id);
    }

    K E為泛型,你可以加其他的方法比如:List findAll().

    然后我們定義一個自接口,實現特殊的方法,比如,我們想查找一定條件的Order信息:

    public interface OrderDao extends Dao<Integer, Order> {
            List<Order> findOrdersSubmittedSince(Date date);
    }

    基本DAO的實現

    第三步就是創建基本的JPA DAO的實現。它實現了Dao接口。

    public abstract class JpaDao<K, E> implements Dao<K, E> {
            protected Class<E> entityClass;
     
            @PersistenceContext
            protected EntityManager entityManager;
     
            public JpaDao() {
                   ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();
                   this.entityClass = (Class<E>) genericSuperclass.getActualTypeArguments()[1];
            }
     
            public void persist(E entity) { entityManager.persist(entity); }
     
            public void remove(E entity) { entityManager.remove(entity); }
     
            public E findById(K id) { return entityManager.find(entityClass, id); }

      上述實現是直接明了的,大家還要注意幾點:

            JpaDao的構造方法是通過ParameterizedType獲取具體的實體類。

        通過@PersistenceContext 獲取EntityManager

            entityClassEntityManagerProtected類型,子類可以直接訪問。

    特殊的DAO實現

    最后,我們創建特殊的DAO,它擴張了基本的DAO接口實現了OrderDAO接口

    public class JpaOrderDao extends JpaDao<Integer, Order> implements OrderDao {
            public List<Order> findOrdersSubmittedSince(Date date) {
                   Query q = entityManager.createQuery(
                           "SELECT e FROM " + entityClass.getName() + " e WHERE date >= :date_since");
                   q.setParameter("date_since", date);
                   return (List<Order>) q.getResultList();

    DAO的使用

    EJB3中,

    @EJB(name="orderDao")
    private OrderDao orderDao;
     
    在Spring中,我們使用XML bean 文件,或者通過autowiring 如下:
     
    @Autowired
    public OrderDao orderDao;
     
    總之。當我們獲取到了DAO的引用后,我們可以如下使用:
     
    Order o = new Order();
    o.setCustomerName("Peter Johnson");
    o.setDate(new Date());
    orderDao.persist(o);
     
    當然,我們可以再OrderDao接口中加入其它的查詢:
    List<Order> orders = orderDao.findOrdersSubmittedSince(date);
    for (Order each : orders) {
            System.out.println("order id = " + each.getId());
    }
     
     
     總之,使用了類型安全的DAO Pattern有如下優勢:
        1.    從Client的角度講,不會直接依賴于JPA的API
        2.    通過泛型實現類型安全,避免Cast異常。
        3.    集中處理所有跟JPA相關的代碼。
        4.    可以在集中點上加入事務,log 性能測試等邏輯。
        5.    通過一個類可以測試數據庫訪問代碼。
      希望這些可以說服你使用DAO Pattern . 接下來我們將討論Bidirectional assocations 雙向關聯模式。
     
     
     

    posted on 2009-07-26 12:32 advincenting 閱讀(3510) 評論(1)  編輯  收藏 所屬分類: java EE

    評論

    # re: JPA 設計模式系列一 DAO Pattern in JPA 2009-07-26 18:11 ahx

    很不喜歡 1280x 的布局,或者像首頁一樣自適應,或者使用1024x768 布局;
    因為,看一行字還需要轉腦袋,太累。 1024的最多需要轉一下眼睛。
      回復  更多評論   

    公告

    Locations of visitors to this pageBlogJava
  • 首頁
  • 新隨筆
  • 聯系
  • 聚合
  • 管理
  • <2009年7月>
    2829301234
    567891011
    12131415161718
    19202122232425
    2627282930311
    2345678

    統計

    常用鏈接

    留言簿(13)

    隨筆分類(71)

    隨筆檔案(179)

    文章檔案(13)

    新聞分類

    IT人的英語學習網站

    JAVA站點

    優秀個人博客鏈接

    官網學習站點

    生活工作站點

    最新隨筆

    搜索

    積分與排名

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 免费人成在线观看播放国产 | 天黑黑影院在线观看视频高清免费| 岛国大片免费在线观看| 亚洲一区欧洲一区| 18禁无遮挡无码网站免费| 国产精品亚洲专区在线观看 | 一级成人a毛片免费播放| 亚洲高清中文字幕综合网| 午夜免费1000部| 亚洲精品无码久久久久YW| 亚洲成人一区二区| 久久精品无码免费不卡| 亚洲高清美女一区二区三区| 亚洲国产另类久久久精品小说| 国产成人精品免费视频大全麻豆| 久草免费福利视频| 亚洲欧好州第一的日产suv| 亚洲欧洲日本在线观看| 国产亚洲精品福利在线无卡一| 16女性下面扒开无遮挡免费| 久久久亚洲精华液精华液精华液| 亚洲日韩中文字幕日韩在线| 最近免费最新高清中文字幕韩国 | 亚洲高清最新av网站| 免费精品国产自产拍观看| 日本免费大黄在线观看| 色噜噜的亚洲男人的天堂| 亚洲激情在线视频| 国产中文字幕免费| 免费欧洲美女牲交视频| 亚洲成?Ⅴ人在线观看无码| 国产乱色精品成人免费视频 | 成年免费a级毛片| 久久精品九九亚洲精品| 亚洲精品岛国片在线观看| 日本在线高清免费爱做网站| 中文字幕在线免费视频| 亚洲国产AV一区二区三区四区 | 日本不卡免费新一区二区三区 | 亚洲午夜无码久久久久| 国产小视频在线观看免费|