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

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

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

    新的起點(diǎn) 新的開始

    快樂生活 !

    JPA 設(shè)計(jì)模式系列一 DAO Pattern in JPA

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

            
    一旦你熟悉annotation,并嘗試過Hello world之類的程序后,你會(huì)感覺,恩 JPA確實(shí)不錯(cuò)。然后,當(dāng)你在你的項(xiàng)目中開始應(yīng)用JPA時(shí),你會(huì)發(fā)現(xiàn)其實(shí)并不那么簡(jiǎn)單,你需要考慮如何處理事務(wù),惰性加載,移除對(duì)象實(shí)例, 繼承等等。這些問題會(huì)在本系列中給你答案。

          
    首先進(jìn)入第一的設(shè)計(jì)模式 DAO。


     我們需要DAO嗎?

           
    在二年前,我們已經(jīng)討論了這個(gè)問題了,討論的結(jié)果是:是否使用DAO依賴于你的應(yīng)用,類似于GOF的設(shè)計(jì)模式,如果是很簡(jiǎn)單的應(yīng)用程序,應(yīng)用設(shè)計(jì)模式,只能增加你的復(fù)雜度。 而對(duì)于復(fù)雜應(yīng)用程序,正因?yàn)槠鋸?fù)雜,應(yīng)用設(shè)計(jì)模式可以減低復(fù)雜度,提高可維護(hù)性。 

           
    應(yīng)用了DAO我們可以得到如下好處:

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

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

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

          4. 
    你可以在一個(gè)實(shí)體中集中所有的查詢避免這些查詢?cè)谄渌a中出現(xiàn)。你可以使用named queries 在實(shí)體類中查詢,但是您仍然需要正確的參數(shù)被設(shè)置。對(duì)應(yīng)這種查詢,你可以在DAO中設(shè)置參數(shù),然后轉(zhuǎn)換成正確的返回類型,比如:

        
    public List<ChangePlan> findExecutingChangePlans() {

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

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

    類型安全且泛化的DAO pattern

        因?yàn)槊恳粋€(gè)DAO都包含一些相同的邏輯,所以我們應(yīng)該抽取這些邏輯放入到父類中。

    實(shí)體類

    比如,我們想實(shí)例化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 接口

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

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

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

    然后我們定義一個(gè)自接口,實(shí)現(xiàn)特殊的方法,比如,我們想查找一定條件的Order信息:

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

    基本DAO的實(shí)現(xiàn)

    第三步就是創(chuàng)建基本的JPA DAO的實(shí)現(xiàn)。它實(shí)現(xiàn)了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); }

      上述實(shí)現(xiàn)是直接明了的,大家還要注意幾點(diǎn):

            JpaDao的構(gòu)造方法是通過ParameterizedType獲取具體的實(shí)體類。

        通過@PersistenceContext 獲取EntityManager

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

    特殊的DAO實(shí)現(xiàn)

    最后,我們創(chuàng)建特殊的DAO,它擴(kuò)張了基本的DAO接口實(shí)現(xiàn)了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;
     
    總之。當(dāng)我們獲取到了DAO的引用后,我們可以如下使用:
     
    Order o = new Order();
    o.setCustomerName("Peter Johnson");
    o.setDate(new Date());
    orderDao.persist(o);
     
    當(dāng)然,我們可以再OrderDao接口中加入其它的查詢:
    List<Order> orders = orderDao.findOrdersSubmittedSince(date);
    for (Order each : orders) {
            System.out.println("order id = " + each.getId());
    }
     
     
     總之,使用了類型安全的DAO Pattern有如下優(yōu)勢(shì):
        1.    從Client的角度講,不會(huì)直接依賴于JPA的API
        2.    通過泛型實(shí)現(xiàn)類型安全,避免Cast異常。
        3.    集中處理所有跟JPA相關(guān)的代碼。
        4.    可以在集中點(diǎn)上加入事務(wù),log 性能測(cè)試等邏輯。
        5.    通過一個(gè)類可以測(cè)試數(shù)據(jù)庫(kù)訪問代碼。
      希望這些可以說服你使用DAO Pattern . 接下來我們將討論Bidirectional assocations 雙向關(guān)聯(lián)模式。
     
     
     

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

    評(píng)論

    # re: JPA 設(shè)計(jì)模式系列一 DAO Pattern in JPA 2009-07-26 18:11 ahx

    很不喜歡 1280x 的布局,或者像首頁(yè)一樣自適應(yīng),或者使用1024x768 布局;
    因?yàn)椋匆恍凶诌€需要轉(zhuǎn)腦袋,太累。 1024的最多需要轉(zhuǎn)一下眼睛。
      回復(fù)  更多評(píng)論   

    公告

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

    統(tǒng)計(jì)

    常用鏈接

    留言簿(13)

    隨筆分類(71)

    隨筆檔案(179)

    文章檔案(13)

    新聞分類

    IT人的英語(yǔ)學(xué)習(xí)網(wǎng)站

    JAVA站點(diǎn)

    優(yōu)秀個(gè)人博客鏈接

    官網(wǎng)學(xué)習(xí)站點(diǎn)

    生活工作站點(diǎn)

    最新隨筆

    搜索

    積分與排名

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 亚洲日韩在线视频| 中文字幕免费视频| 最新国产成人亚洲精品影院| 亚洲中久无码不卡永久在线观看| 免费做爰猛烈吃奶摸视频在线观看 | 亚洲精品国精品久久99热| 国产精品色拉拉免费看| 你是我的城池营垒免费看| 羞羞视频免费网站含羞草| 四虎必出精品亚洲高清| 亚洲成AV人片久久| 亚洲AV无码成人精品区蜜桃| 亚洲精品国产电影| 亚洲Av无码乱码在线观看性色 | 亚洲免费闲人蜜桃| 特级毛片A级毛片100免费播放| 亚洲成av人片天堂网老年人| 一级毛片免费播放视频| 色偷偷亚洲男人天堂| 亚洲精品中文字幕乱码三区| 亚洲国产成人五月综合网| 日本特黄特色aa大片免费| 最近2019中文字幕免费看最新| 6080午夜一级毛片免费看 | 无码一区二区三区AV免费| 亚洲大片免费观看| 中国xxxxx高清免费看视频| 99re视频精品全部免费| 一区二区免费视频| 美女内射无套日韩免费播放| 一区二区三区在线免费看| 国产一精品一AV一免费| 美女视频黄的免费视频网页| 成人无码WWW免费视频| 美女视频黄的免费视频网页| 久久免费视频精品| 99久久免费看国产精品| 精品无码AV无码免费专区 | 亚洲人成网站在线观看播放动漫| 亚洲无人区视频大全| 亚洲午夜久久久精品电影院|