月挂夜中央

懒惰程序员

常用链接

统计

最新评论

2008年2月19日 #

网易微博的OAUTH认证开发(java版)

     摘要:     网易微博最近也开放了它的开发平台http://open.t.163.com,其中java版的oauth认证和新浪微博的很类似(貌似都是从twitter那边copy过来的)。但说句实话,网易java版的sdk和新浪微博的比起来,的确上手比较麻烦,里面提供的example都是把access token写死,作为参数,具体的代码如下: public&nb...  阅读全文

posted @ 2011-02-16 21:31 月挂夜中央 阅读(6291) | 评论 (6)编辑 收藏

springside3.*中log4j和java.util.concurrent的结合使用

     摘要:         在springside3.*中的showcase案例中,有一个把log4j的日志存入数据库的演示,下面是我对这个案例的学习笔记。 1、我们首先来看下log4j相关日志的配置: #Async Database Appender (Store business&n...  阅读全文

posted @ 2011-02-13 21:20 月挂夜中央 阅读(2204) | 评论 (0)编辑 收藏

使用XmemcachedClient设置缓存对象过期时间的问题

前几天在做一个涉及到memcache的项目,使用XmemcachedClient来操作memcache,由于是一个季度的数据,保存数据时这样的
 memcachedClient.set(key, expiredTime, value)
其中设置了过期时间为90天
int cacheExpireTime = 60*60*24*90;
结果就杯具了,保存后用get方法取时都是null;后来无意中把过期时间改成小于30天,就完全没有问题,经过谷歌大神的帮忙,终于发现了原因。
服务端的处理
时间处理源代码【memcached.c】如下:
#define REALTIME_MAXDELTA 
60*60*24*30                     // 定义30天的秒数
static rel_time_t realtime(const time_t exptime) {
       
if (exptime == 0return 0;
       
if (exptime > REALTIME_MAXDELTA) {                       // 超过30天,是绝对时间
              if (exptime <= process_started)                         // 小于进程启动日期
                      return (rel_time_t)1;                                  //
              return (rel_time_t)(exptime - process_started);   // 返回进程启动之后的时间差
       }
 else {                                                                   // 不超过30天,是相对时间
              return (rel_time_t)(exptime + current_time);       // exptime + (tvsec - process_started)
       }

}
原来超过30天就自动转换成绝对时间,和进程启动时间比较,显然60*60*24*90小于启动日期的绝对数,所以对象一存入就过期了,肯定取不到数据。
具体的问题请围观这篇文章:http://blog.sina.com.cn/s/blog_539d361e0100nc9h.html

posted @ 2011-01-21 16:18 月挂夜中央 阅读(4903) | 评论 (0)编辑 收藏

xfire的webservice方法中date类型参数为null出现空指针错误的问题

最近在使用xfire开发webservice,发现一个这样的问题,如果注册的webservice 方法中的参数有Date类型时,调用该方法时把Date型参数填入null,就会报空指针错误,这是xfire的一个bug,很可惜在xfire官方网站上最新版的xfire版本是1.2.6,在这个版本中问题仍然没有解决,而解决的方法在codeHaus的jira中其实发现了这个问题,这个问题主要出在org.codehaus.xfire.aegis.type.basic.DateTimeType的writeObject方法,在1.2.6中这个方法的代码是这样的:

public void writeObject(Object object, MessageWriter writer, MessageContext context)
    
{
        Calendar c 
= Calendar.getInstance();
        c.setTime((Date) object);
        writer.writeValue(format.format(c));
    }
修改过后的代码如下:
public void writeObject(Object object, MessageWriter writer,
            MessageContext context) 
{
        
if (object != null{
            Calendar c 
= Calendar.getInstance();
            c.setTime((Date) object);
            writer.writeValue(format.format(c));
        }
 else {
            writer.writeXsiNil();
        }

    }
加了个对null的判断就好了。很不幸的是xfire现在变成了cxf,指望官方在新的xfire版本中改正这个bug是没戏了,大家还是自己改改用吧。

posted @ 2010-02-24 09:12 月挂夜中央 阅读(3736) | 评论 (2)编辑 收藏

oracle中in,not in和exists,not exists之间的区别

         一直听到的都是说尽量用exists不要用in,因为exists只判断存在而in需要对比值,所以exists比较快,但看了看网上的一些东西才发现根本不是这么回事。
下面这段是抄的
Select * from T1 where x in ( select y from T2 )
执行的过程相当于:
select *
  from t1, ( select distinct y from t2 ) t2
 where t1.x = t2.y;

select * from t1 where exists ( select null from t2 where y = x )
执行的过程相当于:
for x in ( select * from t1 )
   loop
      if ( exists ( select null from t2 where y = x.x )
      then
         OUTPUT THE RECORD
      end if
end loop

从我的角度来说,in的方式比较直观,exists则有些绕,而且in可以用于各种子查询,而exists好像只用于关联子查询(其他子查询当然也可以用,可惜没意义)。
由于exists是用loop的方式,所以,循环的次数对于exists影响最大,所以,外表要记录数少,内表就无所谓了,而in用的是hash join,所以内表如果小,整个查询的范围都会很小,如果内表很大,外表如果也很大就很慢了,这时候exists才真正的会快过in的方式。
         下面这段还是抄的
not in 和not exists
如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;
而not extsts 的子查询依然能用到表上的索引。
所以无论那个表大,用not exists都比not in要快。
          也就是说,in和exists需要具体情况具体分析,not in和not exists就不用分析了,尽量用not exists就好了。

posted @ 2009-01-07 15:03 月挂夜中央 阅读(6255) | 评论 (2)编辑 收藏

如何查看sql的执行计划

在pl/sql developer中,直接写条sql,按F5,就可以调出执行计划,但在只有sql plus的情况下,只能用下面这个语句了,
explain plan for select ....
然后再来一句
select * from table(dbms_xplan.display());
就会出现一个类似下面的信息
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------

----------------------------------------------------------------------------
| Id  | Operation                    |  Name       | Rows  | Bytes | Cost  |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |             |       |       |       |
|   1 |  NESTED LOOPS                |             |       |       |       |
|   2 |   TABLE ACCESS FULL          | AC01        |       |       |       |
|   3 |   TABLE ACCESS BY INDEX ROWID| AB01        |       |       |       |
|   4 |    INDEX UNIQUE SCAN         | PK_AB01     |       |       |       |
----------------------------------------------------------------------------


PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Note: rule based optimization, PLAN_TABLE' is old version

就能看到执行计划了。

posted @ 2009-01-07 12:00 月挂夜中央 阅读(1281) | 评论 (0)编辑 收藏

根据条件动态定义游标

在oracle的函数或过程中,有时候需要根据传进来的参数或者别的什么原因动态定义游标,那么该怎么定义呢,方法如下:
首先,定义游标变量:
type   cur   is   ref   cursor
cv_name cur;
然后,动态定义游标:
If length(v_1)>0 Then 
      
Open cv_name For 'select column1 from table1 where column1 = '||v_1;      
    
Else 
      
Open cv_name For 'select column1 from table1';      
    
End If;
后面的就按游标的正常使用就好了。

posted @ 2008-07-08 14:46 月挂夜中央 阅读(477) | 评论 (0)编辑 收藏

关于oracle中的列使用别名后在sql中的操作

    在oracle中如果列在sql中操作,是很正常的事,比如:
    select col1,col2,col1+col2 from table1;
    但如果使用了别名,情况就不同了:
    select col1 a,col2 b,a+b from table1;
    会报以下的错误:
    ORA-00904: "B": invalid identifier
    怎么解决呢,就是套一个select在外面:
    select a,b,a+b from (select col1 a,col2 b from table1);
    这样就没有问题了。

posted @ 2008-03-20 10:47 月挂夜中央 阅读(1567) | 评论 (1)编辑 收藏

关于oracle的dbms_output的两个小问题

1、如果dbms_output.put_line的内容不能显示,需要在命令行中先敲入set serveroutput on;只要敲一遍就好,之后dbms_output.put_line的内容就能显示出来了;
2、dbms_output.put_line每行只能显示255个字符,超过了就会报错,报错内容如下
      ORA-20000: ORU-10028: line length overflow, limit of 255 chars per line
解决这个问题的方法如下:

declare 
  v_result 
Varchar2(1000);--这是需要打印出结果的字符串
  v_pos Number := 1;--用来记录v_result每行开始字符的位置

WHILE v_pos<= LENGTH(v_result) LOOP
          DBMS_OUTPUT.PUT_LINE(SUBSTR(v_result, v_pos, 
200));
          v_pos:
= v_pos+ 200;
      
END LOOP;
这样就能打印超过255长度的字符串,超过200长度的自动换行打印出来

posted @ 2008-02-19 11:37 月挂夜中央 阅读(41596) | 评论 (1)编辑 收藏