MDA/MDD/TDD/DDD/DDDDDDD
posts - 536, comments - 111, trackbacks - 0, articles - 0
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

tomcat5中,为了保证get数据采用UTF8编码,在server.xml中进行了如下设置:

<Connector port="8080" maxThreads="150" minSpareThreads="25"
maxSpareThreads="75" enableLookups="false" redirectPort="8443"
acceptCount="100" debug="99" connectionTimeout="20000"
disableUploadTimeout="true" URIEncoding="UTF-8"/>

这里指定了get时候的数据编码。但是,当使用IIS作为webserver转发servlet/jsp请求给Tomcat时候,这个设置却失效了。其实原因很简单:IIS是通过AJP协议,把请求转发到Tomcat监听的8009端口上的,所以这里针对8080的设置自然就无效了。正确的方法是进行下面的设置:

<Connector port="8009" enableLookups="false" redirectPort="8443"
debug="0" protocol="AJP/1.3" URIEncoding="UTF-8"/>

posted @ 2007-10-17 21:47 leekiang 阅读(36621) | 评论 (3)编辑 收藏

    进入管理工具 >本地安全策略,把 IP 安全策略 策略已指派 设置为否

posted @ 2007-10-12 00:42 leekiang 阅读(564) | 评论 (0)编辑 收藏

1,ActionForm中setter和getter的类型必须对应。
   struts把post的所有参数放到一个map里,再通过beanutil的populate方法填充到ActionForm,在populate时有一些隐含逻辑,出现一些意想不到的行为,而且不同的BeanUtils版本可能还不一样。如果ActionForm的某个setter方法的参数是Long类型,而post的对应的参数的值为空,则会自动设置为0.另外ActionForm中setter和getter的类型必须对应,这个没搞明白,有空看populate()方法的源码。
2, 在ActionForm中many to one的one方可这样设置
   public String getParentid() {
        return son.getParent().getParentid().toString();
    }
   
    public void setParentid(String parentid) {
        if (parentid!= null && !"".equals(parentid)) {
            son.setParent(new Parent(new Long(parentid)));
        }
    }
3,contextRelative
如果该值被设置为 true,那么路径就被认为是相对于整个 Web 应用的相对路径。
如果该值被设置为 false,那么路径就被认为是相对于一个模块化应用程序的这个模块的相对路径。默认为false。

4,<bean:write>输入网页时必须加filter=false

5,struts1.x可以利用spring提供的RequestUtil.populate(bean)方法自动的将请求参数封装进一个POJO
见http://yuanke.javaeye.com/blog/433370

posted @ 2007-10-09 11:38 leekiang 阅读(325) | 评论 (0)编辑 收藏

1,从Hibernate 3.0.x/3.1.x升级到最新的3.2版,一定要注意,3.2版的很多sql函数如count(), sum()的唯一返回值已经从Integer变为Long,如果不升级代码,会得到一个ClassCastException。

这个变化主要是为了兼容JPA,可以在hibernate.org的最新文档中找到说明。

Hibernate Team也提供了一个与原来兼容的解决方案:

  Configuration classicCfg = new Configuration();
  classicCfg.addSqlFunction( "count", new ClassicCountFunction());
  classicCfg.addSqlFunction( "avg", new ClassicAvgFunction());
  classicCfg.addSqlFunction( "sum", new ClassicSumFunction());
  SessionFactory classicSf = classicCfg.buildSessionFactory();

int count = ((Integer)q.uniqueResult()).intValue();

改成 int count = ((Number)q.uniqueResult()).intValue(); 这样就可以两个版本同时兼容.

2,hibernate3.2要求ehcache1.2

3,session.createSQLQuery(sql).executeUpdate();这个hibernate3.0.5不支持,而hibernate3.2支持

  session.createSQLQuery(fsql).addScalar("singlevalue",
                        Hibernate.DOUBLE).uniqueResult();这个到了3.2就不需要addScalar了.

4,session.createSQLQuery(sql).addEntity(Class class);hibernate3.0.5不支持,单个参数的addEntity方法

5,hibernate3.2可以对原生sql 查询使用ResultTransformer。这会返回不受Hibernate管理的实体。
sess.createSQLQuery("SELECT NAME, BIRTHDATE FROM CATS")
        .setResultTransformer(Transformers.aliasToBean(CatDTO.class))

或setResultTransformer(new AliasToBeanResultTransformer(CatDTO.class))
上面的查询将会返回CatDTO的列表,它将被实例化并且将NAME和BIRTHDAY的值注射入对应的属性或者字段。
http://bbs.xml.org.cn/blog/more.asp?name=lhwork&id=15351

但必须注意,对每一个列都必须addScalar("列名")

6,setResultTransformer与addEntity的一个区别是前者支持查任意的列,后者必须用select * from users的形式或select {a.*},{b.*} from a,b where ....。

7,Map vs. Object[]

Since you can also use a transformer that return a Map from alias to value/entity (e.g. Transformers.ALIAS_TO_MAP), you are no longer required to mess with index based Object arrays when working with a result.

List iter = s.createQuery(
"select e.student.name as studentName," +
" e.course.description as courseDescription" +
"from Enrolment as e")
.setResultTransformer( Transformers.ALIAS_TO_MAP )
.iterate();

String name = (Map)(iter.next()).get("studentName");

Again, this works equally well for Criteria, HQL and native SQL.

 

posted @ 2007-10-09 02:03 leekiang 阅读(986) | 评论 (0)编辑 收藏

1,get一个对象并打算修改这个对象时,hibernate会判断该对象的属性值是否有变动,如果没有任何变动,hibernate不会执行update语句。在同时修改页面上的多条记录时可发现这一点。

2,执行以下语句时hibernate3.0.5会报错,而3.2不会
sql="select 1+1 from dual";
session.createSQLQuery(sql).uniqueResult()
报错:addScalar() or addEntity() must be called on a sql query before executing the query.

3,<many-to-one> 的lazy设置为true时,get子对象不会把该父对象抓过来,但可以手动写代码抓取父对象
如 Son son =(Son)this.getHibernateTemplate().get(Son.class, id);
       然后执行 son.getParent().getName();
   这样不仅仅会抓取到name,其他所有的属性如age,sex等都会取到,即用p.getParent().getAge()达到了同样的效果,后台都执行了select * from parent where id=?   注意用p.getParent()仅能得到parent的id.
   这时debug查看parent对象的内存快照,看到的是一个用cglib实现的代理对象,
Hibernate通过使用CGLIB,来实现动态构造一个目标对象的代理类对象,并且在代理类对象中包含目标对象的所有属性和方法,而且所有属性均被赋值为null。通过调试器显示的内存快照,我们可以看出此时真正的User对象,是包含在代理对象的CGLIB$CALBACK_0.target属性中,当调用son.getName()方法,这时通过CGLIB赋予的回调机制,实际上调用CGLIB$CALBACK_0.getName()方法,当调用该方法时,Hibernate会首先检查CGLIB$CALBACK_0.target属性是否为null,如果不为空,则调用目标对象的getName方法,如果为空,则会发起数据库查询,生成类似这样的SQL语句:select * from parent where id=’1’;来查询数据,并构造目标对象,并且将它赋值到CGLIB$CALBACK_0.target属性中。
这样,通过一个中间代理对象,Hibernate实现了实体的延迟加载,只有当用户真正发起获得实体对象属性的动作时,才真正会发起数据库查询操作。
    <many-to-one> 的lazy设置为false时,抓取父对象没有采用代理机制。

4,用session.close(),执行多次查询后报session is closed的错误,而hibernateSessionFactory.closeSession()没有这个问题,这是什么原因?

5,ORA-01466: 无法读数据 - 表定义已更改
原因是系统时间修改造成的,其他原因详见
http://www.orafaq.com/usenet/comp.databases.oracle.server/2007/03/31/1586.htm

6,
spring的一个方法上有事务,先用hibernate加载一个对象,接着改变对象的某个属性的值,
再用sql去数据库查对应的记录,然后才提交。
用sql去查时发现对应的字段也改变了,这是怎么回事?


  

posted @ 2007-09-28 03:51 leekiang 阅读(633) | 评论 (0)编辑 收藏

在做大批量处理时,容易出现outofmemory的情况,分析及解决如下
(1)原因
 当首次作Insertupdatedeleteselect时,新产生的object在session关闭之前将自动装载到session级别的缓存区,如果,AP使用了二级缓存,同样也会装入到二级缓存。所以当数据量大时,就会出现outofmemory情况。
 
(2)解决方法
 
(A)批量插入(Batch inserts)/批量更新(Batch updates)
必须通过经常的调用 flush() 以及稍后调用 clear() 来控制第一级缓存的大小
如:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
  
for ( int i=0; i<100000; i++ ) {
    Customer customer = new Customer(.....);
    session.save(customer);
    if ( i % 20 == 0 ) {
//20, same as the JDBC batch size //20,与JDBC批量设置相同
        //flush a batch of inserts and release memory:
        //将本批插入的对象立即写入数据库并释放内存
        session.flush();
        session.clear();
    }
}
  
tx.commit();
session.close();
 
(B)大批量更新/删除(Bulk update/delete)
使用HQL语言
 
Session session = sessionFactory.openSession();
        Transaction tx = session.beginTransaction();

        String hqlUpdate = "update Customer set name = :newName where name = :oldName";
        int updatedEntities = s.createQuery( hqlUpdate )
                            .setString( "newName", newName )
                            .setString( "oldName", oldName )
                            .executeUpdate();
        tx.commit();
        session.close();

执行一个HQL DELETE,同样使用 Query.executeUpdate() 方法 (此方法是为 那些熟悉JDBC PreparedStatement.executeUpdate() 的人们而设定的)
Session session = sessionFactory.openSession();
        Transaction tx = session.beginTransaction();

        String hqlDelete = "delete Customer where name = :oldName";
        int deletedEntities = s.createQuery( hqlDelete )
                            .setString( "oldName", oldName )
                            .executeUpdate();
        tx.commit();
        session.close();

posted @ 2007-09-27 14:22 leekiang 阅读(1459) | 评论 (0)编辑 收藏

用一个div将table 套住,把层的宽和高都设为定长,
<div style="overflow-y:scroll;width:100%;height:100%">
 <table>   
 </table>
</div>
overflow-y不要设置为visible

posted @ 2007-09-24 16:57 leekiang 阅读(7871) | 评论 (1)编辑 收藏

 1public String double2String(double d, int fNumber) {
 2        if (fNumber < 0)
 3            fNumber = 0;
 4
 5        String pattern = null;
 6        switch (fNumber) {
 7        case 0:
 8            pattern = "#0"//$NON-NLS-1$
 9            break;
10        default:
11            pattern = "#0."//$NON-NLS-1$
12            StringBuffer b = new StringBuffer(pattern);
13            for (int i = 0; i < fNumber; i++{
14                b.append('#');
15            }

16            pattern = b.toString();
17            break;
18
19        }

20        DecimalFormat formatter = new DecimalFormat();
21        formatter.applyPattern(pattern);
22        String value = formatter.format(d);
23        return value;
24    }
double直接输出时,如果小数点后位数太长会出现字母e,采用本方法转换为string再输出

posted @ 2007-09-16 23:25 leekiang 阅读(6193) | 评论 (1)编辑 收藏

1,logic:empty与logic:present的区别
相同点:对于没有在page,request,session,application中定义或者是没有分配内存空间(null值)的变量,这两个标记处理的方法是一致的.
区别:空字符串""值,他们的处理就不一样了,logic:present 标记认为空字符串仍然是存在的,也就是说,只要是引用了一块内存空间的变量,logic:present 就会返回present ;而logic:empty则认为空字符串仍然为空,由此得出,在logic:empty看来,变量不仅仅要引用一块内存空间,而且该地址空间的值不能为空字符串,否则都认为该变量为空,都会返回empty

2,logic iterate输出map
 
iterate标签处理map时好像只能做到以遍历的方式输出key和value,而不能指定输出某个key
  以下来源:http://www.blogjava.net/msmary/articles/153560.html
      标签本身不直接支持迭代输出输出步骤:
Map-->Set-->Iterator-->Map.Entry-->key
value

        Map m = new HashMap();

        m.put("name","yourname");

        m.put("pass","yourpass");

        request.setAttribute("map",m);

<logic:iterate id="str" name="map" scope="request">

      <h2><bean:write name="str" property="key"/></h2>

      <h2><bean:write name="str" property="value"/></h2>

    </logic:iterate>

   <%

        /**

          Map中保存多个Collection集合,该如何进行了输出?

        */

        List all = null;

        Map m = new HashMap();

       

        all = new ArrayList();

        all.add("msdn");

        all.add("url");

        m.put("name",all);

       

        all = new ArrayList();

        all.add("mole");

        all.add("msistri");

        m.put("info",all);

        //在一个Map中保存了多个集合,每个集合又包含了多个内容

        request.setAttribute("list",m);

    %>

    <logic:iterate id="src" name="list" scope="request" >

      <h2><bean:write name="src" property="key"/></h2>

        <logic:iterate id="ins" name="src" scope="page" property="value">

           <bean:write name="ins"/>

        </logic:iterate>

    </logic:iterate>

http://www.blogjava.net/ftqiuqiu/articles/205631.html
http://zengbo0710.javaeye.com/blog/79405
http://blog.csdn.net/daryl715/archive/2007/03/12/1527098.aspx

posted @ 2007-09-14 15:03 leekiang 阅读(993) | 评论 (0)编辑 收藏

不考虑极端的情况,通常组织机构有个10几个层次就是顶天了。 所有,可以用一个字段存储下所有祖先的信息,例如varchar2(300),其中可以用 '.'隔开。 我的设想是这样的:
id name Nodecode
1 a 1
2 b 1.2
3 c 1.3
4 d 1.2.4
5 e 1.2.5
6 f 1.2.5.6

从6可以直接看到它的上级脉络是6.5.2.1 。当然这里考虑的是级别不多的。但是除非你是很极端的应用,我想还是可以满足的。在插入和更新的时候注意维护nodecode即可。
如果要照到祖先,则只要解析一下nodecode即可。
同理如果要照后代,例如2的后代,则马上可以通过Like的方式获得.

另一篇:
因为TreeKey是个字符串,而1.10会排到1.2, 1.3之前,很显然,这不是我们要的结果。要解决其实也很简单,在编号前面补0,比如,1.10就写成0001.0010,1.2就写成0001.0002,这样排序就不会有问题了。

这让我想起很早前看的微软的一个有关树的软件代码,就看到他们是以000x.000x这种方式进行处理的,当时我还感觉他们怎么这么麻烦,现在想来,才发现是自己无知了,呵呵。


posted @ 2007-09-12 13:37 leekiang 阅读(225) | 评论 (0)编辑 收藏

仅列出标题
共54页: First 上一页 45 46 47 48 49 50 51 52 53 下一页 Last