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

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

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

    afunms

    My Software,My Dream—Forge a more perfect NMS product.

    #

    dao scenario 2

    /**
     * Second scenario:transaction is rare
     * we control connection inside service classes.
     */

    /**
     * -----ConnectionManager.class---------
     */

       public static Connection getConnection()
       {
        return getConnection(ModuleConfig.getDefaultJndi());
       }
      
       public static Connection getConnection(final String jndi)
       {
        Connection conn = null;
        try
        {       
         DataSource ds = dsMap.get(jndi);
            if(ds==null) return null;
           
            conn = ds.getConnection();       
            conn.setAutoCommit(true);
        }
        catch(SQLException sqle)
        {
         SysLogger.error("Database fail to get connection 1",sqle);
        }
        catch(Exception sqle)
        {
         SysLogger.error("Database fail to get connection 2",sqle);
        }
        return conn;
       }
         
       public static void rollback(Connection conn)
       {
        try
        {
         if(conn==null || conn.isClosed())
          return;
        
         if(!conn.getAutoCommit())         
               conn.rollback();
        }
        catch(SQLException se)
        {
            SysLogger.error("Can not do rollback operation.",se);        
        }
       }  
    }  

    /**
     * -----ActionServlet.class---------
     */

       private void processHttpRequest(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException
       {   
        response.setContentType("text/html;charset=GB2312");  
        request.setCharacterEncoding("GB2312");  
       
        String beanId = extractBeanID(request.getRequestURI());
        String methodName = request.getParameter("method");   
        String targetJsp = null;
       
        if(beanId==null || methodName==null)
        {
         request.setAttribute(EXCEPTION_MESSAGE,"請求URI錯誤.");
         forward(request,response,targetJsp);
         return;
        }   
        BaseAction ba = BeanFactory.newAction(beanId);
        BaseService bs = BeanFactory.newService(beanId);
        if(ba==null || bs == null)
        {
         request.setAttribute(EXCEPTION_MESSAGE,"沒有Bean為" + beanId + "的action或service");
         forward(request,response,targetJsp);
         return;
        }
         
        ActionAnnotation ann = AnnotationExtractor.getAnnotation(ba.getClass(), methodName);
        ba.setRequest(request);
        ba.setService(bs);              
        Method method = SysUtil.lookupMethod(ba.getClass().getMethods(),methodName);   

        Connection conn = null;
        if(ann.isNeedDB())
        {

         conn = ConnectionManager.getConnection();
         bs.setConnection(conn);
         bs.setDao(BeanFactory.newDao(beanId,conn));
        }
        if(method!=null)
        {
            try
            {         
                targetJsp = (String)method.invoke(ba);
            }
            catch(Exception e)
            {
             SysLogger.error("Error:" + bs.getClass().getName() + "." + method.getName(),e);
         targetJsp = null;
            }
           }
        if(ann.isNeedDB())
         ConnectionManager.close(conn);
           forward(request,response,targetJsp);
       } 
         
       /**
        * example:method in service class
        * operating conncetion in service
        */

     /**
      * 這是兩個dao實現一個事處的最好例子
      */
     public void addTop(MenuDto dto) throws Exception
     {
      Connection conn = getConnection();
      try
                    {   
       conn.setAutoCommit(false);
       
       MenuDao mDao = new MenuDao(conn);
       MenuRoleDao mrDao = new MenuRoleDao(conn);
       MenuDto menu = mDao.getNextMenu();
       menu.setTitle(dto.getTitle());
       mDao.save(menu);
       mrDao.saveMenu(menu.getId());
       
       conn.commit();
      }
      catch(Exception e)
      {    
       ConnectionManager.rollback(conn);
                            throw e;        
      }  
     }

    posted @ 2007-05-14 14:18 afunms 閱讀(160) | 評論 (0)編輯 收藏

    dao scenario 1

    /**
     * First scenario:transaction is often used in the system
     * we control connection outside service classes.
     */

    /**
     * -----ConnectionManager.class---------
     */
       public static Connection getConnection()
       {
        return getConnection(ModuleConfig.getDefaultJndi(),true);
       }

       public static Connection getConnection(final boolean auto)
       {
        return getConnection(ModuleConfig.getDefaultJndi(),auto);
       }
      
       public static Connection getConnection(final String jndi,final boolean auto)
       {
        Connection conn = null;
        try
        {       
         DataSource ds = dsMap.get(jndi);
            if(ds==null) return null;
           
            conn = ds.getConnection();       
            conn.setAutoCommit(auto);
        }
        catch(SQLException sqle)
        {
         SysLogger.error("Database fail to get connection 1",sqle);
        }
        catch(Exception sqle)
        {
         SysLogger.error("Database fail to get connection 2",sqle);
        }
        return conn;
       }
         
       public static void rollback(Connection conn)
       {
        try
        {
         if(conn==null || conn.isClosed())
          return;
        
         if(!conn.getAutoCommit())         
               conn.rollback();
        }
        catch(SQLException se)
        {
            SysLogger.error("Can not do rollback operation.",se);        
        }
       }  
    }  

    /**
     * -----ActionServlet.class---------
     */

       private void processHttpRequest(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException
       {   
        response.setContentType("text/html;charset=GB2312");  
        request.setCharacterEncoding("GB2312");  
       
        String beanId = extractBeanID(request.getRequestURI());
        String methodName = request.getParameter("method");   
        String targetJsp = null;
       
        if(beanId==null || methodName==null)
        {
         request.setAttribute(EXCEPTION_MESSAGE,"請求URI錯誤.");
         forward(request,response,targetJsp);
         return;
        }   
        BaseAction ba = BeanFactory.newAction(beanId);
        BaseService bs = BeanFactory.newService(beanId);
        if(ba==null || bs == null)
        {
         request.setAttribute(EXCEPTION_MESSAGE,"沒有Bean為" + beanId + "的action或service");
         forward(request,response,targetJsp);
         return;
        }
         
        ActionAnnotation ann = AnnotationExtractor.getAnnotation(ba.getClass(), methodName);
        ba.setRequest(request);
        ba.setService(bs);              
        Method method = SysUtil.lookupMethod(ba.getClass().getMethods(),methodName);   

        Connection conn = null;
        if(ann.isNeedDB())
        {

       /**
        * -----get connection and set autoCommit to false---------
        */ 
        
    conn = ConnectionManager.getConnection(false);
         bs.setConnection(conn);
         bs.setDao(BeanFactory.newDao(beanId,conn));
        }
        if(method!=null)
        {
            try
            {         
                targetJsp = (String)method.invoke(ba);
        /**
         * -----if method is executed successfully,commit connection---------
         */       

          if(ann.isNeedDB()) conn.commit();
            }
            catch(Exception e)
            {
             SysLogger.error("Error:" + bs.getClass().getName() + "." + method.getName(),e);
          /**
        * connection rollback when run into exception
        */
            
    if(ann.isNeedDB()) ConnectionManager.rollback(conn);
          targetJsp = null;
            }
           }
        if(ann.isNeedDB())
         ConnectionManager.close(conn);
           forward(request,response,targetJsp);
       }  
          
          /**
         * example:method in service
      * there has not code for operating conncetion
         */
     
    public void addTop(MenuDto dto) throws Exception
     {
      Connection conn = getConnection();
      MenuDao mDao = new MenuDao(conn);
      MenuRoleDao mrDao = new MenuRoleDao(conn);
      MenuDto menu = mDao.getNextMenu();
      menu.setTitle(dto.getTitle());
      mDao.save(menu);
      mrDao.saveMenu(menu.getId());
     }

    posted @ 2007-05-13 14:09 afunms 閱讀(187) | 評論 (0)編輯 收藏

    perfect DAO design - related classes

         摘要: package afu.framework; import java.sql.Connection; import java.lang.reflect.Constructor; import afu.framework.service.*; import afu.framework.action.*; import af...  閱讀全文

    posted @ 2007-05-12 12:37 afunms 閱讀(128) | 評論 (0)編輯 收藏

    perfect DAO design

    perfect DAO solution

    ------BaseDao------
    public abstract class BaseDao
    {  
       private static final int maxRow = 1000;
       protected Connection conn;
       protected String table;
       protected Class<? extends DtoInterface> dtoClass;
       protected JspPage jspPage;
       protected boolean insideConnection;
               
       public BaseDao(Connection conn)
       { 
        init();
        if(conn==null)
        {
         this.conn = ConnectionManager.getConnection();
         insideConnection = true;        
        }
        else
        {
            this.conn = conn;   
            insideConnection = false;
        }
       }

       public BaseDao()
       { 
        init();
        this.conn = ConnectionManager.getConnection();
        insideConnection = true;   
       }

       public void close(Statement stmt,ResultSet rs)
       {
        try
           {
              if(rs!= null)
                 rs.close();
              if(stmt!=null)
                 stmt.close();
              /**
               * if the connection is passed from outside
               * do not close it.
               */
              if(insideConnection)
              ConnectionManager.close(conn);
           }
           catch(SQLException se)
           {   
           }
       }

       protected abstract void init();
    }

    ------sub dao class example------
    public class ProducerDao extends BaseDao
    {
     public ProducerDao(Connection conn)
     {
      super(conn);
     } 
     
     protected void init()
        {
         super.dtoClass = ProducerDto.class;
         super.table = "nms_producer";
        } 

    ------client code-----
    For the first scenario

       ProducerDao dao = new ProducerDao(null);
    or ProducerDao dao = (ProducerDao)BeanFactory.newDao("producer");
       dao.method();

    For the second scenario
       Connection conn = ConnectionManager.createConnection();
       ProducerDao dao1 = new ProducerDao(conn);
       AnOtherDao dao2 = new AnOtherDao(conn);
       dao1.method1();
       dao2.method2();
       dao2.method3();
       ConnectionManager.close(conn);   

    or Connection conn = ConnectionManager.createConnection();
       ProducerDao dao = (ProducerDao)BeanFactory.newDao("producer",conn);
       AnOtherDao dao = (AnOtherDao)BeanFactory.newDao("another",conn);
       dao1.method1();
       dao2.method2();
       dao2.method3();
       ConnectionManager.close(conn);   

    posted @ 2007-05-11 10:35 afunms 閱讀(140) | 評論 (0)編輯 收藏

    new architecture(10)--NetFlow

         摘要:   閱讀全文

    posted @ 2007-05-10 21:27 afunms 閱讀(100) | 評論 (0)編輯 收藏

    new framework(9)--detach NMS from MVC


          在SourceView1.0中,采集層的對象和表現層的對象經常會混在一起,搞得很
    亂。而且因為對象的不確定性給系統維護帶來很大困難。
          所以在SourceView2.0的設計中,我特地把這兩部分分開,分別放在mvc和nms
    這兩個包中。
        雖然只是簡單地分為兩個package,但卻標志著設計思想的一大進步。

    posted @ 2007-05-09 20:21 afunms 閱讀(112) | 評論 (0)編輯 收藏

    new framework(8)--import static

    現在J2SE 5.0提供了靜態導入的功能,你只需要在import關鍵字后面寫一個static關鍵字就可以直接
    使用類中定義的常量了,例如

    import static afu.framework.util.Constant.CURRENT_USER;
    import static afu.framework.util.Constant.EXCEPTION_MESSAGE;

        public String login()
        
    {
            String userId 
    = getParaValue("userid");
            String password 
    = getParaValue("password");
            String remoteIp 
    = request.getRemoteAddr();
            UserDto dto 
    = ((SysService)service).login(userId, password, remoteIp);
            
            
    if(dto==null)
            
    {
                request.setAttribute(EXCEPTION_MESSAGE,
    "用戶名或密碼不對");
                
    return null;
            }

            request.setAttribute(CURRENT_USER,dto);
            
    return "/common/index.jsp";
        }


    而沒有這個功能之前,我們得這么寫
    request.setAttribute(Constant.EXCEPTION_MESSAGE,"用戶名或密碼不對");

    posted @ 2007-05-08 10:40 afunms 閱讀(111) | 評論 (0)編輯 收藏

    new framework(7)--build sql via reflect

    利用反射構成SQL語句,這樣,對于一般表的CURD,都可快速實現。

       protected String buildInsertSQL(ResultSetMetaData rsm,DtoInterface dto)
       
    {
           String insertSql 
    = null;
           
    try
           
    {
               StringBuffer sqlBuf 
    = new StringBuffer(50);
               StringBuffer valueBuf 
    = new StringBuffer(50);
               sqlBuf.append(
    "insert into ").append(table).append("(");
               
    for(int i=1;i<=rsm.getColumnCount();i++
               
    {
                   String methodName 
    = "get" + rsm.getColumnName(i).replaceAll("_"""); 
                   Method method 
    = lookupMethod(dtoClass.getMethods(), methodName);
                   
    if(method==null
                   

                       SysLogger.debug(
    "get" + rsm.getColumnName(i) + " does not exist"); 
                       
    continue;
                   }
     
                   sqlBuf.append(rsm.getColumnName(i)).append(
    ",");
                   valueBuf.append(
    "'").append(method.invoke(dto)).append("',");               
               }

               sqlBuf.delete(sqlBuf.length() 
    - 1, sqlBuf.length());
               valueBuf.delete(valueBuf.length() 
    - 1, valueBuf.length());
               sqlBuf.append(
    ")values(").append(valueBuf.toString()).append(")");
               insertSql 
    = sqlBuf.toString();
               SysLogger.debug(insertSql);
           }

           
    catch(Exception e)
           
    {
               SysLogger.error(
    "BaseDao.buildInsertSQL()",e);           
           }

           
    return insertSql;
       }

       
       
    protected String buildUpdateSQL(ResultSetMetaData rsm,DtoInterface dto)
       
    {
           String updateSql 
    = null;
           
    try
           
    {
               Method getId 
    = lookupMethod(dtoClass.getMethods(),"getId");
               
    if(getId==null)
               
    {
                   SysLogger.error(dtoClass.getClass().getName() 
    + ":getId method does not exist");
                   
    return null;
               }

               StringBuffer sqlBuf 
    = new StringBuffer(100);
               sqlBuf.append(
    "update ").append(table).append(" set ");
               
    for(int i=1;i<=rsm.getColumnCount();i++
               
    {
                   
    if(rsm.getColumnName(i).equals("id")) continue;
                   
                   String methodName 
    = "get" + rsm.getColumnName(i).replaceAll("_"""); 
                   Method method 
    = lookupMethod(dtoClass.getMethods(), methodName);
                   
    if(method==null
                   

                       SysLogger.debug(
    "get" + rsm.getColumnName(i) + " does not exist"); 
                       
    continue;
                   }
                    
                   sqlBuf.append(rsm.getColumnName(i)).append(
    "='");
                   sqlBuf.append(method.invoke(dto)).append(
    "',");               
               }

               sqlBuf.delete(sqlBuf.length() 
    - 1, sqlBuf.length());           
               sqlBuf.append(
    " where id='").append(getId.invoke(dto)).append("'");
               updateSql 
    = sqlBuf.toString();
               SysLogger.debug(updateSql);
           }

           
    catch(Exception e)
           
    {
               SysLogger.error(
    "BaseDao.buildUpdateSQL()",e);           
           }

           
    return updateSql;   
       }


     

    posted @ 2007-05-07 22:33 afunms 閱讀(151) | 評論 (0)編輯 收藏

    new framework(6)--extract data from ResultSet via reflect

    今天試了一下用反射從ResultSet 提取數據,然后調用相應的dto的方法。
    這樣就不要每次都針對一個新表來寫一次extractData方法了,挺爽的。
    缺點就是數據表中的字段與dto的方法必須一一對應。

       /**
        * extract data from ResultSet to dto
        
    */

       
    protected DtoInterface extractData(ResultSet rs) throws Exception
       
    {
           
    if(dtoClass == null

              
    throw new NullPointerException("dtoClass is not setted!"
    ); 
           
           DtoInterface dto 
    =
     dtoClass.newInstance();
           ResultSetMetaData rsm 
    =
     rs.getMetaData(); 
           
    for(int i=1;i<=rsm.getColumnCount();i++

           

               String methodName 
    = "set" + rsm.getColumnName(i).replaceAll("_"""
    ); 
               SysLogger.debug(
    "[" + rsm.getColumnName(i) + "]=" + rsm.getColumnType(i) + ",method=" +
     methodName);
               Method method 
    =
     lookupMethod(dtoClass.getMethods(), methodName);
               
    if(method==null

               

                   SysLogger.error(
    "set" + rsm.getColumnName(i) + " does not exist"
    ); 
                   
    continue
    ;
               }
     
               
    if(rsm.getColumnType(i)==
    Types.INTEGER) 
                  method.invoke(dto,rs.getInt(i)); 
               
    else if(rsm.getColumnType(i)==
    Types.VARCHAR) 
                  method.invoke(dto,rs.getString(i)); 
           }
     
           
    return
     dto; 
       }

       
       
    protected Method lookupMethod(Method[] methods,String methodName) 
       

           Method result 
    = null

           
    for
    (Method method:methods) 
           

               
    if
    (method.getName().equalsIgnoreCase(methodName)) 
               

                   result 
    =
     method; 
                   
    break

               }
     
           }

           
    return result; 
        }
     

    posted @ 2007-05-06 22:33 afunms 閱讀(126) | 評論 (0)編輯 收藏

    new framework(5)--build selectBox via reflect

         摘要: html中的selectBox也是令我頭疼的東西,因為它總和數據庫關聯,但我們在jsp中又不能直接調用dao, 就算直接調用了dao,jsp中的代碼也是一團亂。所以我專門寫了這個類來解決這個問題。 我們只要專一個list給它,并告訴哪個方法可以得到key,哪個方法可以得到value, 就能生成一個selectBox。 package afu.framework.util; ...  閱讀全文

    posted @ 2007-05-05 21:10 afunms 閱讀(153) | 評論 (0)編輯 收藏

    new framework(4)--fetch request parameters value via reflect

    最討厭就是寫一大堆request.getParameter,新架構中利用反射自動提取request中的參數值,
    然后把它們封閉成一個dto,真是太爽了。

     

        protected DtoInterface extractData(Class<? extends DtoInterface> clazz)
        
    {
            DtoInterface dto 
    = null;
            
    try
            
    {
                dto 
    = clazz.newInstance();
                Method[] methods 
    = clazz.getMethods();
                
    for(Method method:methods)
                
    {
                    
    if(!method.getName().startsWith("set")) continue;
                    
                    String paraValue 
    = getParaValueByMethodName(method.getName().substring(3));
                    
    if(paraValue==nullcontinue;
                    
                    Class
    <?>[] types = method.getParameterTypes();
                    
    if(types==null || types.length==0)
                        
    continue;
                    
    //                System.out.println("methodName=" + method.getName());
    //                System.out.println("para=" + method.getName().substring(3));
    //                System.out.println("paraValue=" + paraValue);
                    
                    
    if(types[0].getName().equals("int"))
                       method.invoke(dto,Integer.parseInt(paraValue));
                    
    else if(types[0].getName().equals("long"))    
                       method.invoke(dto,Long.parseLong(paraValue));
                    
    else if(types[0].getName().equals("double"))    
                        method.invoke(dto,Double.parseDouble(paraValue));
                    
    else if(types[0].getName().equals("float"))    
                         method.invoke(dto,Float.parseFloat(paraValue));
                    
    else
                       method.invoke(dto,paraValue); 
    //String    
                }

            }

            
    catch(Exception e)
            
    {
                SysLogger.error(
    "BaseAction.extractData()",e);    
            }

            
    return dto;
        }

        
        
    private String getParaValueByMethodName(String para)
        
    {
            String result 
    = null;
            
    for (Enumeration em = request.getParameterNames() ; em.hasMoreElements() ;)
            
    {
                String name 
    = (String)(em.nextElement());
                String temp 
    = name.replaceAll("_","");
                
    if(para.equalsIgnoreCase(temp))
                
    {
                    result 
    = request.getParameter(name);
                    
    break;
                }

            }

            
    return result;
        }

     

    posted @ 2007-05-04 20:56 afunms 閱讀(129) | 評論 (0)編輯 收藏

    new framework(3)--why add service

     之前的架構都沒有service這一層,jsp到manager(action),然后在manager中調用dao。
    Action其實屬于web這一層,在web層直接調用dao是不妥的,所以新架構中多了一層

    Service。Service位于action和dao之間,action把從jsp中傳來的參數封裝好傳給dao。

    我覺得最大好處就是不會在調用dao的同時又看到一大堆request.getParameter代碼。

    posted @ 2007-05-03 13:34 afunms 閱讀(105) | 評論 (0)編輯 收藏

    new framework(2)--why put Statement inside dao method

    原來Statement stmt = conn.createStatement();都是在放在BaseDao中,
    子類dao的方法中就可以直接用這個stmt,而且方法最后都會用finally
    來close這個stmt以及rs。

    這個做不好,因為new一個dao后,不能連續調用兩個方法,因為前一個方法
    已經把stmt關閉掉了。

    因此新架構中,在每個方法中都加入Statement stmt = conn.createStatement();
    這樣就不會有上述問題了,但以增加代碼量為代價。
       例子:

        public void addSub(MenuDto dto)
        
    {
            Connection conn 
    = getConnection();
            
    try
            
    {            
                MenuDao mDao 
    = new MenuDao(conn);
                MenuRoleDao mrDao 
    = new MenuRoleDao(conn);
                MenuDto menu 
    = mDao.getNextMenu(dto.getId().substring(0,2));
                
                dto.setId(menu.getId());
                dto.setSort(menu.getSort());
                
                mDao.save(dto);
                mrDao.saveMenu(menu.getId());
            }

            
    catch(Exception e)
            
    {     
                ConnectionManager.rollback(conn);
                SysLogger.error(
    "MenuService.addSub()",e);            
            }
            
        }

    MenuDao連續調用了兩個方法getNextMenusave,如果不把

    Statement stmt = conn.createStatement()置于方法內,那么我們要這樣寫:

               MenuDao mDao = new MenuDao(conn);

               MenuDto menu = mDao.getNextMenu(dto.getId().substring(0,2));          

    MenuDao mDao2 = new MenuDao(conn);

               mDao2.save(dto);

    new兩次,不是不可以,但讓人感覺很不爽。

    posted @ 2007-05-02 13:24 afunms 閱讀(119) | 評論 (0)編輯 收藏

    new framework(1)--why put Connection outside dao

        原來我們都是在new dao時,同時獲得一個Connection  
        DaoInterface dao = new XxxxDao();

        為什么新架構把Connection放在dao之外呢?為了實現事務。
        當一個事務需要調用兩個dao中兩個(以上)方向時,如果出錯,
    只有同一個Connection才能實現rollback。
        DaoInterface dao = new XxxxDao(connection);

        /**
         * 這是兩個dao實現一個事處的最好例子
         
    */

        
    public void addTop(MenuDto dto)
        
    {
            Connection conn 
    = getConnection();
            
    try
            
    {            
                MenuDao mDao 
    = new MenuDao(conn);
                MenuRoleDao mrDao 
    = new MenuRoleDao(conn);
                MenuDto menu 
    = mDao.getNextMenu();
                menu.setTitle(dto.getTitle());
                mDao.save(menu);
                mrDao.saveMenu(menu.getId());
            }

            
    catch(Exception e)
            
    {     
                ConnectionManager.rollback(conn);
                SysLogger.error(
    "MenuService.addTop()",e);            
            }
            
        }
        當然,我們也可以把所有的SQL寫在個dao中,同樣能實現rollback,
    但這樣做違背了dao操作的“原子性”。

    posted @ 2007-05-01 13:10 afunms 閱讀(133) | 評論 (0)編輯 收藏

    2007讀書(3)

    平時編碼時不曾注意的問題,看完這本書后,改進了不少。

    posted @ 2007-03-04 17:24 afunms 閱讀(99) | 評論 (0)編輯 收藏

    僅列出標題
    共25頁: First 上一頁 17 18 19 20 21 22 23 24 25 下一頁 

    My Links

    News

    留言簿(18)

    隨筆檔案

    相冊

    搜索

    最新評論

    閱讀排行榜

    主站蜘蛛池模板: 国产亚洲高清不卡在线观看| 亚洲日韩在线观看| 亚洲.国产.欧美一区二区三区| 成人毛片18女人毛片免费96| 亚洲国产精品成人AV在线| 免费一级毛片在线播放| 国产精品成人啪精品视频免费| 久久精品国产亚洲一区二区| 91久久青青草原线免费| 亚洲AV无码久久久久网站蜜桃| 免费高清在线影片一区| 永久免费观看黄网站| 亚洲av无码国产精品色午夜字幕| 精品成在人线AV无码免费看| 亚洲国产一区二区三区在线观看 | 羞羞视频在线免费观看| 不卡精品国产_亚洲人成在线| 99精品视频在线观看免费播放| 亚洲精品国产精品国自产网站| 国产大片免费观看中文字幕| 免费A级毛片无码专区| 日本一区二区在线免费观看| 亚洲人成毛片线播放| 在线A亚洲老鸭窝天堂| 在线观看永久免费视频网站| 日韩中文字幕免费视频| 一级毛片免费播放视频| 亚洲一级大黄大色毛片| 亚洲av午夜福利精品一区人妖| 免费国内精品久久久久影院| 无码区日韩特区永久免费系列| 最近免费中文字幕中文高清| 久久九九兔免费精品6| 黄色视频在线免费观看| 亚洲精品无码久久久久牙蜜区| 亚洲精品私拍国产福利在线| 国产亚洲精品拍拍拍拍拍| 全部免费a级毛片| 妞干网在线免费视频| 中文免费观看视频网站| 99热在线观看免费|