随笔-59  评论-13  文章-2  trackbacks-0
  2015年8月2日
from
http://blog.163.com/zhouhuoxiang12@126/blog/static/88776461200945112658420/

EntityManager 是用来对实体Bean 进行操作的辅助类。他可以用来产生/删除持久化的实体Bean,通过主键查找实体bean,也可以通过EJB3 QL 语言查找满足条件的实体Bean。实体Bean 被EntityManager 管理时,EntityManager跟踪他的状态改变,在任何决定更新实体Bean 的时候便会把发生改变的值同步到数据库中。当实体Bean 从EntityManager 分离后,他是不受管理的,EntityManager 无法跟踪他的任何状态改变。EntityManager 的获取前面已经介绍过,可以通过@PersistenceContext 注释由EJB 容器动态注入,例:

@PersistenceContext(unitName="foshanshop")

EntityManager em;

EntityManager常用方法:

1.Entity的获取

   find(*.class,ID) :若实体Bean不存在,则返回null

   getReference(*,class,ID) :若实体Bean不存在,则抛出javax.persistence.EntityNotFoundException,另,不保 证                                            实体Bean 已被初始化

   注意:若*.class不是Entity Bean的话,都会引发IllegalArgumentException

2.persist() :添加实体Bean

3.更新实体Bean :当实体正在被容器管理时,你可以调用实体的set 方法对数据进行修改,在容器决定flush 时,更新的数据才会同步到数据库。如果你希望修改后的数据实时同步到数据库,你可以执行EntityManager.flush()方法。

4.merge () :是在实体Bean 已经脱离了EntityManager 的管理时使用,当容器决定flush 时,数据将会同步到数据库中,执行em.merge(Object obj)方法时,容器的工作规则:

(1).如果此时容器中已经存在一个受容器管理的具有相同ID 的Object实例,容器将会把参数obj的内容拷贝进这个受管理的实例,merge()方法返回受管理的实例,但参数obj仍然是分离的不受管理的。容器在决定Flush时把实例同步到数据库中。

(2).容器中不存在具有相同ID 的Object实例。容器根据传进的obj参数Copy 出一个受容器管理的Object实例,同时merge()方法会返回出这个受管理的实例,但参数obj仍然是分离的不受管理的。容器在决定Flush时把 实例同步到数据库中。如果传递进merge ()方法的参数不是实体Bean,会引发一个IllegalArgumentException

5.Remove() :删除对象

6.createQuery() 返回Query对象,以执行JPQL语句

7.createNativeQuery() 返回Query对象,以执行SQL语句

8.refresh() 刷新实体Bean,以得到对新对象 (幽雅的获取最新对象方法)

9.contains() 检测实体当前是否被管理中

   该方法使用一个实体作为参数,如果这个实体对象当前正被持久化内容管理,返回值为true,否则为false

10.clear() 分离所有当前正在被管理的实体

     在处理大量实体的时候,如果你不把已经处理过的实体从EntityManager 中分离出来,将会消耗你大量的内存。调用EntityManager 的clear()方法后,所有正在被管理的实体将会从持久化内容中分离出来。

有一点需要说明下,在事务没有提交前(事务默认在调用堆栈的最后提交,如:方法的返回),如果调用clear()方法,之前对实体所作的任何改变将会掉失,所以建议你在调用clear()方法之前先调用flush()方法保存更改

11. flush() 将实体的改变立刻刷新到数据库中

当实体管理器对象在一个session bean 中使用时,它是和服务器的事务上下文绑定的。实体管理器在服务器的事务提交时提交并且同步它的内容。在一个session bean 中,服务器的事务默认地会在调用堆栈的最后提交(如:方法的返回)

12.javax.persistence.FlushModeType 实体Bean管理器的Flush模式

     FlushModeType.COMMIT   :刷新只有在事务提交时才发生,使用场合:在大量更新数据的过程中存在查询语句(除了find()和getreference()查询)的执行

     FlushModeType.AUTO :(默认模式)刷新在查询语句执行前(除了find()和getreference()查询)或事务提交时才发   生,使用场合:在大量更新数据的过程中没有任何查询语句(除了find()和getreference()查询)的执行。

JDBC 驱动跟数据库交互的次数。JDBC 性能最大的增进是减少JDBC 驱动与数据库之间的网络通讯FlushModeType.COMMIT 模式使更新只在一次的网络交互中完成,而FlushModeType.AUTO 模式可能需要多次交互(触发了多少次Flush 就产生了多少次网络交互)

设置:entityManager.setFlushMode(FlushModeType.COMMIT);

13.getDelegate( )   获取持久化实现者的引用

     用过getDelegate( )方法,你可以获取EntityManager 持久化实现者的引用,如Jboss EJB3 的持久化产品采用Hibernate,可以通过getDelegate( ) 方法获取对他的访问,如:

@PersistenceContext

protected EntityManager em;

HibernateEntityManager manager = (HibernateEntityManager)em.getDelegate();

获得对Hibernate 的引用后,可以直接面对Hibernate 进行编码,不过这种方法并不可取,强烈建议不要使用.在Weblogic 中,你也可以通过此方法获取对Kodo 的访问

另:映射的表名或列名与数据库保留字同名时的处理

     将表名加标式符,例如:在Mysql下,用'order',或在sqlserver下用[TableName],但这样做不适合程序移植

posted @ 2015-08-02 08:31 桂湖山 阅读(41) | 评论 (0)编辑 收藏
  2013年11月29日
 1. include  ocilib.h throught ocilib_demo.h
 2. auto #pragma comment(lib, "ociliba.lib")  in ocilib_demo.h
 3. add in codes
 4. add link path of ociliba.lib
 5. copy ociliba.dll to the fitable path
 the code maybe as:
  OCI_StatementCreate
   ...
 
posted @ 2013-11-29 15:57 桂湖山 阅读(91) | 评论 (0)编辑 收藏
  2011年9月7日

注明转自Delphi深度探索

 

介绍

随着网络免费的大潮的 退去,网站变得越来越商业化。浏览一些常去的网站,每看一个页面都会弹出N多的广告窗口,而且都是花花绿绿的Flash和Gif小动画,浪费带宽(我在家 还是拨号上网),同时干扰了正常的阅读,非常讨厌。那么如何才能将这些广告屏蔽掉呢?答案就是Browser Helper Object(简称BHO)。

BHO实际上也是一个简单的IE扩展COM组件,它和其它COM组件的区别就在于其它扩展需要一些用户的手工操作,如点击菜单,点击工具条按钮,在地址栏输入 网址等等触发动作才会被IE加载。而BHO则不同,每当IE启动时,都会自动去加载BHO而无须任何触发条件,另外BHO还可以监听IE的各类事件的通知消息,比如窗 口大小的变化,下载是否完成等事件。

由于BHO可以在一启动IE就被加载,并能监听各种事件,我们就可以使用BHO扩展实现限制用户浏览某些色情网站,或者搜集用户浏览喜好信息等功能。接下来, 我们就来实现一个能够阻断广告弹出的BHO扩展。

创建COM组件

       新建一个ActiveX Library,保存为IEBHO.dpr,然后新建一个名为TIEAdvBHO的COM Object,然后保存生成的文件为CIEBHO.pas,作为BHO扩展,需要实现两 个接口IObjectWithSite和IDispatch,其中 IObjectWithSite接口同前面的工具条扩展一样可以用来获得浏览器的接口,而IDispatch接口,则被用来监听浏览器的事件。下面就是BHO扩展的类定义:

type
  TTIEAdvBHO = class(TComObject, IObjectWithSite, IDispatch)
  private
    FIESite: IUnknown;
    FIE: IWebBrowser2;
    FCPC: IConnectionPointContainer;
    FCP: IConnectionPoint;
    FCookie: Integer;
  protected
    //IObjectWithSite接口方法定义
    function SetSite(const pUnkSite: IUnknown): HResult; stdcall;
    function GetSite(const riid: TIID; out site: IUnknown): HResult; stdcall;
    //IDispatch接口方法定义
    function GetTypeInfoCount(out Count: Integer): HResult; stdcall;
    function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult;
      stdcall;
    function GetIDsOfNames(const IID: TGUID; Names: Pointer;
      NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; stdcall;
    function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
      Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult;
      stdcall;
    //阻断广告弹出事件处理过程
procedure DoNewWindow2(var ppDisp: IDispatch; var Cancel: WordBool);
    procedure DoBeforeNavigate2(const pDisp: IDispatch; var URL: OleVariant; var Flags: OleVariant; var TargetFrameName: OleVariant; 
var PostData: OleVariant;var Headers: OleVariant; var Cancel: WordBool);
end;

 

IObjectWithSite的接口的实现

 

先 看IObjectWithSite的接口的实现,当IE加载BHO扩展后,会调用BHO的扩展,把自身的IUnknown接口作为参数pUnkSite传 给扩展,BHO扩展应该从pUnkSite参数中获得浏览器接口IWebBrowser2,同时为了监听浏览器的事件,还需要获得事件链接点接口,IE的 支持的事件都定义在DWebBrowserEvents2的双接口中,使用链接点的Advise方法建立对IE事件的监听,注意Advise方法调用后 会返回一个Cookie,需要保存Cookie,后面在退出IE时,需要Cookie作为参数来断开对IE事件的监听。

function TTIEAdvBHO.SetSite(const pUnkSite: IInterface): HResult;
begin
  Result := E_FAIL;
  //保存接口
  FIESite := pUnkSite;
  if not Supports(FIESite, IWebBrowser2, FIE) then
Exit;
  //获得事件连接点
  if not Supports(FIE, IConnectionPointContainer, FCPC) then
    Exit;
  FCPC.FindConnectionPoint(DWebBrowserEvents2, FCP);
  //监听事件
  FCP.Advise(Self, FCookie);
  Result := S_OK;
end;

后面IE有时会调用IObjectWithSite接口的GetSite方法获得需要的接口,这时可以将保存的接口返回。

function TTIEAdvBHO.GetSite(const riid: TIID;
  out site: IInterface): HResult;
begin
  if Supports(FIESite, riid,site) then
    Result := S_OK
  else
    Result:= E_NOINTERFACE;
end;

 

IDispatch接口的实现

 

前 面我们在SetSite中建立了对IE事件的监听,建立事件监听后每当IE产生了新的事件,它就会调用扩展的IDispatch接口的Invoke方法通 知扩展发生的事件类型以及事件参数,并请求扩展对事件进行处理。因此对于BHO扩展来说,IDispatch接口的Invoke方法是必须实现的,而其它 的GetTypeInfoCount,GetTypeInfo和GetIDsOfNames方法都无须实现,只要返回结果为E_NOTIMPL,表示未实 现该方法就可以了。

 

function TTIEAdvBHO.GetIDsOfNames(const IID: TGUID; Names: Pointer;
  NameCount, LocaleID: Integer; DispIDs: Pointer): HResult;
begin
  Result := E_NOTIMPL;
end;
 
function TTIEAdvBHO.GetTypeInfo(Index, LocaleID: Integer;
  out TypeInfo): HResult;
begin
  Result := E_NOTIMPL;
  pointer(TypeInfo) := nil;
end;
 
function TTIEAdvBHO.GetTypeInfoCount(out Count: Integer): HResult;
begin
  Result := E_NOTIMPL;
  Count := 0;
end;

 

事件的监听

 

IE支持的事件都定义在DWebEvents2接口中,如下:

  DWebBrowserEvents2 = dispinterface
    ['{34A715A0-6587-11D0-924A-0020AFC7AC4D}']
    procedure StatusTextChange(const Text: WideString); dispid 102;
    procedure ProgressChange(Progress: Integer; ProgressMax: Integer); dispid 108;
    procedure CommandStateChange(Command: Integer; Enable: WordBool); dispid 105;
    procedure DownloadBegin; dispid 106;
    procedure DownloadComplete; dispid 104;
    procedure TitleChange(const Text: WideString); dispid 113;
    procedure PropertyChange(const szProperty: WideString); dispid 112;
procedure BeforeNavigate2(const pDisp: IDispatch; var URL: OleVariant; var Flags:
 OleVariant; var TargetFrameName: OleVariant; var PostData: OleVariant;                               
var Headers: OleVariant; var Cancel: WordBool); dispid 250;
    procedure NewWindow2(var ppDisp: IDispatch; var Cancel: WordBool); dispid 251;
    procedure NavigateComplete2(const pDisp: IDispatch; var URL: OleVariant); dispid 252;
    procedure DocumentComplete(const pDisp: IDispatch; var URL: OleVariant); dispid 259;
    procedure OnQuit; dispid 253;
    procedure OnVisible(Visible: WordBool); dispid 254;
    procedure OnToolBar(ToolBar: WordBool); dispid 255;
    procedure OnMenuBar(MenuBar: WordBool); dispid 256;
    procedure OnStatusBar(StatusBar: WordBool); dispid 257;
    procedure OnFullScreen(FullScreen: WordBool); dispid 258;
    procedure OnTheaterMode(TheaterMode: WordBool); dispid 260;
  end;

 

可以看到每个事件中的后面都有一个dispid关键加上数字如 258 ,260等等。Dispid的数字就是事件类型的标识符号。
IDispatch的Invoke方法定义如下:
    function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;

Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult;

IE调用Invoke方法时,会设定DispId参数为事件的标识符号,这样我们就可以知道IE发生了什么事件。对于要实现 的阻断广告窗口弹出来说,我们只需关心BeforeNavigate2OnQuit事件就可以了,因为当广告窗口弹出前,会激发 IEBeforeNavigate2事件,而弹出式窗口一般没有工具条,所以只要BeforeNavigate2事件中判断当前页面是否有 工具条就可以判断是否是弹出窗口,并予以禁止。而当IE退出时,会激发OnQuit事件,在OnQuit事件中应该断开事件 监听,同时清理分配的资源。下面就是截获BeforeNavigate2OnQuit事件的Invoke方法的实现:

procedure BuildPositionalDispIds(pDispIds: PDispIdList; const dps: TDispParams);
var
  i: integer;
begin
  Assert(pDispIds <> nil);
  for i := 0 to dps.cArgs - 1 do
    pDispIds^[i] := dps.cArgs - 1 - i;
  if (dps.cNamedArgs <= 0) then
    Exit;
  for i := 0 to dps.cNamedArgs - 1 do
    pDispIds^[dps.rgdispidNamedArgs^[i]] := i;
end;

 

function TTIEAdvBHO.Invoke(DispID: Integer; const IID: TGUID;
  LocaleID: Integer; Flags: Word; var Params; VarResult, ExcepInfo,
  ArgErr: Pointer): HResult;
var
  dps: TDispParams absolute Params;
  bHasParams: boolean;
  pDispIds: PDispIdList;
  iDispIdsSize: integer;
begin
  pDispIds := nil;
  iDispIdsSize := 0;
  bHasParams := (dps.cArgs > 0);
  if (bHasParams) then
  begin
    iDispIdsSize := dps.cArgs * SizeOf(TDispId);
    GetMem(pDispIds, iDispIdsSize);
  end;
  try
    if (bHasParams) then
      BuildPositionalDispIds(pDispIds, dps);
    Result := S_OK;
    case DispId of
      250://BeforeNaviage2事件id
        begin
          DoBeforeNavigate2(IDispatch(dps.rgvarg^[pDispIds^[0]].dispval),
              POleVariant(dps.rgvarg^[pDispIds^[1]].pvarval)^,
              POleVariant(dps.rgvarg^[pDispIds^[2]].pvarval)^,
              POleVariant(dps.rgvarg^[pDispIds^[3]].pvarval)^,
              POleVariant(dps.rgvarg^[pDispIds^[4]].pvarval)^,
              POleVariant(dps.rgvarg^[pDispIds^[5]].pvarval)^,
              dps.rgvarg^[pDispIds^[6]].pbool^);
        end;
      253://OnQuit事件ID
        begin
          FCP.Unadvise(FCookie);
        end;
    else
      Result := DISP_E_MEMBERNOTFOUND;
    end;
  finally
    if (bHasParams) then
      FreeMem(pDispIds, iDispIdsSize);
  end;
end;

 

在Invoke方法中,Params参数包含了被激发的事件包含的参数的数目以及参数的值,而BuildPositionalDispIds 则从Params参数中提取参数值,并放到数组中,然后在BeforeNavigate2事件中,调用DoBeforeNavigate2过程对 事件进行处理,事件参数作为过程参数被传递过去,下面是具体禁止弹出网页的DoBeforeNavigate2的处理过程:

procedure TTIEAdvBHO.DoBeforeNavigate2(const pDisp: IDispatch; var URL,
  Flags, TargetFrameName, PostData, Headers: OleVariant;
  var Cancel: WordBool);
begin
  if FIE.ToolBar=0 then FIE.Quit;
end;

 

在过程中,首先,调用IWebBrowser2接口的Toolbar属性判断页面是否有工具条,如果没有,则调用IE的退出方法关闭弹出窗口。另外在Invoke中还在OnQuit事件激发时,调用事件连接点的UnAdvise方法,断开事件监听。

 注册扩展

 注册扩展非常简单,只要在注册表中关键字HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion
\explorer\Browser Helper Objects\
下添加值为扩展的Guid的字符串形式的下级关键字就可以了。

 type

  TIEAdvBHOFactory = class(TComObjectFactory)
  public
    procedure UpdateRegistry(Register: Boolean); override;
  end;
 
{ TIEAdvBHOFactory }
 
procedure TIEAdvBHOFactory.UpdateRegistry(Register: Boolean);
begin
  inherited;
  if Register then
    CreateRegKeyValue(HKEY_LOCAL_MACHINE, 'Software\Microsoft\Windows\CurrentVersion\explorer\Browser Helper Objects\' 
+ GuidToString(ClassID), '', '')
  else
    DeleteRegKeyValue(HKEY_LOCAL_MACHINE, 'Software\Microsoft\Windows\CurrentVersion\explorer\Browser Helper Objects\' 
+ GuidToString(ClassID), '');
end;
 
initialization
  TIEAdvBHOFactory.Create(ComServer, TTIEAdvBHO, Class_TIEAdvBHO,
    'TIEAdvBHO', '', ciMultiInstance, tmApartment);
end.

 

注册扩展后,打开浏览器浏览新浪网站(http://www.sina.com.cn),你会发现平时讨厌的弹出广告窗口都消失了。

posted @ 2011-09-07 18:09 桂湖山 阅读(120) | 评论 (0)编辑 收藏
  2011年3月13日

在非限定性定语从句中as&which有什么区别

 http://zhidao.baidu.com/question/206158139.html

posted @ 2011-03-13 14:34 桂湖山 阅读(113) | 评论 (0)编辑 收藏
  2011年1月21日
确切地讲,Desktop   Window包含一个无标题的、类名为“SHELLDLL_DefView”的子窗口,这个字窗口又包含一个无标题的、类名为“SysListView32”的子窗口——这才是那个真正包含桌面图标的窗口。
posted @ 2011-01-21 16:54 桂湖山 阅读(136) | 评论 (0)编辑 收藏
  2010年8月26日

当读者有一定c/c++基础
推荐的阅读顺序:
level 1
从<<essential c++>>开始,短小精悍,可以对c++能进一步了解其特性
以<<c++ primer>>作字典和课外读物,因为太厚不可能一口气看完

level 2
然后从<<effective c++>>开始转职,这是圣经,请遵守10诫,要经常看,没事就拿来翻翻
接着是<<exceptional c++>>,个人认为Herb Sutter主席大人的语言表达能力不及Scott Meyers总是在教育第一线的好
顺下来就是<<more effective c++>>和<<more exceptional c++>>,请熟读并牢记各条款
当你读到这里,应该会有一股升级的冲动了

level 3
<<insied the c++ object model>>看过后如一缕清风扫去一直以来你对语言的疑惑,你终于能明白compiler到底都背着你做了些什么了,这本书要细细回味,比较难啃,最好反复看几遍,加深印象
看完上一本之后,这本<<The design and evolution of c++>>会重演一次当年C++他爹在设计整个语言过程中的历程

level 4
<<the c++ standard library>>是stl的字典,要什么都可以查得到
学c++不能不学stl,那么首先是<<effective stl>>,它和圣经一样是你日常行为的规范
<<generic programming and the stl>>让你从oo向gp转变
光用不行,我们还有必要了解stl的工作原理,那么<<stl源码剖析>>会解决你所有的困惑

level 5
对于c++无非是oo和gp,想进一步提升oo,<<exeptional c++ style>>是一本主席这么多年的经验之谈,是很长esp的
一位stl高手是不能不去了解template的,<<c++ template>>是一本百科全书,足够你看完后对于gp游刃有余
<<modern c++ design>>是太过聪明的人写给明眼人看的

好书有很多,不能一一列举
以上我的读书经历,供各位参考。接下来的无非就是打怪练级,多听多写多看;boost、stl、loki这些都是利器,斩妖除魔,奉劝各位别再土法练钢了。

at last,无他,唯手熟尔。


posted @ 2010-08-26 15:36 桂湖山 阅读(138) | 评论 (0)编辑 收藏
  2010年6月18日
1 用dos命令:copy /b c:\temp\my.prn prn,
对USB接口的打印机,则不能用此法了。
2 先将*.PRN转成*.PDF文件(* .prn〔可被Acrobat Distiller 自动识别〕,生成的 .ps 或者 .prn 文件在SSReader\History 目录下——>用Acrobat Distiller 打开 .ps 或者 .prn文件,即可转为pdf文件。),然后再将*.PDF转成WORD文件就可以编辑了;
3 另存网页后,再用打印机打印;
另TIFF文件详解
http://www.cnprint.org/bbs/thread/75/7375/
posted @ 2010-06-18 14:16 桂湖山 阅读(255) | 评论 (0)编辑 收藏
  2010年6月10日
按例子:
在JSP中放置java代码, 如<% %>,完成以下工作
  获取流程
  创建开始节点的任务,并设置任务的参数值,再结束该开始节点的任务,以完成流程的启动。

在其他JSP中依法处理,以便完成其他节点的任务。具体为:
  根据jsp的参数传来的taskid参数值,再由taskId获取到该task的变量值及其有关信息,
  展现一个处理页面,供处理本节点任务的进行修改,提交。
  再提交后,保存task的相关数据,并结束该任务,以便流程继续进行。

 
在流程的定义中,为每个任务的描述赋值为的唯一的标识符和处理页面,以便在task-list中获取该值
并链接到指定的处理页面。其描述可以为:description:deal_page,由task_list页面解析即可。并从
task获取所在流程对应节点node的描述信息,可以进行显示。

task中assigment的express不是jpdl,可用Actor方式指定,这里可用jdpl.
task中的Details的due date不知是什么,应该是一个用于定时的类。注意要实现指定的接口,否则会出项
“参数类型不匹配”的错误。

在流程的变量中赋值,有Decision节点来控制流程的条件转移。


posted @ 2010-06-10 16:25 桂湖山 阅读(148) | 评论 (0)编辑 收藏
  2010年5月22日


The parameter right was declared const. That means the object is const inside the operator function. But, const objects can only call const member functions because const objects must have a guarantee that they won't be changed. Since the operator<() function wasn't defined as const.

a const object can't call the function. The reason is that every class method has an invisible parameter: the this pointer. The this pointer can implicity or explicity be used inside the function to change the object, e.g.:

setPrivateVar(10);

or

this->setPrivateVar(10);

When you declare a member function const, the compiler will ensure that no changes can be made to the calling object.
posted @ 2010-05-22 13:53 桂湖山 阅读(283) | 评论 (0)编辑 收藏
  2010年5月20日

转自:http://hi.baidu.com/bleach007/blog/item/4a9013d141e362309a502729.html

1、缺少libc.lib
解决这个问题的方法是去掉链接到libc.lib,具体地点:项目-〉属性-〉配置属性-〉链接器-〉忽略特定库。

2、unresolved external symbol __iob
这个__iob找不到的问题费 了我大部分的时间。跟踪到stdio.h文件,发现那里有个关于iob的宏,终于搞定。加入一句话到.cpp文件中:extern "C" { FILE _iob[3] = {__iob_func()[0], __iob_func()[1], __iob_func()[2]}; }

3、NULL iterator
STL已经不能有NULL迭代器这么一说了,想想也对,在NULL迭代器上进行++或--之类的是不成立的。

4、结构体默认函数
在VC6中,结构体的默认运算符==或者<之类的如果不实现也可以作为STL元素放入list等容器中。但VC8不行了,因为它已经不再为结构体生 成缺省的操作符函数。

posted @ 2010-05-20 15:41 桂湖山 阅读(349) | 评论 (0)编辑 收藏
仅列出标题  下一页