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 阅读(156) | 评论 (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 阅读(183) | 评论 (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 阅读(124) | 评论 (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 阅读(136) | 评论 (0)编辑 收藏

new architecture(10)--NetFlow

     摘要:   阅读全文

posted @ 2007-05-10 21:27 afunms 阅读(96) | 评论 (0)编辑 收藏

new framework(9)--detach NMS from MVC


      在SourceView1.0中,采集层的对象和表现层的对象经常会混在一起,搞得很
乱。而且因为对象的不确定性给系统维护带来很大困难。
      所以在SourceView2.0的设计中,我特地把这两部分分开,分别放在mvc和nms
这两个包中。
    虽然只是简单地分为两个package,但却标志着设计思想的一大进步。

posted @ 2007-05-09 20:21 afunms 阅读(105) | 评论 (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 阅读(104) | 评论 (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 阅读(145) | 评论 (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 阅读(121) | 评论 (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 阅读(150) | 评论 (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 阅读(122) | 评论 (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 阅读(100) | 评论 (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 阅读(115) | 评论 (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 阅读(129) | 评论 (0)编辑 收藏

2007读书(3)

平时编码时不曾注意的问题,看完这本书后,改进了不少。

posted @ 2007-03-04 17:24 afunms 阅读(97) | 评论 (0)编辑 收藏

仅列出标题
共25页: First 上一页 17 18 19 20 21 22 23 24 25 下一页 

My Links

News

留言簿(18)

随笔档案

相册

搜索

最新评论

阅读排行榜