关于作者

用户名:xuweigui
笔名:Windrift
地区: 上海-绍兴-周宁
行业:其他

日历  

快速登录

+ 用户名:
+ 密 码:

在线留言



天气预报

我的链接

日语

访问统计:
文章个数:315
评论个数:43
留言条数:25




Powered by BlogDriver 2.1

Windrift

 

新浪情侣圈 http://circle.blog.sina.com.cn/g/valentines

文章

Ajax和flex

Ajax

 

Ø      Open Source Community.に属する。

Flex 3 SDK Open Sourceであるが、Flex統合開発環境は有料だ。(Adobe Flex Builder 3 costs US$249 )

 

Ø      AJAXはこなれた技術の組み合わせで実現されていること

AjaxXHTMLCSSJavaScriptなどの技術を組み合わせただけでRIAを構築できること。その技術は現在のWebアプリケーションの開発技術と同じ、技術者が多いので、開発や保守が易く、コストが低い。

Flexのほうは、Flexの固有技術ActionScriptMXMLを学ぶ必要がある。

 

Ø      Ajaxで作った画面は従来のHtml画面と同じ

UIコンポーネントは従来Html画面と同じなので、ユーザーが利用しやすいようになる。

Flexのほうは、Flashと同じ画面を提供して、マウスクリックのメニューが従来のHtml画面と違い、画面テキストのコピもできない。

 

Ø      よくしているAjax Framework

1.      Prototype

Prototypeで開発したWeb Site:

·         CNN

·         The New York Times

·         Digg

·         Apple

·         Veoh.com

·         TypePad

·         Fox News Channel

·         Finetune

·         iLike

·         Last.fm

·         Twitter

·         Hakia

·         YouSendIt

 

2.      JQuery

JQueryで開発したWeb Site:

·         Digg

·         BBC

·         Major League Baseball

·         Dell

·         IsoHunt

·         Break.com

·         TinyPic

·         FixMyMovie

·         eMusic

·         Kayak

·         Box.net

 

3.      MooTools

JQueryで開発したWeb Site:

·         Mint

·         Worth1000

·         Bebo

·         Vimeo

 

4.      Yahoo! UI Library (YUI)

YUIで開発したWeb Site:

·         Yahoo! Shopping

·         Zillow

·         Bebo

·         YouSendIt

·         ImageShack

·         LinkedIn

·         Walmart.com

 

- 作者: Windrift 2008年06月30日, 星期一 16:49  回复(0) |  引用(0) 加入博采

Jquery EventDispatchAction的提交问题
摘要:使用EventDispatchAction时,jsp页面相应的提交按钮需要设置相应的name属性,属性的值与后台要调用的方法名相同。如下按钮提交时将调用相应的add方法。 如果需要在非点击按钮的情况下提交该表单(比如用jqury ajax)。该怎么办呢? 查看全文

- 作者: Windrift 2008年06月30日, 星期一 15:51  回复(0) |  引用(0) 加入博采

弹出式对话框(zz)

  如何利用网页弹出各种形式的窗口,我想大家大多都是知道些的,但那种多种多样的弹出式窗口是怎么搞出来的,我们今天就来学习一下:

  1.弹启一个全屏窗口

<html>
<body onload="window.open('http://www.pconline.com.cn','example01','fullscreen');">;
<b>www.e3i5.com</b>
</body>
</html>

  2.弹启一个被F11化后的窗口

<html>
<body onload="window.open(''http://www.pconline.com.cn','example02','channelmode');">;
<b>www.e3i5.com</b>
</body>
</html>

  3.弹启一个带有收藏链接工具栏的窗口

<html>
<body onload="window.open('http://www.pconline.com.cn','example03','width=400,height=300,directories');">
<b>www.e3i5.com</b>
</body>
</html>

  4.网页对话框

<html>
<SCRIPT LANGUAGE="javascript">
<!--
showModalDialog('http://www.pconline.com.cn','example04','dialogWidth:400px;dialogHeight:300px;
dialogLeft:200px;dialogTop:150px;center:yes;help:yes;resizable:yes;status:yes')
//-->
</SCRIPT>
<b>www.e3i5.com</b>
</body>
</html>

<html>
<SCRIPT LANGUAGE="javascript">
<!--
showModelessDialog('http://www.pconline.com.cn','example05','dialogWidth:400px;dialogHeight:300px;
dialogLeft:200px;dialogTop:150px;center:yes;help:yes;resizable:yes;status:yes')
//-->
</SCRIPT>
<b>http://www.pconline.com.cn</b>
</body>
</html>

  showModalDialog()或是showModelessDialog() 来调用网页对话框,至于showModalDialog()与showModelessDialog()的区别,在于showModalDialog()打开的窗口(简称模式窗口),置在父窗口上,必须关闭才能访问父窗口(建议尽量少用,以免招人反感);showModelessDialog()(简称无模式窗口),打开后不必关闭也可访问父窗口打开的窗口。

dialogHeight: iHeight 设置对话框窗口的高度。
dialogWidth: iWidth 设置对话框窗口的宽度。   
dialogLeft: iXPos 设置对话框窗口相对于桌面左上角的left位置。
dialogTop: iYPos 设置对话框窗口相对于桌面左上角的top位置。
center: {yes | no | 1 | 0 } 指定是否将对话框在桌面上居中,默认值是“yes”。
help: {yes | no | 1 | 0 } 指定对话框窗口中是否显示上下文敏感的帮助图标。默认值是“yes”。   
resizable: {yes | no | 1 | 0 } 指定是否对话框窗口大小可变。默认值是“no”。
status: {yes | no | 1 | 0 } 指定对话框窗口是否显示状态栏。对于非模式对话框窗口,默认值是“yes”;对于模式对话框窗口,默认值是 “no”。

- 作者: Windrift 2008年05月15日, 星期四 13:54  回复(0) |  引用(0) 加入博采

需找可以代替EmEditor的免费文本编辑器
emeditor可以自由的切换文件的编码,甚至在日文系统下也可以编辑GBK的文件。

而其他编辑器就不行了。

使用了一堆开源的,都不行,暂时使用了一款programmer's notepad 2。

不知道能不能在公司检查非法软件之前找到一款合意的呢。


附:
beyondcompare已经用winmerge代替了。

- 作者: Windrift 2008年05月14日, 星期三 12:57  回复(0) |  引用(0) 加入博采

按byte分割一个含有双字节字的字符串

按byte分割一个含有双字节字的字符串, 要求不能把双字节字分开。 

public static String getSubString(String src, int bytes) {
  final int len = src.getBytes().length;
  if (bytes > len ) {
   return src;
  }
  for(int pos = bytes/2; pos < len; pos++)  {
   if(src.substring(0, pos).getBytes().length >= bytes) {
    return  src.substring(0, pos);
   }
  }
  return src;
 }
 

测试程序

 public static void testGetSubString() {
  String str = "a中文bc中e文gt";
  for (int i = 0; i<str.getBytes().length + 1 ; i ++ ) {
   System.out.print("First " + i + " bytes of String: " + str + "is --> ");
   System.out.println(getSubString(str, i));
  }
 }

输出

First 0 bytes of String: a中文bc中e文gtis -->
First 1 bytes of String: a中文bc中e文gtis --> a
First 2 bytes of String: a中文bc中e文gtis --> a中
First 3 bytes of String: a中文bc中e文gtis --> a中
First 4 bytes of String: a中文bc中e文gtis --> a中文
First 5 bytes of String: a中文bc中e文gtis --> a中文
First 6 bytes of String: a中文bc中e文gtis --> a中文b
First 7 bytes of String: a中文bc中e文gtis --> a中文bc
First 8 bytes of String: a中文bc中e文gtis --> a中文bc中
First 9 bytes of String: a中文bc中e文gtis --> a中文bc中
First 10 bytes of String: a中文bc中e文gtis --> a中文bc中e
First 11 bytes of String: a中文bc中e文gtis --> a中文bc中e文
First 12 bytes of String: a中文bc中e文gtis --> a中文bc中e文
First 13 bytes of String: a中文bc中e文gtis --> a中文bc中e文g
First 14 bytes of String: a中文bc中e文gtis --> a中文bc中e文gt

- 作者: Windrift 2008年04月21日, 星期一 15:51  回复(0) |  引用(0) 加入博采

LINUX目录详解
LINUX目录详解

根文件系统一般应该比较小,因为包括严格的文件和一个小的不经常改变的文件系统不容易损坏。损坏的根文件系统一般意味着除非用特定的方法(例如从软盘)系统无法引导,所以不应该冒这个险。

根目录一般不含任何文件,除了可能的标准的系统引导映象,通常叫/vmlinuz 。所有其他文件在根文件系统的子目录中。

/bin
引导启动所需的命令或普通用户可能用的命令(可能在引导启动后)。
/sbin
类似/bin ,但不给普通用户使用,虽然如果必要且允许时可以使用。
/etc
特定机器的配置文件。
/root
root用户的家目录。
/lib
根文件系统上的程序所需的共享库。
/lib/modules
核心可加载模块,特别是那些恢复损坏系统时引导所需的(例如网络和文件系统驱动)。
/dev
设备文件。
/tmp
临时文件。引导启动后运行的程序应该使用/var/tmp ,而不是/tmp ,因为前者可能在一个拥有更多空间的磁盘上。
/boot
引导加载器(bootstrap loader)使用的文件,如LILO。核心映象也经常在这里,而不是在根目录。如果有许多核心映象,这个目录可能变得很大,这时可能使用单独的文件系统更好。另一个理由是要确保核心映象必须在IDE硬盘的前1024柱面内。
/mnt
系统管理员临时mount的安装点。程序并不自动支持安装到/mnt 。 /mnt 可以分为子目录(例如/mnt/dosa 可能是使用MSDOS文件系统的软驱,而/mnt/exta 可能是使用ext2文件系统的软驱)。
/proc , /usr , /var , /home
其他文件系统的安装点。

/etc 目录包含很多文件。下面说明其中的一些。其他的你应该知道它们属于哪个程序,并阅读该程序的man页。许多网络配置文件也在/etc 中,它们在《网络管理指南》中说明。

/etc/rc or /etc/rc.d or /etc/rc?.d
启动、或改变运行级时运行的scripts或scripts的目录,更详细的信息见关于init 的章。

/etc/passwd
用户数据库,其中的域给出了用户名、真实姓名、家目录、加密的口令和用户的其他信息。格式见passwd 的man页。

/etc/fdprm
软盘参数表。说明不同的软盘格式。用setfdprm 设置。更多的信息见setfdprm 的man页。

/etc/fstab
启动时mount -a命令(在/etc/rc 或等效的启动文件中)自动mount的文件系统列表。 Linux下,也包括用swapon -a启用的swap区的信息。见4.8.5节和mount 的man页。

/etc/group
类似/etc/passwd ,但说明的不是用户而是组。见group 的man页。

/etc/inittab
init 的配置文件。

/etc/issue
getty 在登录提示符前的输出信息。通常包括系统的一段短说明或欢迎信息。内容由系统管理员确定。

/etc/magic
file 的配置文件。包含不同文件格式的说明,file 基于它猜测文件类型。见magic 和file 的man页。

/etc/motd
Message Of The Day,成功登录后自动输出。内容由系统管理员确定。经常用于通告信息,如计划关机时间的警告。

/etc/mtab
当前安装的文件系统列表。由scripts初始化,并由mount 命令自动更新。需要一个当前安装的文件系统的列表时使用,例如df 命令。

/etc/shadow
在安装了影子口令软件的系统上的影子口令文件。影子口令文件将/etc/passwd 文件中的加密口令移动到/etc/shadow 中,而后者只对root可读。这使破译口令更困难。

/etc/login.defs
login 命令的配置文件。

/etc/printcap
类似/etc/termcap ,但针对打印机。语法不同。

/etc/profile , /etc/csh.login , /etc/csh.cshrc
登录或启动时Bourne或C shells执行的文件。这允许系统管理员为所有用户建立全局缺省环境。各shell见man页。

/etc/securetty
确认安全终端,即哪个终端允许root登录。一般只列出虚拟控制台,这样就不可能(至少很困难)通过modem或网络闯入系统并得到超级用户特权。

/etc/shells
列出可信任的shell。chsh 命令允许用户在本文件指定范围内改变登录shell。提供一台机器FTP服务的服务进程ftpd 检查用户shell是否列在 /etc/shells 文件中,如果不是将不允许该用户登录。

/etc/termcap
终端性能数据库。说明不同的终端用什么"转义序列"控制。写程序时不直接输出转义序列(这样只能工作于特定品牌的终端),而是从/etc/termcap 中查找要做的工作的正确序列。这样,多数的程序可以在多数终端上运行。见termcap 、 curs_termcap 和terminfo 的man页。

/dev目录
/dev 目录包括所有设备的设备文件。设备文件用特定的约定命名,这在设备列表中说明 (见[Anv])。设备文件在安装是产生,以后可以用 /dev/MAKEDEV 描述。 /dev/MAKEDEV.local 是系统管理员为本地设备文件(或连接)写的描述文稿 (即如一些非标准设备驱动不是标准MAKEDEV 的一部分)。

/usr 文件系统经常很大,因为所有程序安装在这里。 /usr 里的所有文件一般来自Linux distribution;本地安装的程序和其他东西在/usr/local 下。这样可能在升级新版系统或新distribution时无须重新安装全部程序。 /usr 的有些子目录在下面列出(一些不太重要的目录省略了,更多信息见FSSTND)。

/usr/X11R6
X Window系统的所有文件。为简化X的开发和安装,X的文件没有集成到系统中。 X自己在/usr/X11R6 下类似/usr 。
/usr/X386
类似/usr/X11R6 ,但是给X11 Release 5的。
/usr/bin
几乎所有用户命令。有些命令在/bin 或/usr/local/bin 中。
/usr/sbin
根文件系统不必要的系统管理命令,例如多数服务程序。
/usr/man , /usr/info , /usr/doc
手册页、GNU信息文档和各种其他文档文件。
/usr/include
C编程语言的头文件。为了一致性这实际上应该在/usr/lib 下,但传统上支持这个名字。
/usr/lib
程序或子系统的不变的数据文件,包括一些site-wide配置文件。名字lib来源于库(library); 编程的原始库存在/usr/lib 里。
/usr/local
本地安装的软件和其他文件放在这里。
/var/catman
当要求格式化时的man页的cache。man页的源文件一般存在/usr/man/man* 中;有些man页可能有预格式化的版本,存在/usr/man/cat* 中。而其他的man页在第一次看时需要格式化,格式化完的版本存在/var/man 中,这样其他人再看相同的页时就无须等待格式化了。 (/var/catman 经常被清除,就象清除临时目录一样。)
/var/lib
系统正常运行时要改变的文件。
/var/local
/usr/local 中安装的程序的可变数据(即系统管理员安装的程序)。注意,如果必要,即使本地安装的程序也会使用其他/var 目录,例如/var/lock 。
/var/lock
锁定文件。许多程序遵循在/var/lock 中产生一个锁定文件的约定,以支持他们正在使用某个特定的设备或文件。其他程序注意到这个锁定文件,将不试图使用这个设备或文件。
/var/log
各种程序的Log文件,特别是login (/var/log/wtmp log所有到系统的登录和注销) 和syslog (/var/log/messages 里存储所有核心和系统程序信息。 /var/log 里的文件经常不确定地增长,应该定期清除。
/var/run
保存到下次引导前有效的关于系统的信息文件。例如, /var/run/utmp 包含当前登录的用户的信息。
/var/spool
mail, news, 打印队列和其他队列工作的目录。每个不同的spool在/var/spool 下有自己的子目录,例如,用户的邮箱在/var/spool/mail 中。
/var/tmp
比/tmp 允许的大或需要存在较长时间的临时文件。 (虽然系统管理员可能不允许/var/tmp 有很旧的文件。)

/proc 文件系统是一个假的文件系统。它不存在在磁盘某个磁盘上。而是由核心在内存中产生。用于提供关于系统的信息(originally about processes, hence the name)。下面说明一些最重要的文件和目录。 /proc 文件系统在proc man页中有更详细的说明。

/proc/1
关于进程1的信息目录。每个进程在/proc 下有一个名为其进程号的目录。
/proc/cpuinfo
处理器信息,如类型、制造商、型号和性能。
/proc/devices
当前运行的核心配置的设备驱动的列表。
/proc/dma
显示当前使用的DMA通道。
/proc/filesystems
核心配置的文件系统。
/proc/interrupts
显示使用的中断,and how many of each there have been.
/proc/ioports
当前使用的I/O端口。
/proc/kcore
系统物理内存映象。与物理内存大小完全一样,但不实际占用这么多内存;it is generated on the fly as programs access it. (记住:除非你把它拷贝到什么地方,/proc 下没有任何东西占用任何磁盘空间。)
/proc/kmsg
核心输出的消息。也被送到syslog 。
/proc/ksyms
核心符号表。
/proc/loadavg
系统"平均负载";3个没有意义的指示器指出系统当前的工作量。
/proc/meminfo
存储器使用信息,包括物理内存和swap。
/proc/modules
当前加载了哪些核心模块。
/proc/net
网络协议状态信息。
/proc/self
到查看/proc 的程序的进程目录的符号连接。当2个进程查看/proc 时,是不同的连接。这主要便于程序得到它自己的进程目录。
/proc/stat
系统的不同状态,such as the number of page faults since the system was booted.
/proc/uptime
系统启动的时间长度。
/proc/version
核心版本。

- 作者: Windrift 2007年09月12日, 星期三 13:13  回复(0) |  引用(0) 加入博采

别人推荐的C、C++书
<C++ Primer>
<Effective C++>/《More Effective C++》/<Exceptional C++>/《More Exceptional C++》
<C++语言设计与演化>

- 作者: Windrift 2007年08月1日, 星期三 16:36  回复(0) |  引用(0) 加入博采

Struts Spring Hibernate 事务管理的例子。

这两天比较清闲,试着配置了一下Struts Spring Hibernate 。由Spring来接管Struts的Action和Hibernate的事务管理。现做一下笔记。

1. Struts配置文件struts-config.xml

首先加上Spring的Context Loader插件

 <plug-in
  className="org.springframework.web.struts.ContextLoaderPlugIn">
  <set-property property="contextConfigLocation"
   value="/WEB-INF/beans.xml" />
 </plug-in>

其中beans.xml是Spring的配置文件。

添加一个Action

  <action path="/sample"
   type="org.springframework.web.struts.DelegatingActionProxy">
  </action>
注意type变成了Spring的代理类,当然这儿可以加入一些Forward

2. Spring的配置文件 beans.xml

添加action的对应bean,由于struts已经把这个bean委托给spring来管了,所以当然应该在spring中配置对应的class

 <bean name="/sample" class="com.windrift.action.SampleAction">
  <property name="sampleManager" ref="sampleManager" />
 </bean>

对sampleManager的配置,实际上对应的是 com.windrift.manager.SampleManager,由于需要对这个manager配置事务,所以给他指定了一个模板parent="baseService",注意这个parent并不是指继承关系,稍后我们会对这个模板指定事务的策略。

<bean id="sampleManager" parent="baseService">
  <property name="target">
   <bean class="com.windrift.manager.SampleManager" autowire="byName">
    <property name="sampleDAO" ref="sampleDAO" />
   </bean>
  </property>
 </bean>

配置sampleDAO,这里的模板baseDao我们不关心,这儿不详述。

 <bean id="sampleDAO" parent="baseDao">
  <property name="target">
   <bean class="com.windrift.dao.imp.SampleDAOImp" autowire="byName"></bean>
  </property>
 </bean> 

下面配置Hibernate的数据源,这儿用的是MySQL数据库,由于数据库的处理等已经交由Spring处理,因此不再需要Hibernate的配置文件。除了表和PO的映射文件外(如Sample.hbm.xml)

 <bean id="dataSource"
  class="org.apache.commons.dbcp.BasicDataSource"
  destroy-method="close">
  <property name="driverClassName">
   <value>com.mysql.jdbc.Driver</value>
  </property>
  <property name="url">
   <value>jdbc:mysql://localhost/shop</value>
  </property>
  <property name="username">
   <value>root</value>
  </property>
  <property name="password">
   <value>root</value>
  </property>
 </bean>

sessionFactory依据数据源创建Session链接

 <bean id="sessionFactory"
  class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
  <property name="dataSource">
   <ref local="dataSource" />
  </property>
  <property name="mappingResources">
   <list>
    <value>SystemInfo.hbm.xml</value>
    <value>Ad.hbm.xml</value>
    <value>Good.hbm.xml</value>
    <value>Logo.hbm.xml</value>
    <value>Member.hbm.xml</value>
    <value>News.hbm.xml</value>
    <value>NSort.hbm.xml</value>
    <value>Pub.hbm.xml</value>
    <value>Sort.hbm.xml</value>
    <value>Sub.hbm.xml</value>
    <value>Basket.hbm.xml</value>
    <value>Sample.hbm.xml</value>
   </list>
  </property>
  <property name="hibernateProperties">
   <props>
    <prop key="hibernate.connection.useUnicode">true</prop>
    <prop key="hibernate.connection.characterEncoding">
     UTF-8
    </prop>
    <prop key="hibernate.cglib.use_reflection_optimizer">
     false
    </prop>
    <prop key="hibernate.connection.pool.size">2</prop>
    <prop key="hibernate.show_sql">true</prop>
    <prop key="jdbc.fetch_size">50</prop>
    <prop key="jdbc.batch_size">25</prop>
    <prop key="jdbc.use_scrollable_resultset">false</prop>
    <prop key="hibernate.hbm2ddl.auto">update</prop>
    <prop key="hibernate.dialect">
     org.hibernate.dialect.MySQLDialect
    </prop>
   </props>
  </property>
 </bean>

事务管理类,通过SessionFactory来获取session
 <bean id="transactionManager"
  class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  <property name="sessionFactory">
   <ref local="sessionFactory" />
  </property>
 </bean>

配置一个切入器,它依据配置的一些事务策略,会调用 transactionManager来进行事务管理。

这个例子中需要进行事务管理的类(所有parent是baseService的类)的所有以Get开头的方法会在一个只读事务环境中运行。其余方法需要进行事务传递,并且一旦这个方法抛出BaseException异常则回滚事务。(如果希望强制commit事务,则把BaseException前面的-改成+)

<bean id="transactionInterceptor"
  class="org.springframework.transaction.interceptor.TransactionInterceptor">
  <property name="transactionManager">
   <ref bean="transactionManager" />
  </property>
  <property name="transactionAttributes">
   <props>
    <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
    <prop key="*">
     PROPAGATION_REQUIRED,-BaseException
    </prop>
   </props>
  </property>
 </bean>

这个就是前面提到的模板,它说明所有应用此模板的类(parent=baseService的 类)都会被 置于transactionInterceptor中配置的事务环境中。

<bean id="baseService" abstract="true"
  class="org.springframework.aop.framework.ProxyFactoryBean">
  <property name="interceptorNames">
   <list>
    <value>transactionInterceptor</value>
   </list>
  </property>
 </bean>

3. SampleAction.java

只是简单的调用了一下manager的方法

package com.windrift.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import com.windrift.manager.SampleManager;

public class SampleAction extends Action{
 private SampleManager sampleManager;
 public ActionForward execute(ActionMapping aMapping, ActionForm aForm,
   HttpServletRequest aRequest, HttpServletResponse aResponse)
   throws Exception {
  sampleManager.doSomething();
  return null;
  
 }
 public void setSampleManager(SampleManager sampleManager) {
  this.sampleManager = sampleManager;
 }
}

4. SampleManager.java

方法doSomething中我们往数据库里加了两个记录Sample1和Sample2

但是在最后我们强制抛出了一个BaseException,根据前面设置的事务环境和策略,这两条插入的记录都会被回滚。

package com.windrift.manager;

import com.windrift.dao.SampleDAO;
import com.windrift.dao.persist.Sample;
import com.windrift.exception.BaseException;

public class SampleManager {
 private SampleDAO sampleDAO;

 public void setSampleDAO(SampleDAO sampleDAO) {
  this.sampleDAO = sampleDAO;
 }

 public void doSomething() throws BaseException{
  Sample sample1 = new Sample();
  sample1.setSample("sample1");
  sampleDAO.addSample(sample1);
  Sample sample2 = new Sample();
  sample2.setSample("sample2");
  sampleDAO.addSample(sample2);
  throw new BaseException();
 }

}

5. SampleDAOImp.java

简单的调用了父类的方法。

package com.windrift.dao.imp;

import com.windrift.dao.SampleDAO;
import com.windrift.dao.persist.Sample;

public class SampleDAOImp extends BaseDAOImp implements SampleDAO {

 public void addSample(Sample sample) {
  this.save(sample);
 }
}

补充一个需要使用回调函数的方法。由于我们的session的管理(包括事务)都交给spring来处理了。所以通常情况下我们是无法访问session的。但是有时候我们又需要使用session,这时候就需要使用回调函数,以取得session。

 public List getAllSortASC() {
  return getHibernateTemplate().executeFind(new HibernateCallback() {
   public Object doInHibernate(Session session)
     throws HibernateException, SQLException {
  Query query = session.createQuery("from Sort order by sort_id asc");
  List sorts = query.list();
  return sorts;
 }});}

 public Sort getSortById(final int id) {
  List list = getHibernateTemplate().executeFind(new HibernateCallback() {
   public Object doInHibernate(Session session)
     throws HibernateException, SQLException {
    Query query = session
      .createQuery("from Sort where sort_ID = ?");
    query.setInteger(0, id);
    return query.list();    
   }
  });
  if (list != null && list.isEmpty() == false) {
   return (Sort) list.get(0);
  } else {
   return null;
  }
 }

6. DAO的基类

注意由于所有dao都需要继承自HibernateDaoSupport ,所以我们在基类中做这个动作。

package com.windrift.dao.imp;

import java.io.Serializable;

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.windrift.dao.BaseDAO;

public class BaseDAOImp extends HibernateDaoSupport implements BaseDAO {
 /* (non-Javadoc)
  * @see com.windrift.dao.imp.BaseDAO#delete(java.lang.Object)
  */
 public void delete(Object o) {
  getHibernateTemplate().delete(o);
 }

 /* (non-Javadoc)
  * @see com.windrift.dao.imp.BaseDAO#flush()
  */
 public void flush() {
  getHibernateTemplate().flush();
 }

 /* (non-Javadoc)
  * @see com.windrift.dao.imp.BaseDAO#get(java.lang.Class, java.io.Serializable)
  */
 public Object get(Class clazz, Serializable id) {
  return getHibernateTemplate().get(clazz, id);
 }

 /* (non-Javadoc)
  * @see com.windrift.dao.imp.BaseDAO#load(java.lang.Class, java.io.Serializable)
  */
 public Object load(Class clazz, Serializable id) {
  return getHibernateTemplate().load(clazz, id);
 }

 /* (non-Javadoc)
  * @see com.windrift.dao.imp.BaseDAO#refresh(java.lang.Object)
  */
 public void refresh(Object o) {
  getHibernateTemplate().refresh(o);
 }

 /* (non-Javadoc)
  * @see com.windrift.dao.imp.BaseDAO#remove(java.lang.Class, java.io.Serializable)
  */
 public void remove(Class clazz, Serializable id) {
  getHibernateTemplate().delete(get(clazz, id));
 }

 /* (non-Javadoc)
  * @see com.windrift.dao.imp.BaseDAO#save(java.lang.Object)
  */
 public void save(Object o) {
  getHibernateTemplate().save(o);
 }

 /* (non-Javadoc)
  * @see com.windrift.dao.imp.BaseDAO#saveOrUpdate(java.lang.Object)
  */
 public void saveOrUpdate(Object o) {
  getHibernateTemplate().saveOrUpdate(o);
 }

 /* (non-Javadoc)
  * @see com.windrift.dao.imp.BaseDAO#update(java.lang.Object)
  */
 public void update(Object o) {
  getHibernateTemplate().update(o);
 }
}

自此圆满完成这个小例子。最后说一点,由于hibernate进行了一次版本更新,因此存在hibernate3和hibernate两个包(如:import org.springframework.orm.hibernate3.support.HibernateDaoSupport;)。大家一定都使用hibernate3,不然出错比较难找。

- 作者: Windrift 2007年07月4日, 星期三 14:32  回复(2) |  引用(0) 加入博采

Spring的事务控制(zz)

事务控制

    Author: 江南白衣

    暂时使用所有Sample通用的声明式事务控制体系,可以考虑JDK5.0的Annotation方式,但声明式体系下get*,find*的基类预定义比较节约代码。

    在声明式事务体系下,一般会定义一个baseTxService基类

<bean id="baseTxService"
          class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
          abstract="true">
        <property name="transactionManager" ref="transactionManager"/>
        <property name="proxyTargetClass" value="true"/>
   <property name="transactionAttributes">
            <props>
                <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
                <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
                <prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
                <prop key="save*">PROPAGATION_REQUIRED</prop>
                <prop key="update*">PROPAGATION_REQUIRED</prop>
                <prop key="remove*">PROPAGATION_REQUIRED</prop>
            </props>
        </property>
    </bean>

   Tips1 ,因为我们没有创建Service接口,不能用基于接口的Proxy方式,必须使用cgilib来实现AOP事务管理,且cglib的方式比Proxy方式效率略高,因此需定义:

<property name="proxyTargetClass" value="true"/>

   Tips2,当实际的Service子类需要事务控制的方法如--shipOrder,不为以上的get*,save*的命名方式时,需要在子类重新定义transactionAttributes。

   从Spring 2.0M2开始,beans支持default-merge= "true" 的定义,子类不需要重新定义get*,save*。

   可以在beans统一定义default-merge= true,也可以每个bean定义。

<beans default-merge="true"> 
<bean id="orderManager" parent="baseTxService">
        <property name="target">
            <bean class="org.springside.bookstore.service.OrderManager"/>
        </property>
        <property name="transactionAttributes">
            <props>
                <prop key="shipOrder">PROPAGATION_REQUIRED</prop>
            </props>
         </property>
    </bean>
</beans>

- 作者: Windrift 2007年07月4日, 星期三 10:38  回复(0) |  引用(0) 加入博采

Plsql培训中做的练习

上周参加了两天plsql的培训。毕竟系统的了解一下是有意义的。贴上课上做的一些练习。供以后参考。

declare
  tabName varchar(128);
  a       number;
begin
  select table_name into tabName from user_tables where rownum = 1;
  dbms_output.put_line(tabName);
  if ('aa' = 'Aa') then
    a := 5;
  else
    a := 6;
  end if;
  dbms_output.put_line(a);
end;
/*
ICOL$
6
*/

-----------------------------------------------------------------

begin
  dbms_output.put_line(0.95F); --float
  dbms_output.put_line(0.95D); --double
  dbms_output.put_line(0.95);
  dbms_output.put_line(trunc(25.176, 1));
  dbms_output.put_line(trunc(25.176, -1));
  dbms_output.put_line(round(25.176, 1));
  dbms_output.put_line(round(25.176, -1));
  dbms_output.put_line(ceil(25.176));
  dbms_output.put_line(floor(25.176));
end;
/*
9.49999988E-001
9.4999999999999996E-001
.95
25.1
20
25.2
30
26
25
*/

-------------------------------------------------------------------

declare
  -- tabName varchar(128); -- no need
  num number;
begin
  for tabName in (select table_name from user_tables) loop
    dbms_output.put_line(tabName.table_name);
  end loop;
  for num in 1 .. 5 loop
    dbms_output.put_line(num);
  end loop;
end;

----------------------------------------------------------------------

select ascii(' '), initcap('xu weigui'), ltrim('aaaadfdfd', 'a') from dual;

select interval '40' year from dual;

select interval '40-3' year to month from dual;
----------------------------------------------------------------------

declare
  a interval year to month;
begin
  a := numtoyminterval(10.5, 'year');
  dbms_output.put_line(a);
end;

/*
+10-06
*/
----------------------------------------------------
declare
  type mytype is table of varchar2(100) index by binary_integer;
  mytable mytype;

begin
  mytable(1) := 'xuweigui';
  mytable(123) := 'Andy';
  dbms_output.put_line(mytable(1));
  dbms_output.put_line(mytable(123));
end;

--------------------------------------------------------------
declare
  type mytype is table of varchar2(100);
  mytable mytype := mytype('a');
  mytable2 mytype :=mytype(5,4,3,2,1); --Until you initialize it, a nested table or varray is atomically null;

begin
  if mytable is null then
   null;
  elsif mytable.count =0 then
   null;
  end if;
 
  dbms_output.put_line('mytable init');
  for i in mytable.first .. mytable.last loop
   dbms_output.put_line(mytable(i));
  end loop;
 
  mytable.extend(5);
  dbms_output.put_line('mytable.extend(5)');
  for i in mytable.first .. mytable.last loop
   dbms_output.put_line(mytable(i));
  end loop;
 
  mytable(1) := 'xuweigui';
  mytable(6) := 'Andy';
  dbms_output.put_line('mytable assign value');
  for i in mytable.first .. mytable.last loop
   dbms_output.put_line(mytable(i));
  end loop;
 
  dbms_output.put_line('mytable2 init');
  for i in mytable2.first .. mytable2.last loop
   dbms_output.put_line(mytable2(i));
  end loop;
 
  mytable2.extend(20);
  dbms_output.put_line('mytable2 extend(20)');
  for i in mytable2.first .. mytable2.last loop
   dbms_output.put_line(mytable2(i));
  end loop;
 
exception
  when collection_is_null then
    dbms_output.put_line('exception');
end;


-------------------------------------------------------------------
DECLARE
TYPE staff_list IS TABLE OF employees.employee_id%TYPE;
    staff staff_list;
    lname employees.last_name%TYPE;
    fname employees.first_name%TYPE;
BEGIN
    staff := staff_list(100, 114, 115, 120, 122);
    FOR i IN staff.FIRST..staff.LAST LOOP
        SELECT last_name, first_name INTO lname, fname FROM employees
        WHERE employees.employee_id = staff(i);
        DBMS_OUTPUT.PUT_LINE ( TO_CHAR(staff(i)) || ': ' || lname || ', ' || fname );
    END LOOP;
END;
/
--------------------------------------------------------------
declare
  rCnt integer;
begin
  select count(*) into rCnt from employees;
  dbms_output.put_line(sql%rowcount);
end;

------------------------------------------

declare
  --type curType is ref cursor;
  cursor mycursor is
    select * from employees;
begin
  --open mycursor for select * from employees;
  for empRec in mycursor loop
    dbms_output.put_line(empRec.first_name || ' ' || empRec.last_name);
  end loop;
  dbms_output.put_line('-----------------------------------------------');
  for empRec in (select * from employees where employee_id < 120) loop
    dbms_output.put_line(empRec.first_name || ' ' || empRec.last_name);
  end loop;
end;
---------------------------------------------
select count(case
               when salary < 2000 then
                1
               else
                null
             end) count1,
       count(case
               when salary between 2001 and 4000 then
                1
               else
                null
             end) count2,
       count(case
               when salary > 4000 then
                1
               else
                null
             end) count3
  from employees;
-----------------------------------------------------------

begin
  create table test(id integer); --error
end;
/

begin execute immediate 'create table  test (id integer)'; --dynamic sql
end;
/

--------------------------------------------------------------------
--pass parameter to dynamic sql
declare
  str   varchar2(1000);
  fname varchar2(100);
  lname varchar2(100);
begin
  str := 'select first_name, last_name from employees where employee_id = :emp_id';
  execute immediate str
    into fname, lname
    using 201;
  dbms_output.put_line(fname || ' ' || lname);
end;
/
-------------------------------------------------------------
select to_number('F123.456,78',
                 'L999G999D99',
                 'NLS_NUMERIC_CHARACTERS='',.'' ' || ' NLS_CURRENCY=''f'' ' ||
                 'NLS_ISO_CURRENCY=FRANCE')
  FROM DUAL;
--123456.78
SELECT TO_CHAR(123456.78,
               'L999G999D99',
               'NLS_NUMERIC_CHARACTERS='',.'' ' || ' NLS_CURRENCY=''f'' ' ||
               'NLS_ISO_CURRENCY=FRANCE')
  FROM DUAL;
--          f123.456,78

-------------------------------------------------------------------------------
SELECT last_name,
       employee_id,
       manager_id,
       LEVEL,
       SYS_CONNECT_BY_PATH(last_name, '/') "Path"
  FROM employees
--START WITH employee_id = 100
CONNECT BY PRIOR employee_id = manager_id
 ORDER SIBLINGS BY last_name;
--------------------------------------------------------------------
declare
  my_exception exception;
  pragma exception_init(my_exception, -259);--should between -20999, -20000
begin
  begin
    raise MY_EXCEPTION;
  EXception
    when my_exception then
      dbms_output.put_line('first exception');
      dbms_output.put_line(sqlcode);-- -259
      raise;
  end;
EXception
  when my_exception then
    dbms_output.put_line('second exception');
end;
---------------------------------------------------
DECLARE
   past_due   EXCEPTION;
   acct_num   NUMBER;
BEGIN
   DECLARE                                  
      past_due      EXCEPTION;                 
      acct_num      NUMBER;
      due_date      DATE      := SYSDATE - 1;
      todays_date   DATE      := SYSDATE;
   BEGIN
      IF due_date < todays_date
      THEN
         RAISE past_due;                     
      END IF;
   END;                                 
EXCEPTION
   WHEN past_due
   THEN                                
      DBMS_OUTPUT.put_line('Handling PAST_DUE exception.');
   WHEN OTHERS
   THEN
      --go this path
      DBMS_OUTPUT.put_line('Could not recognize PAST_DUE_EXCEPTION in this scope.');
END;


DECLARE
   past_due   EXCEPTION;
   pragma exception_init(past_due, -259);
   acct_num   NUMBER;
BEGIN
   DECLARE                                  
      past_due      EXCEPTION;
      pragma exception_init(past_due, -259);                 
      acct_num      NUMBER;
      due_date      DATE      := SYSDATE - 1;
      todays_date   DATE      := SYSDATE;
   BEGIN
      IF due_date < todays_date
      THEN
         RAISE past_due;                     
      END IF;
   END;                                 
EXCEPTION
   WHEN past_due
   THEN
      --go this path                                
      DBMS_OUTPUT.put_line('Handling PAST_DUE exception.');
   WHEN OTHERS
   THEN     
      DBMS_OUTPUT.put_line('Could not recognize PAST_DUE_EXCEPTION in this scope.');
END;
----------------------------------------------------------------
begin
  raise_application_error(-20111, 'error message');
exception
 when others then
  dbms_output.put_line(sqlcode);
  dbms_output.put_line(sqlerrm);
end;
----------------------------------------------------------------
create or replace package my_package is
  num number := 5;
  one number :=1;
  function f return number;
  procedure print;
  function add (first number, second number default 1) return number; --second has a default value of 1 
end my_package;

create or replace package body my_package is
  i number := 3;
  function f return number is
  begin
    return num;
  end f;
  procedure print is
  begin
    dbms_output.put_line(f());
  end print;
  function add (first number, second number) return number is
  begin
   return first + second;
  end add;
end my_package;

begin
 dbms_output.put_line(my_package.add(5));
 dbms_output.put_line(my_package.add(5, 5));
 dbms_output.put_line(my_package.add(second => 5, first=>12));
 my_package.print();
 dbms_output.put_line(my_package.num);
end;
----------------------------------------------------------------------
create table emp as select * from employees;

create table tab (id number, oldsal number);

create or replace trigger tri
  before update on emp
  for each row
declare
  progma autonomous_transaction;
begin
  insert into tab values (:old.employee_id, :old.salary);
  commit;
end tri;


update emp set salary = salary;
rollback;--although rollback here, data is inserted into tab in trigger

select * from tab;
---------------------------------

begin
for i in 1..5 loop
 dbms_output.put_line(i);
 if i=3 then
  exit;--exit the loop
 end if;
end loop;
dbms_output.put_line('exit loop');
end;
------------------------------

begin
for j in 1..2 loop
  for i in 1..5 loop
   dbms_output.put_line('innner loop ' || i);
   if i=3 then
    exit;--exit the inner loop
   end if;
  end loop;
  dbms_output.put_line('outer loop ' || j);
end loop;
dbms_output.put_line('end');
end;

--------------------------------------
declare
  type myrecord_type is record(
    first_name employees.first_name%type,
    last_name  employees.last_name%type);
  TYPE mycur_type IS REF CURSOR RETURN myrecord_type;
  cur    mycur_type;
  person myrecord_type;
begin
  if 1 = 2 then
    open cur for
      select first_name, last_name from employees where employee_id = 198;
  else
    open cur for
      select first_name, last_name from employees where employee_id = 199;
  end if;
  loop
    fetch cur
      into person;
    exit when cur%NOTFOUND;
    dbms_output.put_line(person.first_name || ' ' || person.last_name);
  end loop;
  close cur;
end;


---------------------------------
alter session set plsql_ccflags = 'to_debug:true'

declare
  $if $$to_debug $then
   cursor cur is select first_name, last_name from employees where employee_id = 198;
  $else
   cursor cur is select first_name, last_name from employees where employee_id = 199;
  $end
begin
   for person in cur loop
    dbms_output.put_line(person.first_name || ' ' || person.last_name);
  end loop;
end;
/*
Example Using ALTER PROCEDURE to Set PLSQL_CCFLAGS
ALTER PROCEDURE circle_area COMPILE PLSQL_CCFLAGS = 'my_debug:TRUE'
REUSE SETTINGS;
*/

-----------------------------------------
DECLARE
    s PLS_INTEGER := 0;
    i PLS_INTEGER := 0;
    j PLS_INTEGER;
BEGIN
    <<outer_loop>>
    LOOP
        i := i + 1;
        j := 0;
        <<inner_loop>>
        LOOP
            j := j + 1;
            s := s + i * j; -- sum a bunch of products
            EXIT inner_loop WHEN (j > 5);
            EXIT outer_loop WHEN ((i * j) > 15);
        END LOOP inner_loop;
    END LOOP outer_loop;
    DBMS_OUTPUT.PUT_LINE('The sum of products equals: ' || TO_CHAR(s));
END;
------------------------------------------------------
--cursor with parameter
DECLARE
  CURSOR c1(job VARCHAR2, max_wage NUMBER) IS
    SELECT *
      FROM employees
     WHERE job_id = job
       AND salary > max_wage;
BEGIN
  FOR person IN c1('CLERK', 3000) LOOP
    -- process data record
    DBMS_OUTPUT.PUT_LINE('Name = ' || person.last_name || ', salary = ' ||
                         person.salary || ', Job Id = ' || person.job_id);
  END LOOP;
END;

- 作者: Windrift 2007年06月25日, 星期一 13:07  回复(0) |  引用(0) 加入博采

Pdf 阅读器“Invalid plugin detected ”的错误

最近安装了Adobe Reader 8, 老是出现“Invalid plugin detected ”的错误,一个文档也看不了。

上网上找了一下,有人提供了一个方法,在打开文档的时候按住左边的 shift键,这样可以阻止plgin的加载。试了一下,果然可以。

但是每次都要按住还是很麻烦,而且一旦忘了,又导致Adobe Reader死掉。

决定彻底清除这个问题,找到Adobe Reader的plgin目录,“C:\Program Files\Adobe\Reader 8.0\Reader\plug_ins”, 里面有十多个Plugin。首先想通过观察他们的创建时间来知道哪个是Adobe Reader 安装之后别的程序加上去的,但是发现他们的创建时间都差不多,无法判断。

无意中发现文件属性Owner,其他的都是administrator,只有一个不是,而是我当前登录的用户。

把他给删掉之后就好了。原来是stardict的插件搞得鬼。

- 作者: Windrift 2007年06月20日, 星期三 18:35  回复(2) |  引用(0) 加入博采

oracle cursor (zz)

使用Cursor:

declare

RoomID Room.RoomID%Type;

RoomName Room.RoomName%Type;

cursor crRoom is

select RoomID,RoomName

from Room;

begin

open crRoom;loop;

fetch crRoom into RoomID,RoomName;

exit when crRoom%notFound;

end loop;

close crRoom;

end;


3.1在游标使用入口参数

SQL语句的Where 子句中恰当使用 相关语句简化逻辑,本来需要使用两个游标,把相关入口参数放入到SQL语句的Where 子句中,一个就搞定了:

cursor crRoom is
select
distinct 楼层,房屋用途
from TT_没有处理的房屋 t
where 数据级别>=
0 and 房屋处理类别= 3 and 产权编号=p_产权编号
and 拆迁房屋类别=p_拆迁房屋类别
and 面积>
0 and (not p_房屋用途 is null
and 房屋用途=p_房屋用途
or p_房屋用途 is null);

另外一个例子:

CREATE OR REPLACE PROCEDURE PrintStudents(
p_Major IN students.major%TYPE) AS
CURSOR c_Students IS
SELECT first_name, last_name
FROM students
WHERE major = p_Major;
BEGIN
FOR v_StudentRec IN c_Students LOOP
DBMS_OUTPUT.PUT_LINE(v_StudentRec.first_name || ' ' ||
v_StudentRec.last_name);
END LOOP;
END;

Oracle带的例子examp6.sql

DECLARE CURSOR bin_cur(part_number NUMBER) IS SELECT amt_in_bin
FROM bins
WHERE part_num = part_number AND
amt_in_bin >
0 ORDER BY bin_num
FOR UPDATE OF amt_in_bin;
bin_amt bins.amt_in_bin%TYPE;
total_so_far NUMBER(
5) := 0;
amount_needed CONSTANT NUMBER(
5) := 1000;
bins_looked_at NUMBER(
3) := 0;
BEGIN
OPEN bin_cur(
5469);
WHILE total_so_far < amount_needed LOOP
FETCH bin_cur INTO bin_amt;
EXIT WHEN bin_cur%NOTFOUND;
/* If we exit, there's not enough to *
* satisfy the order. */
bins_looked_at := bins_looked_at + 1;
IF total_so_far + bin_amt < amount_needed THEN
UPDATE bins SET amt_in_bin =
0 WHERE CURRENT OF bin_cur;
-- take everything in the bin
total_so_far := total_so_far + bin_amt;
ELSE -- we finally have enough
UPDATE bins SET amt_in_bin = amt_in_bin
- (amount_needed - total_so_far)
WHERE CURRENT OF bin_cur;
total_so_far := amount_needed;
END IF;
END LOOP;
CLOSE bin_cur;
INSERT INTO temp VALUES (NULL, bins_looked_at,
'<- bins looked at');
COMMIT;
END;

-- Created on 2004-8-9 by ADMINISTRATOR
declare
--带有变量的Cursor

cursor crBooks(c_bookTitle varchar2) is
select *
from books a
where a.title like c_bookTitle||
'%'
;
begin
for v_Books in crBooks(
'Oracle8'
) loop
dbms_output.put_line(v_Books.author1);
end loop;
end;


3.2.使用对象的属性

-- Author : XJG

-- Created : 2002.03.01 20:52:22

-- Purpose : 产生拆迁数据的报表数据

procedure GenConCQReport (

p_UserID in Common.SEQType, ---0 =使用权,1 = 高级使用权,2 = 机团

p_UserType in Common.THundred) is

type TTitleArr is varray (5) of varchar2 (20);

v_Title TTitleArr

:= TTitleArr ('可以签订的财产',

'已经签订的财产',

'可能可以签定的财产',

'不能签订的财产',

'已签定的合同'

);

v_DateLevel TTitleArr := TTitleArr ('1', '2', '3', '4', '5');

begin

forall i in v_Title.first .. v_Title.last

update TT_拆迁数据分类 T

set T.数据级别 = to_number (v_DateLevel (i))

where (T.财产编号 is not null)

and (T.财产编号, T.财产类别) in (

select TT.财产编号, TT.财产类别

from TT_拆迁数据分类 TT

start with TT.标题 = v_Title (i)

connect by prior TT.拆迁数据分类编号 =

TT.上级编号);

end;

3.3匿名游标

匿名游标,是我自己给的一个称呼。在游标FOR循环中可以定义查询,由于没有显式声明所以游标没有名字,记录名通过游标查询来定义。

DECALRE

v_tot_salary EMP.SALARY%TYPE;

BEGIN

FOR r_dept IN (SELECT deptno,dname FROM dept ORDER BY deptno) LOOP

DBMS_OUTPUT.PUT_LINE('Department:'|| r_dept.deptno||'-'||r_dept.dname);

v_tot_salary:=0;

DBMS_OUTPUT.PUT_LINE('Toltal Salary for dept:'|| v_tot_salary);

END LOOP;

END;

3.4游标指针

-- Author : wdz
-- Created : 2003-10-22
-- Purpose : 使用系统定义的游标指针类型作为参数

wdzwdz 发表于:2004.08.26 21:00

- 作者: Windrift 2007年05月25日, 星期五 13:24  回复(0) |  引用(0) 加入博采

一款开源的pdf阅读器Sumatra PDF

很小巧。速度很快!

http://blog.kowalczyk.info/software/sumatrapdf/

What is Sumatra PDF?

Sumatra PDF is a slim, free, open-source PDF viewer for Windows.

Why another PDF reader?

Sumatra has a minimalistic design. Simplicity has a higher priority than a lot of features.

It's small and starts up very fast.

It's designed for portable use: it's just one file with no external dependencies so you can easily run it from external USB drive.

- 作者: Windrift 2007年05月23日, 星期三 14:20  回复(0) |  引用(0) 加入博采

一款开源的pdf阅读器Sumatra PDF

很小巧。速度很快!

http://blog.kowalczyk.info/software/sumatrapdf/

What is Sumatra PDF?

Sumatra PDF is a slim, free, open-source PDF viewer for Windows.

Why another PDF reader?

Sumatra has a minimalistic design. Simplicity has a higher priority than a lot of features.

It's small and starts up very fast.

It's designed for portable use: it's just one file with no external dependencies so you can easily run it from external USB drive.

- 作者: Windrift 2007年05月23日, 星期三 14:19  回复(0) |  引用(0) 加入博采

oracle权限

一、权限概述
  权限是用户对一项功能的执行权力。在Oracle中,根据系统管理方式不同,将权限分为系统权限与实体权限两类。系统权限是指是否被授权用户可以连接到数据库上,在数据库中可以进行哪些系统操作。而实体权限是指用户对具体的模式实体(schema)所拥有的权限。这样讲可以有些模糊,举个例子来说:select any table是系统权限,它表示可以查看任何表。而select on table1是实体权限,表示对表table1的查询权限。

二、系统权限列表
  在这里我们列出所有的权限,并将它们分类。这里只列出权限名,有关权限的详细说明请参考oracle官方参考手册。
1.数据库管理员系统权限(数据库实体管理部分)
ADUIT ANY
CREATE ANY CLUSTER
ALTER ANY CLUSTER
DROP ANY CLUSTER
CREATE ANY INDEX
ALTER ANY INDEX
DROP ANY INDEX
GRANT ANY PRIVILEGE
CREATE ANY PROCEDURE
ALTER ANY PROCEDURE
DROP ANY PROCEDURE
EXECUTE ANY PROCEDURE
ALTER ANY ROLE
DROP ANY ROLE
GRANT ANY ROLE
CREATE ANY SEQUENCE
ALTER ANY SEQUENCE
DROP ANY SEQUENCE
SELECT ANY SEQUENCE
CREATE ANY SNAPSHOT
ALTER ANY SNAPSHOT
DROP ANY SNAPSHOT
CREATE ANY SYSNONYM
DROP ANY SYSNONYM
CREATE ANY TABLE
ALTER ANY TABLE
DROP ANY TABLE
LOCK ANY TABLE
COMMENT ANY TABLE
SELECT ANY TABLE
INSERT ANY TABLE
UPDATE ANY TABLE
DELETE ANY TABLE
CREATE ANY TRIGGER
ALTER ANY TRIGGER
DROP ANY TRIGGER
CREATE ANY VIEW
DROP ANY VIEW
CREATE ANY TYPE
DROP ANY TYPE
CREATE ANY LIBRARY
DROP ANY LIBRARY

2.数据库管理系统权限(数据库维护部分)
ALTER DATABASE
CREATE PROFILE
ALTER PROFILE
DROP PROFILE
ALTER RESOURCE COST
CREATE PUBLIC DATABASE LINK
DROP PUBLIC DATABASE LINK
CREATE ROLE
CREATE ROLLBACK SEGMENT
ALTER ROLLBACK SEGMENT
DROP ROLLBACK SEGMENT
ALTER SYSTEM
CREATE TABLESPACE
ALTER TABLESPACE
MANAGE TABLESPACE
ALTER USER
DROP USER
CREATE SESSION
CREATE PUBLIC SYNONYM
DROP PUBLIC SYNONYM
UNLIMITED TABLESPACE
CREATE ROLE
DROP ROLE

3.数据库开发用户系统权限表
CREATE CLUSTER
DROP CLUSTER
CREATE PROCEDURE
DROP PROCEDURE
CREATE DATABASE LINK
CREATE SYSNONYM
DROP SYNONYM
CREATE SEQUENCE
CREATE SNAPSHOTP
CREATE TABLE
CREATE VIEW
UNLIMITED TABLESPACE
CREATE TYPE
CREATE LIBRARY

三、系统权限授权命令的使用
  语法:
GRANT 权限名 TO 用户|角色|PUBLIC
其中,PUBLIC表示将权限赋给数据库中所有的用户
例:赋给用户USER1权限CREATE TABLE的授权命令如下:
SQL>GRANT CREATE TABLE TO USER1;
授权语句还可以增加WITH ADMIN OPTION选项,表示被授权的用户可以将它所得权限赋给其它用户,如:
SQL>GRANT CREATE TABLE,CREATE VIEW TO USER1,USER2 WITH ADMIN OPTION;
若要了解各用户所拥有的系统权限,可以查询数据字典USER_SYS_PRIVS、ROLE_SYS_PRIVS。
若要回收权限,则使用REVOKE命令,如:
SQL>REVOKE CREATE TABLE FROM USER1;

四、实体权限管理
  实体权限是指某一用户对某一特定schema对象的操作权限。
1.实体权限分类
  不同的实体类型有不同的实体权限,如下表

2.实体权限的授命令

  语法如下:
GRANT 实体权限名|ALL TO 用户|角色|PUBLIC
其中,ALL表示实体的所有实体权限。
如:
SQL>GRANT SELECT ON BOOKS_QUTHORS TO USER1;
以下语句用来查询表的实体权限的授权信息:
SQL>SELECT * FROM USER_TAB_PRIVES
若要回收实体权限,使用REVOKE,其语法如下:
REVOKE 实体权限名|ALL ON 实体名 FROM 用户名|角色名|PUBLIC。

- 作者: Windrift 2007年05月22日, 星期二 19:24  回复(2) |  引用(0) 加入博采

提高Excel中VBA的效率
第六课提高Excel中VBA的效率

来源:啄木鸟之家 等级:默认等级
发布于2005-12-30 09:26 被读3940次 【字体:

由于Microsoft Office办公套件的广泛应用,以及该软件版本的不断提升,功能不断完善,在Office办公套件平台上开发出的的VBA应用程序越来越多,而VBA是一种宏语言,在运行速度上有很大的限制。因此VBA编程的方法直接关系到VBA程序运行的效率,本文列举了一些提高VBA程序运行效率的方法。 方法1:尽量使用VBA原有的属性、方法和Worksheet函数 由于Excel对象多达百多个,对象的属性、方法、事件多不胜数,对于初学者来说可能对它们不全部了解,这就产生了编程者经常编写与Excel对象的属性、方法相同功能的VBA代码段,而这些代码段的运行效率显然与Excel对象的属性、方法完成任务的速度相差甚大。例如用Range的属性CurrentRegion来返回Range 对象,该对象代表当前区。(当前区指以任意空白行及空白列的组合为边界的区域)。同样功能的VBA代码需数十行。因此编程前应尽可能多地了解Excel对象的属性、方法。 充分利用Worksheet函数是提高程序运行速度的极度有效的方法。如求平均工资的例子:     For Each c In
      Worksheet(1).Range(″A1:A1000″)
TotalValue = TotalValue + c.Value
Next
AverageValue = TotalValue / Worksheet(1).Range(″A1:A1000″).Rows.Count
而下面代码程序比上面例子快得多:
AverageValue=Application.WorksheetFunction.Average(Worksheets(1).Range(″A1:A1000″))
其它函数如Count,Counta,Countif,Match,Lookup等等,都能代替相同功能的VBA程序代码,提高程序的运行速度。 方法2:尽量减少使用对象引用,尤其在循环中 每一个Excel对象的属性、方法的调用都需要通过OLE接口的一个或多个调用,这些OLE调用都是需要时间的,减少使用对象引用能加快VBA代码的运行。例如 1.使用With语句。
  Workbooks(1).Sheets(1).Range(″A1:A1000″).Font.Name=″Pay″
    Workbooks(1).Sheets(1).Range(″A1:A1000″).Font.FontStyle=″Bold″ ...
则以下语句比上面的快
With Workbooks(1).Sheets(1).Range(″A1:A1000″).Font
.Name = ″Pay″
.FontStyle = ″Bold″
...
End With 2.使用对象变量。
如果你发现一个对象引用被多次使用,则你可以将此对象用Set 设置为对象变量,以减少对对象的访问。如:
Workbooks(1).Sheets(1).Range(″A1″).Value = 100
Workbooks(1).Sheets(1).Range(″A2″).Value = 200
则以下代码比上面的要快:
Set MySheet = Workbooks(1).Sheets(1)
MySheet.Range(″A1″).Value = 100
MySheet.Range(″A2″).Value = 200 3.在循环中要尽量减少对象的访问。
For k = 1 To 1000
Sheets(″Sheet1″).Select
Cells(k,1).Value = Cells(1,1).Value
Next k
则以下代码比上面的要快:
Set TheValue = Cells(1,1).Value
Sheets(″Sheet1″).Select
For k = 1 To 1000
Cells(k,1).Value = TheValue
Next k 方法3:减少对象的激活和选择 如果你的通过录制宏来学习VBA的,则你的VBA程序里一定充满了对象的激活和选择,例如Workbooks(XXX).Activate、Sheets(XXX).Select、Range(XXX).Select等,但事实上大多数情况下这些操作不是必需的。例如 Sheets(″Sheet3″).Select
Range(″A1″).Value = 100
Range(″A2″).Value = 200
可改为:
With Sheets(″Sheet3″)
.Range(″A1″).Value = 100
.Range(″A2″).Value = 200
End With 方法4:关闭屏幕更新 如果你的VBA程序前面三条做得比较差,则关闭屏幕更新是提高VBA程序运行速度的最有效的方法,缩短运行时间2/3左右。关闭屏幕更新的方法:
Application.ScreenUpdate = False
请不要忘记VBA程序运行结束时再将该值设回来:
Application.ScreenUpdate = True 以上是提高VBA运行效率的比较有效的几种方法。

- 作者: Windrift 2007年03月12日, 星期一 13:00  回复(0) |  引用(0) 加入博采

让销售人员乐于参展

让销售人员乐于参展
  
作者:SHEREE R. CURRY 来源: 《世界经理人》杂志 
  
 
  
 
  公司参展的目的有很多,找到商机无限的潜在客户是其中之一,在这方面,销售人员发挥着重要作用。但是一直以来,很多销售人员都不喜欢参加展会,因为他们有诸多顾虑。例如,因为不能出去跑市场而损失一大笔收入,因为要直接与潜在客户面谈,当众被拒的尴尬经历令人不快,等等。所以,运作参展项目的营销人员首先要认识到并处理好销售人员的这些担心,以最终获得后者的合作和支持,从而实现“兄弟同心”,共同打一场漂亮的营销战。

  这是人尽皆知的展会之痛:许多销售人员都不喜欢参加展会,有些人还无所顾忌地宣扬自己的这种想法。我们来看一个案例。利维(Carol Levey)是瑞士艾美表(Maurice Lacroix)的一个高级营销主管。在2002年拉斯维加斯的JCK珠宝展上,利维的参展团里的一个销售人员怒气冲天地和她争吵,而当时她正在接待一个客户。“几百个人在我们的展位前经过,而他却在高声尖叫并咒骂我,只因我不能参加他和一个客户的会谈。”

  这个销售人员显然是有失体统的,但是这个案例说明,没有销售人员的配合,公司的参展目的就会很难实现。

  通过给员工进行参展培训,给他们发放参展事宜指南,召开各种动员会议,你可以把各项工作妥当地分配给他们。但是要让他们为实现公司的参展目标而全心全意地工作,你必须了解他们的需要,并提出有针对性的解决方案。

  关于参展,销售人员经常抱怨的问题有七个,在剖析它们的同时,让我们来看看相应的解决方案是什么。

  顾虑一:蒙受经济损失

  对很多销售人员来说,参加展会往往意味着一件事情:损失销售业绩。那意味着损失佣金、完不成销售任务,最可怕的结局是连工作也丢了。“你把销售人员带出去参展,他们就少了一个星期的时间去完成月度或者季度目标,”某销售和营销咨询公司总裁坎马拉塔(Mike Cammarata)说,“如果展会上的潜在顾客需要销售人员花上3个月,甚至18个月的时间才能与公司做成一笔生意,那么他们对销售人员的意义就不大了。因为等到订单进来时,销售人员可能工作都已经丢了。”

  如果销售人员的收入纯粹是靠佣金来支撑的,他的风险无疑就更大了。“如果一个人没有销售底薪,而是全部靠佣金,把他送到芝加哥去参展一个星期,就无异于让他支付一张1,000美元的账单。”坎马拉塔说。

  对策:支付报酬

  如果你的销售人员担心因为参展而蒙受经济损失,想想如何给他们计酬才能打消他们的这种忧虑。要确定哪种解决方案可以最好地弥补他们的损失,你首先要做的是,找出销售人员的收入是怎样构成的。

  除非你的预算非常宽松,可以给每个销售人员1,000美元,否则你还是要去考虑如何补偿他们的问题。坎马拉塔建议展会经理和销售经理一起商量一个方案,针对每一个潜在客户在展会结束后与公司达成的交易量大小,按照一定的比例给予当时接待对方的销售人员介绍费。

  “其数额应该比后来促成这笔交易的销售人员所拿的佣金更高,”坎马拉塔说,“你要在不扣减完成交易者所得佣金的基础上,再给在展会上负责接待这位潜在客户的销售人员0.5%的佣金。”比如,如果最后达成的销售额是5万美元,展会上的销售人员可以得到250美元。如果这个销售人员能在展会上吸引到四至五个最终与公司达成交易的潜在客户,他就可以把因为外出参展而损失的收入赚回来,甚至赚得更多。

  顾虑二:与原有安排冲突

  在展会中工作,每一个有责任心的销售人员都不免要为两件事情而分散心思:第一是办公室事务,第二是展会上的其他客户。不论你的展位上有多少来访客户,销售人员仍然会打电话回办公室去跟进那边的工作进度,或者去回复堆积如山的电子邮件。他们也需要时间在展馆中会见自己的客户,以及到展馆外面透透气。

  对策:给他们休息时间

  作为展会经理,你要充分认识到时间对于销售人员来说是多么宝贵,你必须给他们安排足够的“休息”时间。让他们能到展位以外的其他地方去和客户会谈,或者和潜在客户去喝喝咖啡,或者去拜访在其他展位上参展的他们自己的客户。

  某销售咨询公司的董事长尼伦伯格(Andrea Nierenberg)建议,销售人员在展位上忙碌了90分钟后,应该让他们休息一下。休息时间为30至45分钟比较合适,这样他们就有时间见客户了。最好还能够提供一个地方,让他们远离嘈杂的展位,去和潜在客户会谈。

  还有一个办法是,让销售团队自行决定日程。有一年,厨房台面制造商Cosentino公司在参加在佛罗里达州奥兰多市举行的国际建筑业展览会时,就是这样做的。Corson公司负责Cosentino在佛罗里达州代顿纳市以外地区的销售。其总裁说:“Cosentino允许我们自己选择工作时间。星期四我在展馆工作了一整天。这样更合理,因为我的办公室离展馆有一个小时的车程。到展馆后,我就全力以赴地工作。”

  顾虑三:有做苦差的感觉

  尽管你信誓旦旦地向销售人员保证,在展会上工作不仅对公司,而且对他们个人都是非常有好处的。但是,销售人员还是会把它看成是一件苦差事。促销品经销商Evigna公司的销售副总裁莫里森(David Morrison)说:“ 他们希望展会上的工作不会太累,并且有被人照顾的感觉,而不是像做苦差那样辛苦。”他们不希望被一些烦琐的小事情搞得焦头烂额。

  对策:给予明星待遇

  当你大张旗鼓地宣扬展会对公司而言是多么重要,希望展位工作人员多做贡献的时候,你也要告诉他们,你会为他们准备好各种条件,使他们工作起来畅通无阻。比如,告诉他们宣传资料放在展位的什么位置,手机号码清单放在何处。然后,给销售人员提供可口的午餐,以免他们在长长的快餐摊位前排队。最重要的是,确保销售人员能够全力以赴地去推销产品,而不用去操心一些细枝末节的东西。

  “我参加过很多展会,经常发现有些展位上没有宣传资料,要么是因为没有及时送到,要么是用完了,而销售人员又不知道怎么和组织者联系,”尼伦伯格说,“你应该派一个行政人员多复印一些资料,同时检查记事本是否还在身边,完成其他的行政事务,就可以避免这种问题的发生。”给销售人员一点额外的好处也可以激励他们的积极性。“把短途旅游作为一个奖励,”VNUExpositions

  公司的副总裁库克(Bill Cooke)说,“如果展会是在一个旅游热点城市举行,比如纽约、奥兰多、新奥尔良或者旧金山,在展会开始之前,给他们两到三天的时间去市区旅游,欣赏美景。或者安排他们在展会结束后留下来住几天,把他们的配偶也请过来。”库克还建议给他们一笔出差津贴,足够让他们在这段日子里轻轻松松地过好每一天。

  顾虑四:展会现场沉闷无比

  有时候,销售人员感觉展会非常沉闷,觉得在展位上走来走去是浪费时间。对有些人而言,这是因为他们不想呆在那。但是,如果你没有在现场创造一个激情洋溢的环境或者没有给展位工作人员提供适当的培训,这样的抱怨无可厚非。某销售管理培训公司CEO布鲁克斯(Bill Brooks)说:“很多销售人员不知道在展会上做什么,因为他们没有接受过正规的培训。”

  对策:打破工作的单调性

  AccuWeather是一家专门为各家电视台提供天气预报信息的公司。在参加展会前,公司的销售团队会帮助做好准备工作,制作在展会上要播放的录像资料。“最重要的是要让销售人员产生主人翁意识,并熟悉展位上的所有资料,这样他们才会更加热情地向客户介绍。”该公司销售团队的主管雷尼(Leigh Rainey)说。

  “在其他我工作过的公司,销售团队只是在展前拿到一份台词来背诵,”雷尼说,“结果,销售团队要么毫无兴趣,要么无法解释产品展示资料所要表达的精妙之处。”

  为了打破展位上工作的单调性,布鲁克斯建议实行销售人员工作职责轮换体系。“让一个人做迎宾,一个人发资料,一个人负责展位物品。让他们不断地轮换角色,”布鲁克斯说,“他们需要不同的体验,否则会觉得一天的工作既漫长又无聊。”

  此外,充分利用销售人员喜欢竞争的天性,以比赛的形式来激励他们更加积极地工作。尼伦伯格建议每天评选一个在与潜在客户交流方面表现最佳的员工出来。“让他们在每天的早会上或者晚餐时,和整个团队一起分享成功的故事,”他说,“故事最精彩者将获得一份奖励,比如一张礼品券、一个新记事簿,或者一个掌上电脑。展会结束的时候,成功故事讲述者中的前三名可以获得一份额外的奖励,比如双人旅行凭单,或者和公司销售总裁或者销售副总裁一起共进午餐或晚餐的机会。”

  除了个人竞赛,你还可以举行团队竞赛。“我见过的最有效的奖励是,如果团队获得了一定数量的潜在客户,每个成员都将获得一张去某高档饭店用餐的凭证,还可以携带一位客人,”布鲁克斯说,“这样你们就是作为一个团队在工作了,而不是一个人单枪匹马地工作。”想办法让销售人员知道竞争的激烈性。某咨询公司的总裁盖奇(Bill Gager)建议说:“如果你的展位后面有一个小房间的话,可以让人把比赛的结果贴在墙壁上,这样每个人都可以看见它。最好能够随时更新。”

 展会经理如何赢得销售经理的支持

  赢得了销售经理们的支持,惟其马首是瞻的销售人员自然也会给予你支持。要和销售团队中的高层交上朋友并对其施加影响力,有四个诀窍。

  请求合作而不是要求合作。展会经理不要见怪,但是一般来说,你没有权力去指挥销售部门,因为展会经理的汇报对象通常是营销部,而销售经理的汇报对象是公司总裁。尽管如此,在涉及到展会事宜时,许多展会经理总是试图施展自己的权威,结果却惨不忍睹。“只有为数很少的展会经理懂得用商量的口气对销售经理说,‘你希望派你部门的谁参加展会呢?’或者,‘我准备在展会开始前的那个周末给展位工作人员做一次培训,什么时段对你和你的下属最合适呢?’”某销售和营销咨询公司总裁坎马拉塔说。

  向销售管理层推销你的计划。销售经理总是被销售额和利润所激励。他们需要对自己的销售指标负责,而他们的业绩是根据下面的销售人员的成绩来衡量的。话已说得够明白了。那么,销售经理为什么要把销售人员从市场上抽调出来,让他们帮你看一星期的展位呢?

  告诉销售经理,作为展会经理,你的工作就是把公司和产品用最赏心悦目的方式展示给有兴趣的客户,从而吸引优质、合格的潜在客户。告诉销售经理,只要他们稍微给点支持,你就可以帮助销售部实现目标。在沟通中,多用“我们”这个词汇,而不是“你和我”,因为事实上你的成功也有赖于参加展会的销售人员的成功,要看他们能否把潜在客户变成真正的客户。

  还有一个策略,那就是问问销售经理:“除了挖掘潜在客户外,你在展会上能否得到其他益处?”比如,用参加展会替代一次销售培训,却不用花成本。

  一旦销售管理层接受了你的观点,接下来你要做的就是确保他们向下属传达了他们对你的支持意愿。请销售经理发邮件给销售人员,明确说明:“我支持克伦作为展会经理的工作,我希望你们都全力配合。”

  在展会的早期计划阶段,就邀请销售管理层参与进来。展会相当于公司的一个缩影。所以,在运作参展项目时,应该像运作公司一样,各个部门之间要互相配合。

  请销售经理参加所有与制定展会目标有关的会议。他们可以给你提供一些有价值的见解,包括应该采用什么样的销售战略,展前推广活动应该针对哪些客户进行。如果销售经理们觉得自己能参与到决策过程中,他们会对你的请求更加配合。

  及时致谢。“一般情况下,销售部门在展会结束后收到的反馈非常少,”坎马拉塔说。他们心里都在想:“告诉我们,我们在展会上的表现如何?”坎马拉塔建议展会经理给每一个参加展会的销售人员发一封感谢信。比如,“亲爱的鲍勃,非常感谢你的支持,你在展会中抓住了50个潜在客户。”此外,还要在信中说明,作为一个团队,你们大家在展会中取得的成绩,包括所吸引到的潜在客户的总数、新闻覆盖率,以及有没有获得最佳展览奖等。

  展会结束后一两个月,统计一下投资回报率(ROI)。有多少个潜在客户与公司达成了交易?比如,“亲爱的鲍勃,由于你的贡献,我们接到了15笔业务。”不要忘了把所有的结果都向高层领导汇报。让他们知道,你把自己成功的一大半都归功于销售部门。

  顾虑五:潜在客户质量欠佳

  当提到要向客户做产品介绍时,销售人员主要担心两个问题:第一,潜在客户的质量—他们真的对产品有兴趣吗?他们有钱购买吗?第二,如何在展馆内找到潜在客户。销售协调员罗泽说:“营销部门的工作是让销售更加容易开展,销售流程更加高效。我们要知道营销部门已经通过电子邮件和其他方法,尽到了自己的职责。”

  对策:让他们看数据

  向销售人员演示你计划如何吸引高质量的潜在客户到展位上来。你需要证明自己已经发送了大量的邮件,或者已经做好了一个独一无二的方案吸引客户到展位来。罗泽说,其中一个方法就是把销售团队纳入到营销资料的发送名单中。“你应该把销售人员当成是自己的客户一样,向他们推销你的营销战略。”

  康索特(Chris Consorte)是直销与整合营销公司Integrated Direct的合伙人,还是纽约长岛大学的营销老师。他建议,定制给潜在客户发送的展前营销邮件,把销售经理和销售人员作为展会联系人介绍给潜在客户,这样他们和潜在客户就联系起来了。康索特说:“当你向潜在客户做展前推介时,销售人员都将积极主动地参与进来。而且,这能让他们兴奋起来。他们会认为万一有一个客户前来找他们,而他们不在展位上,那自己真是愚蠢到底。即使展位的人流量不大,他们也不会离开。”

  顾虑六:常被客户拒绝

  一个经验丰富的参展商说,他给销售人员付报酬并不只是为了让他们去促成交易,而是希望他们能勇于接受客户的拒绝。由于销售人员通常都是通过电话联系客户后才与之见面,他们并不习惯在没有任何事先联系的情况下,就和陌生人面对面地交流。所以,在展会上直接和潜在客户见面,可能会让他们觉得心虚。

  “有很多人和我说过他们在走廊上和潜在客户打招呼却被拒的不快经历,”盖奇说,“有一次,一个销售员向潜在客户递上名片,而对方却当着他的面撕掉名片,还说‘你别想我和你做生意’。”

  对策:奖励勇于接受被拒的行为

  由于销售人员经常会遭到拒绝,你应该不断地鼓励他们,让他们保持乐观的精神。盖奇说其中一个方法是“给承受了最可怕的经历的人奖励”。每天展会结束时,让销售人员一起分享最难堪的被拒经历,给承受了最大羞辱的那个人发奖。盖奇建议用一个小小的奖励来安抚他们的情绪,比如一张价值25美元的购物礼券。“这样一来,即使被拒也不是完全没有收获,”他说,“销售人员就更容易忍受拒绝了。”

  顾虑七:工作不被认可

  销售人员经常认为自己不被认可,或者不是展览项目团队中的重要成员。他们希望自己是风头人物,举手抬足都能吸别人的注意。如果他们觉得自己被忽略了,他们就不想参加展会了。

  对策:满足他们的自尊心

  让公司高层来发挥一些作用。不论是一段CEO讲话的录像,还是让一个销售冠军和总裁共进晚餐,这样做的目的是确保销售人员知道他们的努力将得到最高领导的认可。

  “有些东西必须从最高领导层那下传才有意义,”Trade Show Coach公司的总裁,展会顾问弗里德曼(Susan Friedmann)说,“即使只是一张写着‘谢谢你’的纸条、一份公司内部简报,或者一封内部电子邮件,都是为了让销售人员知道他们的工作会得到认可。”

  弗里德曼还建议以颁发证书的形式,来表达对销售人员的赞赏。她说:“人们喜欢在自家的墙上悬挂证书。对有些人来说,这很有意义。”

  让销售团队参与到整个过程中来,包括展会的整个计划过程和给展会最佳工作人员颁奖的过程。同时让他们知道他们的意见有多么地重要。弗里德曼建议让销售团队来决定谁可以获得最佳展位工作人员奖。

  你也可以在另一个不同的层次上满足销售人员的自尊心。“让销售人员以某个产品或者销售技巧的专家的身份开办研讨会,”布鲁克斯说,“把研讨会作为收集名片的好机会。”如果有200人参加你的研讨会,这意味着你将获得大量的潜在客户。“就我而言,如果没有机会组织研讨会,我就不会参加展会,”布鲁克斯说,“我从研讨会上得到的潜在客户比呆在展位上得到的多得多。”

  原文经许可摘自Exhibitor杂志2005年4月期。该杂志社位于美国明尼苏达州罗彻斯特市。Exhibitor杂志登记2005年版权,(888)235-6155,www.ExhibitorOnline.com。黄德文译。Sheree R. Curry是明尼苏达州Maple Grove的一名自由撰稿人。

- 作者: Windrift 2007年03月6日, 星期二 18:41  回复(0) |  引用(0) 加入博采

决策始于远见

决策始于远见
  
作者:LUDA KOPEIKINA 来源: 《世界经理人》杂志 
  
 
  
 
  对领导者来说,做决策的过程就是一个冒险的判断过程。你要从诸多备选方案中做出选择(它是你对未来的一种预测),然后凭借极大的勇气向组织内外的人宣布自己的预测。如何让这一过程的冒险系数实现最小化?作者建议领导者通过实践和评估以往决策的成效,来锤炼自己的远见能力,借助远见做出正确的决策。其中,分析方案灵敏度和发掘最匹配方案是两个最有效的方法。

  欲穷千里目,更上一层楼。做决策是冒险的判断过程,涉及的一个重要方面就是利用现有知识对未来进行预测,这就是我们所说的“远见能力”。高效的领导者都具有出色的远见能力。

  一旦你做出某种决策和选择,就意味着你向世界宣布了你对未来的某种预测。也许只有你做出了这种预测,也许这种预测是错误的。表明自己的立场是需要勇气的,如果决策的不可逆转性越强,你需要的勇气就越多。

  要做出某种决策,领导者还需要坚信自己的选择对自己和企业而言都是正确的,他必须从内心深处认同自己的选择。如果缺乏这种自信,领导者就不会具有执行决策的勇气。

  远见能力的关键在于能够发现未来最有可能朝哪发展。此外,它还能给你带来其他好处。比如,你可以识别关键的里程碑事件,预测潜在的环境变化,并识别和预测成功道路上的阻碍因素。这种预测很大程度上取决于领导者的直觉。领导者可以通过实践和评估以往决策的成效来锤炼自己的远见能力。

  领导需要远见能力

  企业的管理者通常在遇到下列情况时会运用自己的远见能力:

  •当面临的不确定性极高时

  •当没有什么先例可以借鉴时

  •当难以对变数进行科学预测时

  •当客观事实有限时

  •当客观事实未能指明应选择的方向是什么时

  •当分析数据的作用有限时

  •当供选择的解决方案看上去都有道理,且都有很好的论据支持时

  •当必须在有限的时间内做出正确的决策时

  •当与人谈判时或要做出人事决策时

  企业的大多数战略决策都是在上述一种或多种情形下做出的,因此要求企业领导者利用自己的直觉和远见能力。在下面的例子中,作为电信公司CEO的保罗需要在有限的时间内做出正确的决策,而市场是否能走出低迷状态并不明朗,并且,分析数据的作用有限。

  保罗公司的一些经营活动是受政府管制的。一年半以前,公司决定扩张到一些新的区域,并开始向政府申请扩张许可。政府的批复迟迟没有下来,而市场竞争日益激烈。以前,公司可以通过提高产品价格来平衡投资成本,但在当前的环境下,公司很难这样做。

  另一方面,公司刚刚对一项新建工厂的计划进行了全面评估。有人建议投资这项计划,以便提高服务的可靠性。据估计,其成本大概是1亿美元。

  这时候,政府颁布了一项准许公司进入新区域的条例。不过对公司而言,这个时机并不好。因为电信行业正处于衰退期的中期,市场恢复缓慢,同时公司正再次面临裁员。更为糟糕的是,政府此次颁发的条例对公司的投资行为设定了期限。

  保罗意识到他只有两个选择:其一是立即进行投资,其二是与政府协商延长投资期限。

  任何一个选择都不理想。对保罗而言,立即投资是不可行的,因为公司正面临裁员。推迟投资又会把服务可靠性这个问题推上风口浪尖。

  处在这样的困境下,领导者常采用以下方法:或是评估利弊,或是用排除法决定采用哪一方案,或是基于参考点对各备选方案进行评估,或是平衡得失后做出决定。当你要从多个角度对各种决策方案进行评估时,这些分析方法非常有效。它不仅能指引你做出选择,对其进行合理解释,还能给你提供信息,指导你如何针对它采取行动。

  如果某个选择看起来很合理,但你对它的感觉并非如此,你可能需要进行深入挖掘,以弄清楚你为什么会有这种感觉。有两种方法可以帮助你做到这一点:分析方案灵敏度和发掘最匹配方案。

  两种方法提升远见能力

  方法一:分析方案灵敏度

  这种方法包括8个步骤,每分析一种方案,这些步骤就要依次进行一次。

  1、保持头脑清醒,以便激发洞察力,理清脉络,明确方案利弊。

  2、识别方案中最不确定的因素。

  3、想象一下方案付诸实施之后,最有可能出现的状况。想象一下,从你做出决定启用某解决方案的那一刻起,事情将会朝什么方向发展。你如何就它与相关人员进行沟通?哪些人与之相关?接着将会发生什么?事情将会如何发展(注意那些首先进入你大脑的想法)?将会有哪些里程碑事件(即方案实施过程中将会出现的关键点)?如何应对最不确定的因素?

  不必专注于哪种情况的可能性具体有多少,相反,你只需要专注于那些自然而然地进入你大脑的对于未来的预测。

  4、评估最糟糕的情况。问问自己:如果那项决策对业务产生消极影响,最糟糕的情况将会是怎样?评估你的反应和接受程度。一旦真的出现最糟糕的情况,你是否有能力应对?如果这种情况可能出现,就应做好准备应对它。

  5、找出导致方案失败的原因。注意关键不确定因素是如何导致最糟糕情况出现的。同时,罗列其他原因。是什么原因直接导致最糟糕情况出现的?不要纠缠于对结果的研究,只要识别那些导致方案失败的问题。

  在做好准备接受最糟糕的情况之后,问问自己:为避免出现这种局面,我应如何对方案进行改进?为避免出现导致方案失败的因素,应该采取哪些措施?

  再次充分发挥你的想象力,认真思考应该实施什么样的有创意的方案,来解决在关键转折点出现的风险。

  6、评估最好的情况。问问自己:如果选择了这个方案,最好的结果是什么?想象一下最好的情况。注意那些自然而然地进入你大脑的事物,注意那些里程碑事件。然后在脑海里重放这些画面,描绘其中的具体细节,并对方案进行完善。

  7、根据目标和主要约束因素对方案进行评估。你也许会对自己的反应感到吃惊。比如,“这个方案并不能很好地解决这个问题,但我喜欢它。实际上,我认为这是个正确的选择。”注意不要忽视这些信号,不要试图自圆其说。关注这些信号,并认真思考为什么自己会有这样的想法。

  8、寻求调整方案的办法。问问自己:怎样才能对方案进行调整,使之可以更顺利地交付目标成果,并更好地克服主要约束因素?考虑从以下几个方面对方案进行调整:

  关注方案中的积极因素。你能否详述这些积极因素,使之满足影响决策的要素?

  或者反其道而行,关注方案中不协调的因素。再思考其他方案,看看是否某个方案不包含这些不协调的因素。如果确有某个方案没有这些不协调的因素,你能否将这个方案与前一种方案进行有效结合,以解决问题?

  考虑改变方案的执行力度和实施范围,以便应对更多的约束因素。

  下面有一个有趣的例子,我们可以从中看到领导者是如何成功地分析方案灵敏度的。

  斯坦利是上市软件公司RC的CEO,这家公司的资产达2亿美元。在过去六个月中,它的两大竞争对手A公司和B公司已向它发出了收购建议。事情已经到了摊牌阶段,公司必须从这两家中选择一个买家。A和B提出的竞购价相近,且按照行业标准来说都是“非常好”的出价。

  其中A建议以换股的方式收购RC。与B相比,A的规模较小,赢利能力较弱,但它也是一家上市公司,其市值是RC的1.7倍。在过去半年中,A的股价已有所增长。尽管如此,斯坦利认为A在过去三年中的业绩并不佳,只是最近才开始赢利,并在过去几个季度持续赢利。

  B的资产达8亿美元,是一家私人公司,由一群金融人士所有。这些人擅长管理不良不动产,但缺乏从事软件行业的知识。在过去的18个月中,他们已经收购了五家公司。

  斯坦利也可以选择继续经营RC。RC已经收购了两家公司,并有足够的股本和现金来收购更多的公司。RC的业绩良好,赢利能力强,且在业界有良好的口碑。斯坦利面临的选择是:是继续经营RC,还是接受A公司或B公司的收购?

  当然,困难之一在于从股东的角度对现金收购和股权交换进行比较。令情况变得更为复杂的是,两大竞购者各有千秋。如果市场前景良好,以股权交换的方式完成收购,意味着RC获得的总价值可能更高。不过,以现金收购可以使股东立即获得较好的回报。

  困难之二在于董事会有不同的意见。由于看到了公司管理团队的才能和过去在收购别的公司时取得的成功,董事会也想继续经营RC。然而,斯坦利考虑的主要是发生在行业里的一些变化,即市场越来越整合。他认为这个行业的路子会越来越难走。

  现金收购似乎更具吸引力,它可以使股东立即获得现金,但斯坦利不确定股东会有何反应。他们是感到高兴,还是会抱怨管理层没有接受A的收购建议(股权交换可能意味着更高的获利潜力)?不过,如果接受现金收购,股东可以明确知道每股市值,这对成功做出决策是一个帮助。

  实际上,第一种方案(即接受A公司的换股建议)的最大变数,在于合股后股票的增长潜力。斯坦利担心A公司的股价被高估了。况且,两家公司合二为一后同样会受到市场趋势的影响,前景同样不明朗。股东以后会有更好的现金回报吗?选择A公司有较大的风险,股东们甚至可能得不到斯坦利在做出这个决策时为其设定的回报。

  董事会成员都把宝押在了公司现有管理团队(斯坦利是其中一员)的知识和经验上。过去,这个管理团队一直引领着公司朝着很好的方向发展。不过,斯坦利担心的是市场趋势,特别是随着强大竞争者的出现,市场竞争已经越来越激烈了。如果选择第三种方案,即继续经营RC,就意味着要收购更多的公司。但是,现在可供收购的公司越来越少,收购的成本也越来越高。

  在认真审视了当前的形势和各种方案之后,斯担利意识到自己并不看好股权交换的建议,他对第三种方案(即继续经营RC)的感觉甚至更糟。

  在进行方案灵敏度分析之后,斯坦利有了一个清晰的决定。他向董事会推荐了第二种方案,即接受B公司的现金收购建议。

  如果董事会没有不同的意见,斯坦利面对的情况就会简单得多。导致分歧产生的原因在于,董事会成员和斯坦利根据各种方案的相关信息,对投资回报做出了不同的预测。

  如果有一天,你需要面对诸多不稳定因素做出抉择,你将不得不冒险。而且,你冒险做出的选择将向人们揭示你重视的是什么。

   方法二:发掘最匹配方案。

  这种方法强调情绪的重要性。当你对某个方案产生一种兴奋或坚定的感觉时,这种情绪会促使你完全接受这一方案,并确保它实施成功。这种方法包括以下步骤:

  1、保持头脑清醒。

  2、了解所有的方案。你也可以给每种方案打上标签或设想在具体哪种场景下应用哪种方案,然后将它们一一排列在你面前。

  3、依次扫视每种方案,并评估自己的反应。你不需要认真思考这些方案。通常,你会对其中的一个产生异样的感觉,并且你会注意到这种兴奋的感觉越来越高涨。如果你对某种方案产生了这种感觉,它很可能就是你要的那种。

  4、如果某一方案给你的感觉比较突出,问问自己:“这是我想要的吗?”理清你的想法,然后问问自己:“我对它感到满意吗?”

  5、对自己说:“我将做出一个对自己和其他相关各方都适合的决策。”

  这种简单的方法有可能产生惊人的效果。请看下面的例子。

  鲍勃是一家大型制造公司的CEO。公司决定向南美市场扩张,因为根据市场调研数据,如果扩张得当,公司就有机会先于竞争对手进入南美市场,并取得较大的市场份额。

  鲍勃有多方面的考量。一方面,他想有效地对南美市场进行大量投资,并使之为公司带来最大的发展潜力和最大的市场份额。另一方面,他也意识到时间极为紧迫。虽然目前公司的产品在南美市场遭遇的竞争并不激烈,但这种状况不会持续多久。因此,公司需要尽快采取行动。

  鲍勃的团队提出了两种投资方案:第一种方案是进行小额投资,从美国把产品销往南美各国;第二种方案是进行大型投资,在阿根廷建立生产厂,并在南美的几个主要国家设立新的销售队伍。鲍勃正在考虑他们提出的第二种方案,即在三个南美国家设立销售处。

  在进行方案灵敏度分析之后,考虑到关键的不确定因素,鲍勃意识到两种方案都不能很好地实现自己的决策目标。

  虽然鲍勃也认为在一至四个国家设立销售处,有助于公司在控制成本的同时实现业务增长(这是他之前要求方案制定团队一定要考虑的参数),然而,在他设想采用这种方案后出现的最佳情况时,他与巴西的一位顾客进行了交谈。

  “当我正在脑海中思索最佳结果时,这位顾客告诉我,他对与他合作的我们公司的员工很满意,对我们的产品质量也满意。不过,他强调他会一直对我们公司交付产品的速度和灵活性进行评估,因为这对他的公司的正常运作至关重要。这使我突然意识到,即使我们在第二种方案中考虑了灵活的产品交付措施,也很难达到他的期望。”

  鲍勃从一位巴西顾客的角度出发,立即意识到之前制定的库存产品的方案,并不能满足这位顾客的需求。通常,要知道做某件事的方法,你得先把它做一遍。

  鲍勃对方案进行了调整,使之符合自己的决策目标。他意识到自己喜欢第二种方案的主要思路,即公司能够及时接触到在南美的客户,并与之达成交易。但问题在于,这种方案并不能满足顾客在交货方面的要求。公司可以通过在当地建立新的生产厂来解决这个问题,但这需要一笔很大的投资,而鲍勃目前并不愿意这样做。

  经过慎重考虑后,鲍勃提出了一种新的方案:公司应该在南美建立产品组装厂,而不是生产厂,但依然会照第二种方案在一到四个国家设立销售处。鲍勃回忆到:“这种方案非常简单!不知道自己以前为什么没有想出来。也许是因为以前公司从没有这样做过。我们的一贯做法是不断建新厂。”

  在运用第二种方法之后(发掘最匹配方案),鲍勃深信新的方案是最合适的。

  企业管理者的职责就是做出决策。不过,他们做出的大多数决策并不令人满意或并不受欢迎。要做出有效的决策,他们需要很大的勇气来坚持自己的立场。

  原文经位于美国新泽西Upper Saddle River的Pearson Education, Inc,许可,摘自Luda Kopeikina所著The Right Decision Every Time: How to Reach Perfect Clarity on Tough Decisions一书的第一版(ISBN号码为:0-13-186262-6)。阿桑译。Luda Kopeikina是麻省理工学院斯隆管理学院(MIT Sloan School of Management)的客座教授和Noventra Corporation公司的CEO。

- 作者: Windrift 2007年03月6日, 星期二 17:50  回复(0) |  引用(0) 加入博采

For循环的flowchart

前阵子一个同事问画flowchart时,for循环的时候怎么画。居然我也不知道。

今天偶然找到一个eclipse插件可以把代码转化成flowchart.

于是试了一下下面的代码:

 public void fuc() {
  int i = 0;
  i++;
  for(i=0; i<3; i++){
   i++;
  }
  i++;
 }

flowchart如下:

PS. eclipse 插件是Flowchart4j(http://flowchart4j.codeswat.com/

- 作者: Windrift 2007年02月26日, 星期一 15:08  回复(0) |  引用(0) 加入博采

hibernate could not execute query 解决方法

Hibernate查询时候的问题。
莫名其妙地报如下的错误,
org.hibernate.exception.GenericJDBCException: could not execute query

最后把mysql的驱动程序 从 mysql-connector-java-3.2.0-alpha改成mysql-connector-java-5.0.4就可以了。
开源软件的版本问题真是害死人!

- 作者: Windrift--徐为贵 2007年01月31日, 星期三 13:25  回复(6) |  引用(0) 加入博采