posts - 29, comments - 0, trackbacks - 0, articles - 0
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

在ApplicationContext.xml 里面的配置:


<!-- begin day -->

<bean id="Initlogdatatarget" class="com.sotrip.statistic.scheduling.Initlogdata">
 <property name="tlogvisitDAO"><ref local="tlogvisitDAO"/></property>
 </bean>
<bean id="Jobfortimerdaysservice"
     class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
 <property name="transactionManager"><ref local="transactionManager"/></property>
 <property name="target"><ref local="Initlogdatatarget"/></property>
 <property name="transactionAttributes">
  <props>  
   <prop key="exec*">PROPAGATION_REQUIRED</prop>
  </props>
 </property>
</bean>

<bean id="methodInvokingJobDetail"
 class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <!--**** 此处的 targetObject 所指定的bean Jobfortimerdaysservice 需是service层的,通过它定义的事务属性 就可以使得 targetMethod 所定义的方法具有事务属性。-->
 <property name="targetObject"><ref bean="Jobfortimerdaysservice"/></property>
 <property name="targetMethod"><value>execute</value></property>
</bean>

<bean id="cronTrigger"
 class="org.springframework.scheduling.quartz.CronTriggerBean">
 <property name="jobDetail">
  <ref bean="methodInvokingJobDetail"/>
 </property>
 <property name="cronExpression">
  <value>0 0/2 * * * ?</value>
 </property>
</bean>

<!-- end day-->

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
 <property name="triggers">
  <list>
<!--  <ref local="cronTriggertest"/>-->
   <ref local="cronTrigger"/>
    <ref local="cronTriggermonth"/><!-- 此处可以配置多个trigger-->
  </list>
 </property>
</bean>

在就是定时时间的定义:

Cron-Expressions are used to configure instances of CronTrigger. Cron-Expressions are strings that are actually made up of seven sub-expressions, that describe individual details of the schedule. These sub-expression are separated with white-space, and represent:

  1. Seconds
  2. Minutes
  3. Hours
  4. Day-of-Month
  5. Month
  6. Day-of-Week
  7. Year (optional field)

An example of a complete cron-expression is the string "0 0 12 ? * WED" - which means "every Wednesday at 12:00 pm".

cronExpression配置说明

字段   允许值   允许的特殊字符
  0-59   , - * /
  0-59   , - * /
小时   0-23   , - * /
日期   1-31   , - * ? / L W C
月份   1-12 或者 JAN-DEC   , - * /
星期   1-7 或者 SUN-SAT   , - * ? / L C #
年(可选)   留空, 1970-2099   , - * /

 


posted @ 2007-05-28 15:37 change| 编辑 收藏

在spring里面我们一般是这样来使用模板模式的:

JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.update("UPDATE user SET age = 10 WHERE id = 'erica'");

或者:

JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate
.update(
"UPDATE user SET age = ? WHERE id = ?",
new PreparedStatementSetter() {
public void setValues(PreparedStatementSetter ps)
throws SQLException {
ps.setInt(1, 18);
ps.setString(2, "erica");
}
}
);

那么具体在spring里面他是怎么运作的呢?

下面以query查询为例:

public class JdbcTemplate extends JdbcAccessor implements JdbcOperations, InitializingBean {

。。。。。。。。。。。。。。。。。。。。。。。。。

protected Object query(
   PreparedStatementCreator psc, final PreparedStatementSetter pss, final ResultSetExtractor rse)
   throws DataAccessException {
  if (logger.isDebugEnabled()) {
   String sql = getSql(psc);
   logger.debug("Executing SQL query" + (sql != null ? " [" + sql  + "]" : ""));
  }
  return execute(psc, new PreparedStatementCallback() {

//此处以 PreparedStatementCallback 为参数调用 execute()方法,在execute()方法里面回调传入的方法。在回调方法里面即根据传入的 PreparedStatement 执行 查询操作,返回结果。而 PreparedStatement  的获取是在调用回调方法的客户端实现即在execute()方法里面获取,并作为参数传给回调方法。
   public Object doInPreparedStatement(PreparedStatement ps) throws SQLException {
    ResultSet rs = null;
    try {
     if (pss != null) {
      pss.setValues(ps);
     }
     if (getFetchSize() > 0) {
      ps.setFetchSize(getFetchSize());
     }
     rs = ps.executeQuery();
     ResultSet rsToUse = rs;
     if (nativeJdbcExtractor != null) {
      rsToUse = nativeJdbcExtractor.getNativeResultSet(rs);
     }
     return rse.extractData(rsToUse);
    }
    finally {
     JdbcUtils.closeResultSet(rs);
     if (pss instanceof ParameterDisposer) {
      ((ParameterDisposer) pss).cleanupParameters();
     }
    }
   }
  });
 }

那么在execue()方法里面是怎样回调的呢?下面看看execue()方法:

public Object execute(PreparedStatementCreator psc, PreparedStatementCallback action) {
  Connection con = DataSourceUtils.getConnection(getDataSource());
  PreparedStatement ps = null;
  try {
   Connection conToUse = con;
   if (this.nativeJdbcExtractor != null &&
     this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativePreparedStatements()) {
    conToUse = this.nativeJdbcExtractor.getNativeConnection(con);
   }
   ps = psc.createPreparedStatement(conToUse);
   DataSourceUtils.applyTransactionTimeout(ps, getDataSource());
   PreparedStatement psToUse = ps;
   if (this.nativeJdbcExtractor != null) {
    psToUse = this.nativeJdbcExtractor.getNativePreparedStatement(ps);
   }
   Object result = action.doInPreparedStatement(psToUse);
   SQLWarning warning = ps.getWarnings();
   throwExceptionOnWarningIfNotIgnoringWarnings(warning);
   return result;
  }
  catch (SQLException ex) {
   throw getExceptionTranslator().translate(
     "executing PreparedStatementCallback [" + psc + "]", getSql(psc), ex);
  }
  finally {
   if (psc instanceof ParameterDisposer) {
    ((ParameterDisposer) psc).cleanupParameters();
   }
   JdbcUtils.closeStatement(ps);
   DataSourceUtils.closeConnectionIfNecessary(con, getDataSource());
  }
 }

添加删除的操作类似,只是他们的实现都在以execute命名的方法里面。

public void execute(final String sql) throws DataAccessException {
  if (logger.isDebugEnabled()) {
   logger.debug("Executing SQL statement [" + sql + "]");
  }
  class ExecuteStatementCallback implements StatementCallback, SqlProvider {
   public Object doInStatement(Statement stmt) throws SQLException {
    stmt.execute(sql);
    return null;
   }
   public String getSql() {
    return sql;
   }
  }
  execute(new ExecuteStatementCallback());
 }

public Object execute(final StatementCallback action) {
  Connection con = DataSourceUtils.getConnection(getDataSource());
  Statement stmt = null;
  try {
   Connection conToUse = con;
   if (this.nativeJdbcExtractor != null &&
     this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativeStatements()) {
    conToUse = this.nativeJdbcExtractor.getNativeConnection(con);
   }
   stmt = conToUse.createStatement();
   DataSourceUtils.applyTransactionTimeout(stmt, getDataSource());
   Statement stmtToUse = stmt;
   if (this.nativeJdbcExtractor != null) {
    stmtToUse = this.nativeJdbcExtractor.getNativeStatement(stmt);
   }
   Object result = action.doInStatement(stmtToUse);
   SQLWarning warning = stmt.getWarnings();
   throwExceptionOnWarningIfNotIgnoringWarnings(warning);
   return result;
  }
  catch (SQLException ex) {
   throw getExceptionTranslator().translate("executing StatementCallback", getSql(action), ex);
  }
  finally {

//这里就是我们自己写程序的时候需要写的关于数据库链接的关闭操作
   JdbcUtils.closeStatement(stmt);
   DataSourceUtils.closeConnectionIfNecessary(con, getDataSource());
  }
 }

posted @ 2007-05-28 15:34 change| 编辑 收藏

Spring 的声明式事务是通过TransactionProxyFactoryBean 来实现的,而它是通过持有一个拦截器:TransactionInterceptor 来做到的。

public class TransactionProxyFactoryBean extends ProxyConfig implements FactoryBean, InitializingBean {

 private final TransactionInterceptor transactionInterceptor = new TransactionInterceptor();

 /**
  * Set the transaction manager. This will perform actual
  * transaction management: This class is just a way of invoking it.
  * @see TransactionInterceptor#setTransactionManager
  */
 public void setTransactionManager(PlatformTransactionManager transactionManager) {
  this.transactionInterceptor.setTransactionManager( transactionManager);
 }

。。。。。。。。。。//声明的事务属性在这里得到                                   

                                       //见(DefaultTransactionDefinition)定义

}

//TransactionInterceptor 在service层的方法调用的时候,会更具配置判断调用的方法//是否需要事务的处理,若需要则获取设置事务属性对象和事务管理器并启动一个//事务,而其具体的实现是委托给 TransactionAspectSupport 类的//createTransactionIfNecessary 方法实现的,其类结构如下

public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor {

 public Object invoke(MethodInvocation invocation) throws Throwable {
  // Work out the target class: may be null.
  // The TransactionAttributeSource should be passed the target class
  // as well as the method, which may be from an interface
  Class targetClass = (invocation.getThis() != null) ? invocation.getThis().getClass() : null;
  
  // Create transaction if necessary
  TransactionInfo txInfo = createTransactionIfNecessary(invocation.getMethod(), targetClass);//此处即是根据配置的声明性事务属性决定方法事务级别

  Object retVal = null;
  try {
   // This is an around advice.
   // Invoke the next interceptor in the chain.
   // This will normally result in a target object being invoked.
   retVal = invocation.proceed();
  }
  catch (Throwable ex) {
   // target invocation exception
   doCloseTransactionAfterThrowing(txInfo, ex);
   throw ex;
  }
  finally {
   doFinally(txInfo);
  }
  doCommitTransactionAfterReturning(txInfo);

  return retVal;
 }
 
}

//在TransactionAspectSupport 类方法createTransactionIfNecessary()里面根据配置的声明性事务属性,决定启动一个事务,和返回事务级别(信息):

protected TransactionInfo createTransactionIfNecessary(Method method, Class targetClass) {
  // If the transaction attribute is null, the method is non-transactional
  TransactionAttribute transAtt = this.transactionAttributeSource.getTransactionAttribute(method, targetClass);
  TransactionInfo txInfo = new TransactionInfo(transAtt, method);
  if (transAtt != null) {
   // We need a transaction for this method
   if (logger.isDebugEnabled()) {
    logger.debug("Getting transaction for " + txInfo.joinpointIdentification());
   }

   // The transaction manager will flag an error if an incompatible tx already exists

   txInfo.newTransactionStatus(this.transactionManager.getTransaction(transAtt));

//此处的参数 this.transactionManager.getTransaction(transAtt) 即是调用各具体平台的 transactionManager 来获取她的事务属性,在获取事务属性的同时她会更具具体的事务属性 来决定是否开始和怎么开始一个事务;见类AbstractPlatformTransactionManager  结构。

 public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager, Serializable {

。。。。。。。。。。。。。。。。。。。。。

public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {

if (isExistingTransaction(transaction)) {

//下面即是 更具具体的配置事务属性 来决定事务
   if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER)
{
    throw new IllegalTransactionStateException(
      "Transaction propagation 'never' but existing transaction found");
   }
   if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
    if (debugEnabled) {
     logger.debug("Suspending current transaction");
    }
    Object suspendedResources = suspend(transaction);
    boolean newSynchronization = (this.transactionSynchronization == SYNCHRONIZATION_ALWAYS);
    return newTransactionStatus(
      null, false, newSynchronization, definition.isReadOnly(), debugEnabled, suspendedResources);
   }
   else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
    if (debugEnabled) {
     logger.debug("Creating new transaction, suspending current one");
    }
    Object suspendedResources = suspend(transaction);

//此处的doBegin 方法给更具具体的平台和配置事务属性来启动一个事务
    doBegin(transaction, definition);
    boolean newSynchronization = (this.transactionSynchronization != SYNCHRONIZATION_NEVER);
    return newTransactionStatus(
      transaction, true, newSynchronization, definition.isReadOnly(), debugEnabled, suspendedResources);
   }

。。。。。。。。。。。。。。。。。。。。。

}

  // We always bind the TransactionInfo to the thread, even if
  // we didn't create a new transaction here.
  // This guarantees that the TransactionInfo stack will be
  // managed correctly even if no transaction was created by
  // this aspect.
  txInfo.bindToThread();
  return txInfo;
 }

//下面是事务的提交操作,回滚类似

protected void doCommitTransactionAfterReturning(TransactionInfo txInfo) {
  if (txInfo != null && txInfo.hasTransaction()) {
   if (logger.isDebugEnabled()) {
    logger.debug("Invoking commit for transaction on " + txInfo.joinpointIdentification());
   }

  //这里的transactionManager 就是Spring配置文件里面配置的事务 如:org.springframework.orm.hibernate3.HibernateTransactionManager 。
   this.transactionManager.commit(txInfo.getTransactionStatus());

  }
 }

//

protected void doFinally(TransactionInfo txInfo) {
  if (txInfo != null) {
   txInfo.restoreThreadLocalStatus();
  }
 }
private void restoreThreadLocalStatus() {
   // Use stack to restore old transaction TransactionInfo.
   // Will be null if none was set.
   currentTransactionInfo.set(oldTransactionInfo);
  }

//下面以 HibernateTransactionManager  例,说说事务的开始和提交/回滚

//此dobegin()方法即是开始一个事务
 protected void doBegin(Object transaction, TransactionDefinition definition) {
  HibernateTransactionObject txObject = (HibernateTransactionObject) transaction;

  if (txObject.getSessionHolder() == null) {
   Session session = SessionFactoryUtils.getSession(
     getSessionFactory(), getEntityInterceptor(), getJdbcExceptionTranslator(), false);
   if (logger.isDebugEnabled()) {
    logger.debug("Opened new session [" + session + "] for Hibernate transaction");
   }
   txObject.setSessionHolder(new SessionHolder(session), true);
  }

  txObject.getSessionHolder().setSynchronizedWithTransaction(true);
  Session session = txObject.getSessionHolder().getSession();

  try {
   Connection con = session.connection();
   Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
   txObject.setPreviousIsolationLevel(previousIsolationLevel);

   if (definition.isReadOnly() && txObject.isNewSessionHolder()) {
    // just set to NEVER in case of a new Session for this transaction
    session.setFlushMode(FlushMode.NEVER);
   }

   if (!definition.isReadOnly() && !txObject.isNewSessionHolder()) {
    // we need AUTO or COMMIT for a non-read-only transaction
    FlushMode flushMode = session.getFlushMode();
    if (FlushMode.NEVER.equals(flushMode)) {
     session.setFlushMode(FlushMode.AUTO);
     txObject.getSessionHolder().setPreviousFlushMode(flushMode);
    }
   }

   // add the Hibernate transaction to the session holder

//此处即是真正的调用了hibernate的session开始一个事务session.beginTransaction() 。
   txObject.getSessionHolder().setTransaction(session.beginTransaction());

   // register transaction timeout
   if (definition.getTimeout() != TransactionDefinition.TIMEOUT_DEFAULT) {
    txObject.getSessionHolder().setTimeoutInSeconds(definition.getTimeout());
   }

   // register the Hibernate Session's JDBC Connection for the DataSource, if set
   if (getDataSource() != null) {
    ConnectionHolder conHolder = new ConnectionHolder(con);
    if (definition.getTimeout() != TransactionDefinition.TIMEOUT_DEFAULT) {
     conHolder.setTimeoutInSeconds(definition.getTimeout());
    }
    if (logger.isDebugEnabled()) {
     logger.debug("Exposing Hibernate transaction as JDBC transaction [" +
       conHolder.getConnection() + "]");
    }
    TransactionSynchronizationManager.bindResource(getDataSource(), conHolder);
    txObject.setConnectionHolder(conHolder);
   }

   // bind the session holder to the thread
   if (txObject.isNewSessionHolder()) {
    TransactionSynchronizationManager.bindResource(getSessionFactory(), txObject.getSessionHolder());
   }
  }

  catch (Exception ex) {
   SessionFactoryUtils.closeSessionIfNecessary(session, getSessionFactory());
   throw new CannotCreateTransactionException("Could not create Hibernate transaction", ex);
  }
 }

//回滚

protected void doCommit(DefaultTransactionStatus status) {
  HibernateTransactionObject txObject = (HibernateTransactionObject) status.getTransaction();

。。。。。。。。。。。。。。。。。。。。。。。。。。
  try {
   txObject.getSessionHolder().getTransaction().commit();
  }
  catch (net.sf.hibernate.TransactionException ex) {
   // assumably from commit call to the underlying JDBC connection
   throw new TransactionSystemException("Could not commit Hibernate transaction", ex);
  }
  catch (JDBCException ex) {
   // assumably failed to flush changes to database
   throw convertJdbcAccessException(ex.getSQLException());
  }
  catch (HibernateException ex) {
   // assumably failed to flush changes to database
   throw convertHibernateAccessException(ex);
  }
 }

  }
  else {
   // The TransactionInfo.hasTransaction() method will return
   // false. We created it only to preserve the integrity of
   // the ThreadLocal stack maintained in this class.
   if (logger.isDebugEnabled())
    logger.debug("Don't need to create transaction for " + methodIdentification(method) +
      ": this method isn't transactional");
  }

posted @ 2007-05-28 15:33 change| 编辑 收藏

引用:http://shidu.blogbus.com/logs/2004/12/540365.html

配置文件大概如下:
<action-mappings>
<action path="/account"
name="accountForm"
parameter="action"
scope="request"
type="com.ai.uaap.admin.web.action.AccountAction">
<forward name="listOK" path="/AccountMaster.jsp" />
<forward name="removeOK" path="/account.do?action=list" redirect="true" />
</action>

我在执行完remove的方法之后的代码是return mapping.findForward("removeOK")。这时就会访问account.do?action=list这个地址,以前我想在account.do?action=list之后继续添加参数(例如account.do?action=list&abc=123)不知道该怎么实现。

今天看到一个资料给出了实现:
String path = mapping.findForward("removeOK").getPath();
ActionForward forward = new ActionForward(path + "&abc=123", true);
//这里的true是Redirect
return forward;

posted @ 2007-05-28 15:32 change| 编辑 收藏

CREATE TABLE V_GIS_MONTH
(
  ID         VARCHAR2(255 BYTE)                 NOT NULL,
  VISITTIME  DATE                               DEFAULT NULL,
  GISNAME    VARCHAR2(255 BYTE),
  GISLEVEL   VARCHAR2(255 BYTE),
  PARENT     VARCHAR2(255 BYTE),
  VNUMBER    NUMBER(19),
  IPFROM     VARCHAR2(255 BYTE),
  IPLEVEL    VARCHAR2(2 BYTE),
  GISPATH    VARCHAR2(1024 BYTE)
)
TABLESPACE USERS

PCTUSED    0
PCTFREE    10
INITRANS   1
MAXTRANS   255
STORAGE    (
            INITIAL          64K
            MINEXTENTS       1
            MAXEXTENTS       2147483645
            PCTINCREASE      0
            BUFFER_POOL      DEFAULT
           )
LOGGING
NOCACHE
NOPARALLEL;


ALTER TABLE V_GIS_MONTH ADD (
  PRIMARY KEY (ID)
    USING INDEX
    TABLESPACE USERS
    PCTFREE    10
    INITRANS   2
    MAXTRANS   255
    STORAGE    (
                INITIAL          64K
                MINEXTENTS       1
                MAXEXTENTS       2147483645
                PCTINCREASE      0
               ));


select gisdays.ipfrom,gisdays.gisname,sum(gisdays.vnumber)AS count from V_Gis_Month gisdays where gisdays.GISPATH = '/sotrip_dest/destination_home/china/zhejiang/' and gisdays.iplevel='3' group by gisdays.ipfrom,gisdays.gisname ORDER BY count desc;

gis:表示目的地

在数据库里面这样的查询是可以的,但是用这样的语句在hibernate的DAO层

这样做:

String queryString = "select gisdays.ipfrom,sum(gisdays.vnumber) AS count  from "+strtable+" gisdays where gisdays.iplevel='"+striplevel+"' "+strquery+" and to_char(gisdays.visittime,'YYYY-MM-DD')  between '"+strfrom+"' and '"+strto+"' group by gisdays.ipfrom ORDER BY count desc";           
  

Iterator iterator = this.getHibernateTemplate().find(queryString).iterator();

是不行的,会出现异常,报错。

改为:

String queryString = "select gisdays.ipfrom,sum(gisdays.vnumber)  from "+strtable+" gisdays where gisdays.iplevel='"+striplevel+"' "+strquery+" and to_char(gisdays.visittime,'YYYY-MM-DD')  between '"+strfrom+"' and '"+strto+"' group by gisdays.ipfrom ORDER BY sum(gisdays.vnumber) desc";           

 Iterator iterator = this.getHibernateTemplate().find(queryString).iterator();

while(iterator.hasNext())
  {
   Object[] pair = (Object[])iterator.next();   
   VGisMonth gismonth = new VGisMonth();
   for(int i=0;i<pair.length;i++)
   {
    System.out.println("pair["+i+"]="+pair[i]);
   }

}//这里iterator 所返回的是对象数组,它把取得的每一列都作为一个对象,然后返回一个对象数组的叠代器,然后我们就可以取出里面的每一列(对象)转换成相应的数据类型,(这里 strtable 是table所对应的实体的名字)

就可以了。应该是在里面不支持对  统计添加的列 的别名命名吧。呵呵:)

posted @ 2007-05-28 15:31 change| 编辑 收藏

      本命年已经悄然过去,在这一年里面确实有太多的心酸泪史。虽然没有招受太多肉体上的伤害,但是生心的痛苦远胜于此。

       过去的日子总感觉自己活的浑浑噩噩的。生活,学习,感情,都是一团糟。然而在这段晕呼的岁月里面却有一件事情总是不间断,那就是思索生活的意义。”活着是为了什么“,“。。。”诸如此类的莫名其妙的为什么还有很多很多,我想我都快可以自己在写一本十万个为什么了。说句老实话,本人没有为了人类的从高理想而活的高尚情操,所以这种思索只会让我变得更加的颓废,萎缩。我想不清楚这么高深的问题。也许是太富有哲理性了,更本就不是我这种凡夫俗子所能够想的通的。对于这种问题的思索让我失去了方向,干什么事情都找不着北。也因此带来了很多的困扰,也因此而承受了很多原本就不应该承受的负担。太多的思绪,太多的顾虑,太多的想不通,太多,太多,太多的问题使我的脑袋都已经在塞不下任何其他的东西。

      在这一年里面,我们去了索创的培训,这确实是一个不错的机会,然而心不在焉的也没有把心思花在上面,一连串的心事让我身在教室心在外。虽是基本不间断的去上课,可我能够感觉的到,我像是一具形尸走肉,盲目的穿行在纷乱的人群里面。感觉自己真的使那么的孤单,那么的无助。慢慢的自己也就开始喜欢上了幻想,喜欢活在自己的梦里面。

       在后来就进了公司去实习,这也许就是一个战时的避难所,然而它并没有使我得到多少解脱,我还是依然活在我的梦里面。我希望通过不间歇的劳作使自己尽量的不要理会那些身外之事,然而我毕竟还没有去少林出家,自然少不了七情六欲,固然没有炼得真身,依然为尘世所绕。也许活在自己的梦里面是幸福的,梦真的醒来也是幸福的,但是我却处在了阴阳交界似睡非省的边缘。糊里糊涂的活着,活在稀里糊涂的世界里面。。。

       有人说失败的男人才会想家。看来我真的是一个失败的男人,因为今年的我就特别的想回家。也许我真的是需要在家里调养一下,忘却我心中的那份不应有的牵挂。

posted @ 2007-05-28 15:31 change| 编辑 收藏

相信大家对于mvc模式并不陌生,它的主要作用就是使 :结果展示,业务操作,以及后台的数据库操作,

起到隔离的效果,这种分层解偶 的思想最大的好处应该就是便于扩展吧。对于现在比较流行的网站建设架构

structs+hibernate+spring来说,就是用struct的标签来做结果的展示,用它的action来处理业务逻辑,而用

hibernate来处理业务逻辑所要操作的后台数据库数据。而他们各自的扩展变化和具体操作实现的变化 基本上

都不合影响到其他层的改动。个人感觉   数据库的设计定了,那么更具业务需求的hibernate接口成基本上就是

定下来了,因为数据库的操作无非不是根据 不同的条件实现  增,删,改,查!说穿也就是说hibernate所做的

只是对于你所设计的表 做 增,删,改,查 操作,而这些操作基本上是固定模式。对于spring的用处主要就是

用它的课配置事务处理的能力。

posted @ 2007-05-28 15:29 change| 编辑 收藏

最近用structs+hibernate+spring做的一个项目,后台用的是oracle92。

测试的时候发现了一个数据的插入问题,在数据库里面定义的一个varchar(4000)的字段,在action层打印显示的字段大小明明就是<4000字节的  可是一执行用hibernate插入操作的时候,就报错,而且显示的字段大小只要一超过2000就报错说超出范围,而且汉字还是3字节编码的,而所有的页面都用gbk编码郭了,一直百思不得其解,原来是oracle驱动得问题。oracle92自己带的驱动只是适合jdk1.3以前的,在oracle的官方网站上下载一个最新驱动,一切ok!晕吧!呵呵,希望大家  不要范和我一样的毛病。为此二郁闷。

posted @ 2007-05-28 15:28 change 阅读(120) | 评论 (0)编辑 收藏

比如在删除一条在数据库操作的时候 我们一般是类似是这样使用:

this.getHibernateTemplate().delete("from Information where INFOID='"+infoid.trim()+"'");

然而具体在spring内部是怎么操作的呢?

delete()----->excecute()----->执行回调方法HibernateCallback .doInHibernate()。

下面来让我们来直接看一下spring的源代码。

//hibernate回调接口

public interface HibernateCallback {

Object doInHibernate(Session session) throws HibernateException, SQLException;

}

//

package org.springframework.orm.hibernate;

public class HibernateTemplate extends HibernateAccessor implements HibernateOperations {

//。。。。。。。。。。。。。。。。

public int delete(final String queryString) throws DataAccessException {
  Integer deleteCount = (Integer) execute(new HibernateCallback() {//定义回调实现
   public Object doInHibernate(Session session) throws HibernateException {
    checkWriteOperationAllowed(session);
    return new Integer(session.delete(queryString));//此处有hibernate的实现操作
   }
  });
  return deleteCount.intValue();
 }

 public Object execute(HibernateCallback action) throws DataAccessException {
  Session session = (!isAllowCreate() ? SessionFactoryUtils.getSession(getSessionFactory(), false) :
  SessionFactoryUtils.getSession(getSessionFactory(), getEntityInterceptor(), getJdbcExceptionTranslator()));
  boolean existingTransaction = TransactionSynchronizationManager.hasResource(getSessionFactory());
  if (!existingTransaction && getFlushMode() == FLUSH_NEVER) {
   session.setFlushMode(FlushMode.NEVER);
  }
  try {
   Object result = action.doInHibernate(session);//此处调用hibernatecallback回调接口即hibernate的实现
   flushIfNecessary(session, existingTransaction);
   return result;
  }
  catch (HibernateException ex) {
   throw convertHibernateAccessException(ex);
  }
  catch (SQLException ex) {
   throw convertJdbcAccessException(ex);
  }
  catch (RuntimeException ex) {
   // callback code threw application exception
   throw ex;
  }
  finally {
   SessionFactoryUtils.closeSessionIfNecessary(session, getSessionFactory());
  }
 }

//。。。。。。。。。。。。。。

//其他操作类似

}


posted @ 2007-05-28 15:27 change| 编辑 收藏

仅列出标题
共3页: 上一页 1 2 3