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

2012年1月14日

2012.09.19 office for mac 2011更新到14.2.4版本,最大的变化就是解决了office在pro retina中的显示问题。

 

检查并安装更新到14.2.4之后,我的retina中office的显示完全OK了.

这是office for mac team的官方声明链接link

这是网上关于升级到14.2.4之后仍然无效的解决方法的链接link2.

 

posted @ 2012-10-13 09:53 timelyxyz 阅读(225) | 评论 (0)编辑 收藏

并集:Set1 union Set2

交集:Set1 intersect Set2

posted @ 2012-10-11 21:15 timelyxyz 阅读(234) | 评论 (0)编辑 收藏

正确语句
1 update jytuser set userid=(select member.userid from member where member.id=jytuser.owner_id)

 

有2个易错点: 

1)表自关联好像行不通。我猜想会不会和查询时建立的索引更改有关。

2)这种写法postgres不支持

1 update jytuser,member set jytuser.userid=member.userid where jytuser.owner_id=jmember.id and jytuser.userid=0;

报错如下:

 

posted @ 2012-10-10 11:36 timelyxyz 阅读(197) | 评论 (0)编辑 收藏

最近在做数据同步的项目,过程中接触了spring+jdbc的开发模式(IDE: sts),然后开始使用maven管理项目。目前碰到的一个问题是在本地添加一个repository,加的是用于连接sqlserver的驱动包sqljdbc4.jar。我在很多maven仓库里都没找到这个jar,只能手动的下载来,然后添加到本地仓库里。发现这个包好像很多人没有添加成功,我在这里找到了解决方法http://claude.betancourt.us/add-microsoft-sql-jdbc-driver-to-maven/

主要步骤如下:

1. 本地下载sqljdbc4.jar

2. 解压到本地文件夹中,并找到sqljdbc4.jar路径

3. 打开命令窗口,执行以下语句(前提:先配置好maven环境变量)

1 C:\Users\nbxyz>mvn install:install-file -Dfile=e:\sqljdbc4.jar -DgroupId=com.microsoft.sqlserver -DartifactId=sqljdbc4 -Dversion=4.0 -Dpackaging=jar

4."BUILD SUCCESS"即添加成功



生成的pom文件如下

1 <?xml version="1.0" encoding="UTF-8"?>
2 <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
4   <modelVersion>4.0.0</modelVersion>
5   <groupId>com.microsoft.sqlserver</groupId>
6   <artifactId>sqljdbc4</artifactId>
7   <version>4.0</version>
8   <description>POM was created from install:install-file</description>
9 </project>

 

posted @ 2012-10-09 14:40 timelyxyz 阅读(305) | 评论 (0)编辑 收藏

 1     private static Map<String, Long> getPictureHeightAndWidthMap(String picUrl) {
 2         Map<String, Long> map = new HashMap();
 3         try {
 4             URL url = new URL(picUrl);
 5             HttpURLConnection connection = (HttpURLConnection) url
 6                     .openConnection();
 7             DataInputStream in = new DataInputStream(
 8                     connection.getInputStream());
 9             BufferedImage image = ImageIO.read(in);
10             map.put("w", image.getWidth() * 1L);
11             map.put("h", image.getHeight() * 1L);
12             connection.disconnect();
13             in.close();
14         } catch (IOException e) {
15             e.printStackTrace();
16         }
17         return map;
18     }
19 
20     public static Long getHeight(String picUrl) {
21         Map<String, Long> map = getPictureHeightAndWidthMap(picUrl);
22         return null == map.get("h") ? 0 : map.get("h");
23     }
24 
25     public static Long getWidth(String picUrl) {
26         Map<String, Long> map = getPictureHeightAndWidthMap(picUrl);
27         return null == map.get("w") ? 0 : map.get("w");
28     }

posted @ 2012-09-26 09:34 timelyxyz 阅读(411) | 评论 (0)编辑 收藏

Do "Show package contents" on the Eclipse.app.  
Edit Contents/Info.plist.  
Just above   

</dict>
</plist>

Place this:  

<key>NSHighResolutionCapable</key> 
<true/>

Then, log out or make a copy of the app so that OSX will notice the change.  Now, the info window will not show "Open in Low Resolution" as checked.  Launch Eclipse and enjoy your new retina awesomeness.

solution from https://bugs.eclipse.org/bugs/show_bug.cgi?id=382972

同样的方法也可以解决的软件有:Spring tool suites.

posted @ 2012-09-22 18:27 timelyxyz 阅读(321) | 评论 (0)编辑 收藏

1 首先查看PATH
命令:$PATH  
 
2 如何设置PATH
命令:echo "export PATH=xxxxxx:$PATH" >> ~/.bash_profile
解释:把"export PATH=xxxxxx:$PATH"输出打印到~/.bash_profile中去。
 
3 Unix知识补充:~/.bash_profile介绍
mac和linux终端一般用bash来进行解析。当bash在读完了整体环境变量的/etc/profile并借此调用其他配置文件后,接下来则是会读取用户自定义的个人配置文件。bash读取的文件总共有三种:
~/.bash_profile   ~/.bash_login    ~/.profile
其实bash再启动是只读上面文件的一个,而读取的顺序则是依照上面的顺序。也就是说读到bash_profile就不读后面的了,如果bash_profile不存在,后面的才能有机会。
让我们来看看bash_profile里面有什么内容:
命令:cat ~/.bash_profile 
最后重启你的终端就会有刚才设置的全局变量了。 
 【2012.02.28更新】
最直观的方法是:
cd ~
open .bash_profile
这时候就会直接用记事本程序打开这个配置文件,比在终端里那么设置要简单直观多了。
要注意一点那就是配置文件里的变量是会覆盖的,比如
export PATH=1
export PATH=2
那么后面的2会把前面的1覆盖的。

posted @ 2012-09-22 17:14 timelyxyz 阅读(474) | 评论 (0)编辑 收藏

hibernate默认的,以及网络上的主流支持left join的表关系是one-to-many的,可以使用left join fetch(需要配置lazy="true" fetch="select"),也可以使用Criteria或者CriteriaQuery(link1 link2)来进行查询。

 

对于many-to-one,首先我们先建两个model:

 

@Entity
public class ClassOne {
public String id;
public boolean isDeleted;  
}

@Entity

public class ClassTwo {
public String id; 
@ManyToOne
public ClassOne classOne; // 父表
public boolean isDeleted;  
}

 目前有两个需求:

 

(1)select a.id,b.id from ClassTwo as b left join b.classOne as a;【正确,获取到了所有ClassOne表的数据项】

(2)select a.id,count(b.id) from ClassTwo as b left join b.classOne as a where a.isDeleted=false and b.isDeleted=false group by a.id;【count结果中把0的滤去了,没达到我的需求】 

对于第二种,目前我还没找到具体的解决方法,仍需研究。 

 

posted @ 2012-09-18 13:47 timelyxyz 阅读(196) | 评论 (0)编辑 收藏

hi

outer-join     fetch     lazy         主键表class     检索策略         检索方式
true/false/auto     select     false         true/false     立即检索(n+1次查询)     所有
-         -     no-proxy/proxy     true         延迟检索         所有
-         -     -         false         立即检索(n+1次查询)     所有
-         join     false         true/false     inner join         QBC,get()/load()
-         -     -         -         立即检索(n+1次查询)     HQL,NativeSQL
-         join     no-proxy/proxy     false         inner join         QBC,get()/load()
-         -     -         -         立即检索(n+1次查询)     HQL,NativeSQL
-         -     -         true         inner join         QBC,get()/load()
-         -     -         -         延迟检索




String hql = "select t,count(tp) from ContentTag_Post as tp     left join fetch tp.tag as t"
    + " where tp.tag=t and t.owner.id=? "
    + " and tp.isDeleted=false and t.isDeleted=false "
    + " group by t order by t.createTime desc ";


        String hql = "select t,count(tp) from ContentTag as t left join ContentTag_Post as tp "
                + " where t.owner.id=? and t=tp.tag "
                + " and t.isDeleted=false and tp.isDeleted=false "
                + " group by t order by t.createTime desc ";

 Path expected for join!
2012-08-22 12:47:37 [ERROR]  Invalid path: 'tp.tag'
right-hand operand of a binary operator was null
<AST>:0:0: unexpected end of subtree
left-hand operand of a binary operator was null


select查询 join查询

@LazyToOne用法
http://docs.jboss.org/hibernate/annotations/3.4/reference/zh_cn/html/entity.html
Java中的transient,volatile和strictfp关键字
http://www.iteye.com/topic/52957
transient
  Java语言的关键字,用来表示一个域不是该对象串行化的一部分。当一个对象被串行化的时候,transient型变量的值不包括在串行化的表示中,然而非transient型的变量是被包括进去的


class A implements Serializable {
 private String name;
 transient private String address;
}

那么你在串行化(IO流等)A类时 给它的name和address属性赋值,那么你在提取A时,拿到了name属性,但是却拿不到address属性。




lazy是延时的意思,如果lazy=true,那么就是说数据库中关联子表的信息在hibernate容器启动的时候不会加载,而是在你真正的访问到字表非标识字段的时候,才会去加载。
反之,如果lazy=false的话,就是说,子表的信息会同主表信息同时加载。
一般用只有完全用到子表信息的时候,才会lazy=false

join 查询的时候,是用以条语句查处所有记录,包括关联表记录,select查出的是N+1条记录,两个都是差不多的,但是如果用了lazy=true,延迟加载的话,select在查询时只会查出主表记录,也就是1,如果其他地方也用到了数据,此时就会自动在执行查询,查出N,可以降低内存消耗 .还有,hibernate是的session是轻量级的,创建和销毁都不花很多资源,查询数据也很快,这里fetch主要起这个作用    

Path expected for join! unexpected end of subtree

posted @ 2012-09-04 10:55 timelyxyz 阅读(143) | 评论 (0)编辑 收藏

使用条件如下:

a left join  b

a must be b's parent

posted @ 2012-07-24 11:37 timelyxyz 阅读(385) | 评论 (0)编辑 收藏

突然抛了一个concurrentModificationException错误,Iterator的一个基本概念没有掌握导致的这个错误,就是在Iterator的实现类。比如Hashtable里面的内部类
 private class Enumerator<T> implements Enumeration<T>, Iterator<T>

会在next,或者remove的时候检查当前集合是否会在修改状态,如果是的话,就会抛出 ConcurrentModificationException,而他自己remove则是使用了同步的方法,而且同步了modCount;expectedModCount;

 1 public T next() {
 2      if (modCount != expectedModCount)
 3          throw new ConcurrentModificationException();
 4      return nextElement();
 5  }
 6 
 7 
 8 public void remove() {
 9      if (!iterator)
10         throw new UnsupportedOperationException();
11      if (lastReturned == null)
12         throw new IllegalStateException("Hashtable Enumerator");
13      if (modCount != expectedModCount)
14         throw new ConcurrentModificationException();
15 
16      synchronized(Hashtable.this) {
17         Entry[] tab = Hashtable.this.table;
18         int index = (lastReturned.hash & 0x7FFFFFFF) % tab.length;
19 
20      for (Entry<K,V> e = tab[index], prev = null; e != null; prev = e, e = e.next) {
22       if (e == lastReturned) {
23          modCount++;
24          expectedModCount++;
25          if (prev == null)
26             tab[index] = e.next;
27          else
28             prev.next = e.next;
29          count--;
30          lastReturned = null;
31          return;
32       }
33      }
34      throw new ConcurrentModificationException();
35      }
36     }
37     }
而自己在next的同时,修改了这个集合,导致了这个错误的出现

 

在Map或者Collection的时候,不要用它们的API直接修改集合的内容,如果要修改可以用Iterator的remove()方法,例如:
1 public void setReparation( Reparation reparation ) {
2         for (Iterator it = this.reparations.iterator();it.hasNext();){    //reparations为Collection
3             Reparation repa = (Reparation)it.next();
4             if (repa.getId() == reparation.getId()){
5                 this.reparations.remove(repa);
6                 this.reparations.add(reparation);
7             }
8         }
9    }

 

如上写会在运行期报ConcurrentModificationException,可以如下修改:

 

 1  public void setReparation( Reparation reparation ) {
 2         boolean flag = false;
 3         for (Iterator it = this.reparations.iterator();it.hasNext();){    //reparations为Collection
 4             Reparation repa = (Reparation)it.next();
 5             if (repa.getId() == reparation.getId()){
 6                 it.remove();
 7                 flag = true;
 8                 break;
 9             }
10         }
11         if(flag){
12           this.reparations.add(reparation);
13         }
14     }

 

 

原文摘自 alreal 

 

posted @ 2012-07-17 17:01 timelyxyz 阅读(109) | 评论 (0)编辑 收藏

API语法:

File(String pathname)
通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。
public static final String separator
与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串。此字符串只包含一个字符,即 separatorChar
public static final char separatorChar
与系统有关的默认名称分隔符。此字段被初始化为包含系统属性 file.separator 值的第一个字符。在 UNIX 系统上,此字段的值为 '/';在 Microsoft Windows 系统上,它为 '\\'

注意:

路径名字符串与抽象路径名之间的转换与系统有关。将抽象路径名转换为路径名字符串时,每个名称与下一个名称之间用一个默认分隔符 隔开。默认名称分隔符由系统属性 file.separator 定义,可通过此类的公共静态字段 separatorseparatorChar 使其可用。将路径名字符串转换为抽象路径名时,可以使用默认名称分隔符或者底层系统支持的任何其他名称分隔符来分隔其中的名称。

 

例如,我希望的文件绝对路径是E:\dev\workspace\iclass_web/conf/filterconfig.xml(计作myPath),有两种创建File的形式:

1)new File(myPath)不会报错;

2)new File("E:\dev\workspace\iclass_web/conf/filterconfig.xm")报错,应修改为new File("E:\\dev\\workspace\\iclass_web/conf/filterconfig.xml"

 我的系统是windows32位,io.File的一个字段FileSystem是一个抽象类,FileSystem被一个Win32FileSystem类继承,从而实现里面的public abstract String normalize(String path);方法。

 Win32FileSystem部分源码如下:

 1 private final char slash;  2     private final char altSlash;  3     private final char semicolon;  4
 5     public Win32FileSystem() {  6     slash = ((String) AccessController.doPrivileged(  7               new GetPropertyAction("file.separator"))).charAt(0);  8     semicolon = ((String) AccessController.doPrivileged(  9               new GetPropertyAction("path.separator"))).charAt(0); 10     altSlash = (this.slash == '\\') ? '/' : '\\'; 11     } 12 13     private boolean isSlash(char c) { 14     return (c == '\\') || (c == '/'); 15     } 16 17     private boolean isLetter(char c) { 18     return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')); 19     } 20 21     private String slashify(String p) { 22     if ((p.length() > 0) && (p.charAt(0) != slash)) return slash + p; 23     else return p; 24     } 25    26     /* Check that the given pathname is normal.  If not, invoke the real 27        normalizer on the part of the pathname that requires normalization. 28        This way we iterate through the whole pathname string only once. */ 29     public String normalize(String path) { 30     int n = path.length(); 31     char slash = this.slash; 32     char altSlash = this.altSlash; 33     char prev = 0; 34     for (int i = 0; i < n; i++) { 35         char c = path.charAt(i); 36         if (c == altSlash) 37         return normalize(path, n, (prev == slash) ? i - 1 : i); 38         if ((c == slash) && (prev == slash) && (i > 1)) 39         return normalize(path, n, i - 1); 40         if ((c == ':') && (i > 1)) 41         return normalize(path, n, 0); 42         prev = c; 43     } 44     if (prev == slash) return normalize(path, n, n - 1); 45     return path; 46     }

 

posted @ 2012-07-10 17:12 timelyxyz 阅读(152) | 评论 (0)编辑 收藏

Hibernate中使用COUNT DISTINCT关键字: Hibernate

在Hibernate中, 计算某列非重复记录的总数, 使用COUNT + DISTINCT

在MySQL中,可以使用

sql 代码
  1. select COUNT(DISTINCT(name)) from products  

但在Hibernate中却不能用如下格式

  1. select COUNT(DISTINCT(name)) from ProductDTO  

需要把里面的括号去掉, 改成

  1. select COUNT(DISTINCT name ) from ProductDTO  

在MySQL中也可以使用这种样式.

posted @ 2012-06-28 13:24 timelyxyz 阅读(112) | 评论 (0)编辑 收藏

报错现象

Oops: JPAQueryException
An unexpected error occured caused by exception JPAQueryException: Error while executing query select t from TurnedIn t, Notification n  where n.itemId=t.id and n.type=? and n.receiver.id=? and n.isDeleted=false group by t order by t.createTime desc: org.hibernate.type.SerializationException: could not deserialize
...
Caused by: java.io.InvalidClassException: models.member.Member; local class incompatible: stream classdesc serialVersionUID = 8996579512119659486, local class serialVersionUID = -7513555048418418149

异常原因

本地和远程的member序列化后的serialVersionUID不

解决方法

将本地的序列化的类中的版本号(serialVersionUID )改成和远程中一样,在本地的序列化类里的private static final long serialVersionUID =  改成远程的就行了,如果没有的话就加上这句。

 

关于“org.hibernate.type.SerializationException: could not deserialize”,我查了很多的资料,大概有以下几个原因:

1.该类的序列版本号与从流中读取的类描述符的版本号不匹配(jdk版本更换会造成这个问题)

2.该类包含未知数据类型(hibernate配置文件中未指定数据类型)

3.该类没有可访问的无参数构造方法


 

 

 

posted @ 2012-06-26 09:51 timelyxyz 阅读(1083) | 评论 (0)编辑 收藏

pgSql

语法 to_number(text, text)

例子 select to_number(trim(both 'ibs' from classname), '999999') as cn from bbs order by cn   /*trim(both 'ibs' from classname)去除classname字段中的'ibs'字符*/

mySql

语法 str*1 / str+1 / -str  /*str为varchar的数字,此处不一定是1,只要是数字即可*/

hql

语法 to_number(text, text)

 

例子 select b from BBS b where b.isDeleted=false order by to_number(trim(both 'ibs' from b.className), '999999')


 

 

pgSql数据类型格式化函数 

posted @ 2012-06-14 15:43 timelyxyz 阅读(580) | 评论 (0)编辑 收藏

order by isTop desc


 

默认false在前;按desc,true在前

posted @ 2012-06-13 15:00 timelyxyz 阅读(720) | 评论 (0)编辑 收藏

      在push之前有时候会不放心是不是忘记加某些文件,或者是不是多删了个什么东西,这时候希望能够看看上次commit都做了些什么。

一开始想到的是用git diff,但是git diff用于当前修改尚未commit的时候较为方便,一旦commit后,需要指定上次节点的名称(一个hash值),不方便。这种时候用git log更合适,因为commit的内容会以log来记录。

下面记录几个常用的情境以及对应的命令。

仅仅想看最近谁有提交,以及提交的描述

对应命令 git log

显示Sample

 

commit 6305aa81a265f9316b606d3564521c43f0d6c9a3
Author: XXX
Date:   Thu Nov 3 11:38:15 2011 +0800

    fill author information in the head of files and format some code

commit 8e8a4a96e134dab8f045937efee35bd710006946
Author: XXX
Date:   Thu Nov 3 04:05:34 2011 +0800

    user management is mostly complete

    details:
    add support for account disable/enable
    rewrite most related views to suit the above need
    provide two decorators for access control (see README)
    fixed many errors in Milestone 1

commit 2870cd564371d8ad043d0da426a5770d36412421
Author: XXX
Date:   Mon Oct 17 20:19:04 2011 -0400

    fix the bug of get_ori_url_from_shorturl().

commit b6cdd881a19ecaff838d5825c3a6b7058fdd498a
Author: XXX
Date:   Mon Oct 17 20:17:37 2011 -0400

    fix the bug of get_article_from_short_url.

仅仅想看最后一次的提交

对应命令参数 -n 1

显示Sample

commit 6305aa81a265f9316b606d3564521c43f0d6c9a3
Author: XXX
Date: Thu Nov 3 11:38:15 2011 +0800

fill author information in the head of files and format some code

想看到最近一次提交所有更改过的文件

对应命令 git log -n 1 --stat

显示Sample

commit 6305aa81a265f9316b606d3564521c43f0d6c9a3
Author: XXX
Date:   Thu Nov 3 11:38:15 2011 +0800

    fill author information in the head of files and format some code

Site/accounts/decorators.py                        |    2 +-
Site/accounts/forms.py                             |    1 +
Site/accounts/models.py                            |    1 +
Site/accounts/readme                               |    3 ++-
Site/accounts/templates/account_activate.html      |    1 +
Site/accounts/templates/account_disabled.html      |    1 +

28 files changed, 37 insertions(+), 8 deletions(-)

想看到最近一次提交所有更改的细节

对应命令 git log -n 1 -p

显示Sample

commit 6305aa81a265f9316b606d3564521c43f0d6c9a3
Author: XXX
Date:   Thu Nov 3 11:38:15 2011 +0800

    fill author information in the head of files and format some code

diff --git a/Site/accounts/decorators.py b/Site/accounts/decorators.py
index 22522bc..a6bb440 100755
--- a/Site/accounts/decorators.py
+++ b/Site/accounts/decorators.py
@@ -1,9 +1,9 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
+# author: Rex Nov. 3, 2011
from functools import wraps
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
-from django.utils.decorators import available_attrs
from Site.accounts.models import UserProfile

def login_required(view_func):
diff --git a/Site/accounts/forms.py b/Site/accounts/forms.py
index 016710b..778d92a 100755
--- a/Site/accounts/forms.py
+++ b/Site/accounts/forms.py
@@ -1,5 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
+# author: Rex Nov. 3, 201

有了这几条命令,基本上对于想看最近更改的情境就可以应付过去了。最后一条并不很常用,如果有visual的工具可能更直观些。

 

原文转自git使用点滴

 

posted @ 2012-06-13 12:24 timelyxyz 阅读(212) | 评论 (0)编辑 收藏

      Onunload,onbeforeunload都是在刷新或关闭时调用,可以在<script>脚本中通过window.onunload 来指定或者在<body>里指定。区别在于onbeforeunload在onunload之前执行,它还可以阻止onunload的执行。

    Onbeforeunload也是在页面刷新或关闭时调用,Onbeforeunload是正要去服务器读取新的页面时调用,此时还没开始读取;而 onunload则已经从服务器上读到了需要加载的新的页面,在即将替换掉当前页面时调用。Onunload是无法阻止页面的更新和关闭的。而 Onbeforeunload 可以做到。曾经做一个考试系统,涉及到防止用户半途退出考试(有意或者无意),代码如下:

 

<body onbeforeunload=" checkLeave()">

 

<script>
function checkLeave(){
    event.returnValue="确定放弃考试?(考试作废,不记录成绩)";
}
</script>

 

 

这样可以让用户确认是否要退出考场,其实BLOGJAVA在用户编写BLOG时,如果不保存而跳转到其他页面,也会有一个确认的提示(防止误操作),也是用到Onbeforeunload。

   另外还可以用来在页面关闭的时候关闭session,代码如下(注:用window.screenLeft > 10000 来区分关闭和刷新操作):

<body onbeforeunload=" closeSession()">

 

<script>
function closeSession (){
    //关闭(刷新的时候不关闭Session)
    if(window.screenLeft>10000){
       //关闭Session的操作(可以运用AJAX)
    }
}
</script>

 

 

 

文章摘自 blogJava

 

posted @ 2012-06-11 16:11 timelyxyz 阅读(120) | 评论 (0)编辑 收藏

问题描述:firefox下js中动态组装select时指定option的selected属性的失效

 

有问题的代码如下:

 1                         // 加载select列表
 2                         var teaOption ='', ownerSel = $("ownerSel");
 3                         for(var i = 0; i < teaList.length; i ++){
 4                             var teacher = teaList[i];
 5                             if(teacher.isDeleted === false){
 6                                 var tid = teacher.id, tName = teacher.fullName, newOption;
 7                                 var flag = ((tid === formerOwnerId) ? 'selected="selected"' : '');
 9                                 teaOption += '<option value="'+tid+'" '+ flag +'>'+ tName +'</option>';
10                             }
11                         }
12                         ownerSel.html(teaOption);

 此时selected属性无效,ff中的select显示的是option列表的最后一个。

原因貌似是这样子:
selected这个属性本身是没有错的,你在页面开始加载的前写好,然后浏览器加载的时候就会读取这个dom,然后有selected这个效果。
但是通过js动态组装的select的html代码,在ie下我刚刚试了下可行(我刚刚失败的原因是三目运算符处少加了一个括号);firefox下,在请求加载的同时加载dom元素,但是ff内核可能是为了追求速度,而省略了一些dom的属性的加载,导致了selected这个属性的失效。

解决方法(我用的是mootools):在加载的时候将option元素通过如下解决

 1                         // 加载select列表
 2                         var ownerSel = $("ownerSel");
 3                         for(var i = 0; i < teaList.length; i ++){
 4                             var teacher = teaList[i];
 5                             if(teacher.isDeleted === false){
 6                                 var tid = teacher.id, tName = teacher.fullName, newOption;
 7                                 if(tid === formerOwnerId)
 8                                     newOption = new Element('option', {"value" : tid, "selected" : "selected"}).html(tName);
 9                                 else
10                                     newOption = new Element('option', {"value" : tid}).html(tName);
11                                 ownerSel.grab(newOption); // 将新的element插入到select中
12                             }
13                         }

 

posted @ 2012-06-07 08:34 timelyxyz 阅读(1557) | 评论 (0)编辑 收藏

错误 org.hibernate.HibernateException: ordinal parameter mismatch 。

我的错误是未将hql语句设置参数时的占位符去掉(粗糙流了下- -///)

1 hql += " and bbs.id=? " + bbs.id;

 

 

在这之前网上发现的另一种错误也很值得注意:在数据表中用了关键字“call” 作为数据字段,所以产生了这个问题。Hibernate报错如下:

 

 org.hibernate.HibernateException: ordinal parameter mismatch
 at org.hibernate.engine.query.HQLQueryPlan.buildParameterMetadata(HQLQueryPlan.java:225)
 at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:95)
 at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:54)
 at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:71)
 at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:133)
 at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:112)
 at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1583)
  ......
 

 

 出错的原因是在org.hibernate.engine.query.ParameterParser类中有下列一段代码

 

1 public static void parse(String sqlString, Recognizer recognizer) throws QueryException{
2     boolean hasMainOutputParameter = sqlString.indexOf( "call" ) > 0 &&
3                                    sqlString.indexOf( "?" ) < sqlString.indexOf( "call" ) &&
4                                    sqlString.indexOf( "=" ) < sqlString.indexOf( "call" );
5     ......
6 }

 


我们都知道hibernate3可以调用存储过程或函数,但是有一定的限制(具体可以查看hibernate官方手册)。
据我分析这段代码应该是用来分析字符串是否是调用存储过程或函数的语句。
解决方法:
1.不要在表或列中,出现"call"字样
2.用Criteria来代替hql语句

 

posted @ 2012-06-06 13:20 timelyxyz 阅读(329) | 评论 (0)编辑 收藏

String和StringBuffer的区别,网上资料可以说是数不胜数,但是看到这篇文章,感觉里面做的小例子很有代表性,所以转一下,并自己做了一点总结。

在java中有3个类来负责字符的操作。

1.Character 是进行单个字符操作的,

2.String 对一串字符进行操作。不可变类。

3.StringBuffer 也是对一串字符进行操作,但是可变类。

String:
是对象不是原始类型.
为不可变对象,一旦被创建,就不能修改它的值.
对于已经存在的String对象的修改都是重新创建一个新的对象,然后把新的值保存进去.
String 是final类,即不能被继承.

StringBuffer:
是一个可变对象,当对他进行修改的时候不会像String那样重新建立对象
它只能通过构造函数来建立,
StringBuffer sb = new StringBuffer();
note:不能通过付值符号对他进行付值.
sb = "welcome to here!";//error
对象被建立以后,在内存中就会分配内存空间,并初始保存一个null.向StringBuffer
中付值的时候可以通过它的append方法.
sb.append("hello");

字符串连接操作中StringBuffer的效率要比String高:

String str = new String("welcome to ");
str += "here";
的处理步骤实际上是通过建立一个StringBuffer,让侯调用append(),最后
再将StringBuffer toSting();
这样的话String的连接操作就比StringBuffer多出了一些附加操作,当然效率上要打折扣.

并且由于String 对象是不可变对象,每次操作Sting 都会重新建立新的对象来保存新的值.
这样原来的对象就没用了,就要被垃圾回收.这也是要影响性能的.

看看以下代码:
将26个英文字母重复加了5000次,

  String tempstr = "abcdefghijklmnopqrstuvwxyz";
  int times = 5000;
  long lstart1 = System.currentTimeMillis();
  String str = "";
  for (int i = 0; i < times; i++) {
  str += tempstr;
  }
  long lend1 = System.currentTimeMillis();
  long time = (lend1 - lstart1);
  System.out.println(time);
可惜我的计算机不是超级计算机,得到的结果每次不一定一样一般为 46687左右。
也就是46秒。
我们再看看以下代码

  String tempstr = "abcdefghijklmnopqrstuvwxyz";
  int times = 5000;
  long lstart2 = System.currentTimeMillis();
  StringBuffer sb = new StringBuffer();
  for (int i = 0; i < times; i++) {
  sb.append(tempstr);
  }
  long lend2 = System.currentTimeMillis();
  long time2 = (lend2 - lstart2);
  System.out.println(time2);
得到的结果为 16 有时还是 0
所以结论很明显,StringBuffer 的速度几乎是String 上万倍。当然这个数据不是很准确。因为循环的次数在100000次的时候,差异更大。不信你试试。

根据上面所说:

str += "here";
的处理步骤实际上是通过建立一个StringBuffer,让侯调用append(),最后
再将StringBuffer toSting();

所以str += "here";可以等同于

StringBuffer sb = new StringBuffer(str);

sb.append("here");

str = sb.toString();

所以上面直接利用"+"来连接String的代码可以基本等同于以下代码

  String tempstr = "abcdefghijklmnopqrstuvwxyz";
  int times = 5000;
  long lstart2 = System.currentTimeMillis();
  String str = "";
  for (int i = 0; i < times; i++) {
  StringBuffer sb = new StringBuffer(str);
  sb.append(tempstr);
  str = sb.toString();
  }
  long lend2 = System.currentTimeMillis();
  long time2 = (lend2 - lstart2);
  System.out.println(time2);
平均执行时间为46922左右,也就是46秒。

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yirentianran/archive/2008/09/03/2871417.aspx

StringBuffer维护了一个大小固定的字符串缓冲区,当字符串长度超过StringBuffer大小时会自动增加,主要使用Insert和append方法,对于运行期要进行字符串的组装操作推荐使用,

  StringBuilder: jdk5以后有个和StringBuffer等价的StringBuider,区别在于StringBuffer是线程安全的,StringBuilder是单线程的,不提供同步,理论上效率更高。

  String是系统内置类型,而且是final的,定义一个字符串会产生一个实例和一个对该实例地址的引用。

  如果在编译期间定义的字符串,例如 :

  String a = "name";
  a += "is";
  a += "good";

  尽管这种方法是不被推荐的,但在编译期,编译器会对该代码进行优化,所以还是可以理解为:String a = "name is good";而如果在此时采用StringBuffer,反而会推迟到运行期才会被处理,相比之下,反而会比StringBuffer效率更高,灵活运 用。
String 字符串常量
StringBuffer 字符串变量(线程安全)
StringBuilder 字符串变量(非线程安全)
 简要的说, String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象, 因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,那速度是一定会相当慢的。
 而如果是使用 StringBuffer 类则结果就不一样了,每次结果都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,再改变对象引用。所以在一般情况下我们推荐使用 StringBuffer ,特别是字符串对象经常改变的情况下。而在某些特别情况下, String 对象的字符串拼接其实是被 JVM 解释成了 StringBuffer 对象的拼接,所以这些时候 String 对象的速度并不会比 StringBuffer 对象慢,而特别是以下的字符串对象生成中, String 效率是远要比 StringBuffer 快的:
 String S1 = “This is only a” + “ simple” + “ test”;
 StringBuffer Sb = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);
 你会很惊讶的发现,生成 String S1 对象的速度简直太快了,而这个时候 StringBuffer 居然速度上根本一点都不占优势。其实这是 JVM 的一个把戏,在 JVM 眼里,这个
 String S1 = “This is only a” + “ simple” + “test”; 其实就是:
 String S1 = “This is only a simple test”; 所以当然不需要太多的时间了。但大家这里要注意的是,如果你的字符串是来自另外的 String 对象的话,速度就没那么快了,譬如:
String S2 = “This is only a”;
String S3 = “ simple”;
String S4 = “ test”;
String S1 = S2 +S3 + S4;
这时候 JVM 会规规矩矩的按照原来的方式去做

在大部分情况下 StringBuffer > String
StringBuffer
Java.lang.StringBuffer线程安全的可变字符序列。一个类似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。
可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。
StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。 append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。
例如,如果 z 引用一个当前内容是“start”的字符串缓冲区对象,则此方法调用 z.append("le") 会使字符串缓冲区包含“startle”,而 z.insert(4, "le") 将更改字符串缓冲区,使之包含“starlet”。
在大部分情况下 StringBuilder > StringBuffer
java.lang.StringBuilde
java.lang.StringBuilder 一个可变的字符序列是5.0新增的。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。两者的方法基本相同。
通过非官方试验测试,StringBuilder和StringBuffer的测试总结如下:

1. 为了获得更好的性能,在构造 StirngBuffer 或 StirngBuilder 时应尽可能指定它的容量。当然,如果你操作的字符串长度不超过 16 个字符就不用了。

2. 相同情况下使用 StirngBuilder 相比使用 StringBuffer 仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险。而在现实的模块化编程中,负责某一模块的程序员不一定能清晰地判断该模块是否会放入多线程的环境中运行,因 此:除非你能确定你的系统的瓶颈是在 StringBuffer 上,并且确定你的模块不会运行在多线程模式下,否则还是用 StringBuffer 吧 J

3. 用好现有的类比引入新的类更重要。很多程序员在使用 StringBuffer 时是不指定其容量的(至少我见到的情况是这样),如果这样的习惯带入 StringBuilder 的使用中,你将只能获得 10 %左右的性能提升(不要忘了,你可要冒多线程的风险噢);但如果你使用指定容量的 StringBuffer ,你将马上获得 45% 左右的性能提升,甚至比不使用指定容量的 StirngBuilder 都快 30% 左右。

posted @ 2012-06-05 17:04 timelyxyz 阅读(117) | 评论 (0)编辑 收藏

在原先的json数据中再新增数据

Object.append(ajaxData,{arrAttach : xxx ... // 新的数据});

 

扩展原先已经定义好的方法

callFun.extend("bind",function(){...// 新的操作}) 

 

这样可以用于多个并列操作,但又存在微小差异的ajax请求的发送

        var ajaxData = {
                "type" : $sendObjDeal()
            },callFun = function(json){
                msgArea.appendHTML(json.html,"top");
                send.fireEvent("afterCheckSubmit", send);
                clearMsgInput();
            },ajaxUrl;

        if (flag === "0"){
            ajaxUrl = ...;
            Object.append(ajaxData,{content : eassyCont.val()});
            callFun.extend("bind",function(){bindAfterSend(msgArea.getElement(".jsForIbtn"),1)})        
        }else if (flag === "1") {
            ajaxUrl = ContentItem.poll;
            Object.append(ajaxData,{pollItemContentTexts:JSON.encode($$(".jsForPollOption").val()), 

                                    pollContentText : voteQuestion.val()

                                   });
            callFun.extend("bind",function(){bindAfterSend(msgArea.getElement(".jsForIbtn"),4)})
        } else if (flag === "2") {
            ajaxUrl = ContentItem.assignment;
            ...// 独立的操作
           
        }
        // 统一发送ajax请求
        new AjaxPost(this,{
            url : ajaxUrl,
            data: ajaxData,
            callback : function(json){
                callFun(json);
                callFun.bind()
            }
        }).send()

 

posted @ 2012-06-04 14:22 timelyxyz 阅读(108) | 评论 (0)编辑 收藏

    int result = session
                .createSQLQuery(
                        "update member set blockconnectionrequests = :blockval, onlyshowprofiletomyconnections = :onlyval  where username in ('icScholar', 'smsAdminer')")
                .setParameter("blockval", false).setParameter("onlyval", false)
                .executeUpdate();

posted @ 2012-05-31 17:43 timelyxyz 阅读(161) | 评论 (0)编辑 收藏

<SCRIPT LANGUAGE="JavaScript">
var myDate = new Date();
    myDate.getYear();       //获取当前年份(2位)【注意:FireFox 的getYear返回的是“当前年份-1900”的值(传说以前一直这样处理),IE却当Year>=2000】
    myDate.getFullYear();   //获取完整的年份(4位,1970-????)
    myDate.getMonth();      //获取当前月份(0-11,0代表1月)
    myDate.getDate();       //获取当前日(1-31)
    myDate.getDay();        //获取当前星期X(0-6,0代表星期天)
    myDate.getTime();       //获取当前时间(从1970.1.1开始的毫秒数)
    myDate.getHours();      //获取当前小时数(0-23)
    myDate.getMinutes();    //获取当前分钟数(0-59)
    myDate.getSeconds();    //获取当前秒数(0-59)
    myDate.getMilliseconds();   //获取当前毫秒数(0-999)
    myDate.toLocaleDateString();    //获取当前日期
    var mytime=myDate.toLocaleTimeString();    //获取当前时间
    myDate.toLocaleString( );       //获取日期与时间

if (mytime<"23:30:00")
{
alert(mytime);
}
</SCRIPT>

posted @ 2012-05-21 23:29 timelyxyz 阅读(108) | 评论 (0)编辑 收藏

今天链接mysql的时候报了一个错“error 2013:Lost connection to MySQL server during query”,进不去,应该是连接信息有误,可是我输入的账号用户名全部是正确的,原因不知道。

后来重新启动了mysql的服务,莫名的又能连接上了。

 

网上查询了下,原因大致是这样子的:

在向NFS上备份的时候,数据的流向是这样的:MySQL Server端从数据文件中检索出数据,然后分批将数据返回给mysqldump客户端,然后mysqldump将数据写入到NFS上。一般地,向NFS 上写入数据的速度较之Server端检索发送数据的速度要慢得多,这就会导致mysqldump无法及时的接受Server端发送过来的数据,Server端的数据就会积压在内存中等待发送,这个等待不是无限期的,当Server的等待时间超过net_write_timeout(默认是60秒)时它就失去了耐心,mysqldump的连接会被断开,同时抛出错误Got error: 2013: Lost connection。
 

 

http://hi.baidu.com/ldtrain/blog/item/1c7f87be76c9020119d81f18.html
 

posted @ 2012-05-21 23:24 timelyxyz 阅读(5261) | 评论 (0)编辑 收藏

ActionContext(Action上下文) 

ActionContext介绍

通过上面用户注册例子的学习,我们知道Xwork与Web无关性,我们的Action不用去依赖于任何Web容器,不用和那些JavaServlet复杂的请求(Request)、响应(Response)关联在一起。对请求(Request)的参数(Param),可以使用拦截器框架自动调用一些get()和set()方法设置到对应的Action的字段中。但是,仅仅取得请求参数的值就能完全满足我们的功能要求吗?不,在Web应用程序开发中,除了将请求参数自动设置到Action的字段中,我们往往也需要在Action里直接获取请求(Request)或会话(Session)的一些信息,甚至需要直接对JavaServlet Http的请求(HttpServletRequest)、响应(HttpServletResponse)操作。

带着这些问题,我们来看看下面的一个功能需求:

我们需要在Action中取得request请求参数“username”的值:

ActionContext context = ActionContext.getContext();

Map params = context.getParameters();

String username = (String) params.get(“username”);

为了实现这个功能,我们用了三个步骤:

1、取得我们当前的ActionContext对象context,ActionContext是个什么冬冬?

2、从context对象里获取我们所有的请求参数,取得的却是一个Map对象params?

3、居然可以从我们的Map对象params里获取我们需要的request请求参数“username”的值。

ActionContext(com.opensymphony.xwork.ActionContext)是Action执行时的上下文,上下文可以看作是一个容器(其实我们这里的容器就是一个Map而已),它存放放的是Action在执行时需要用到的对象,比如:在使用WebWork时,我们的上下文放有请求的参数(Parameter)、会话(Session)、Servlet上下文(ServletContext)、本地化(Locale)信息等。

在每次执行Action之前都会创建新的ActionContext,ActionContext是线程安全的,也就是说在同一个线程里ActionContext里的属性是唯一的,这样我的Action就可以在多线程中使用。

我们可以通过ActionContext的静态方法:ActionContext.getContext()来取得当前的ActionContext对象,我们看看这段代码:

public static ActionContext getContext() {

ActionContext context = (ActionContext) actionContext.get();


if (context == null) {

OgnlValueStack vs = new OgnlValueStack();

context = new ActionContext(vs.getContext());

setContext(context);

}


return context;

}

一般情况,我们的ActionContext都是通过:ActionContext context = (ActionContext) actionContext.get();来获取的。我们再来看看这里的actionContext对象的创建:static ThreadLocal actionContext = new ActionContextThreadLocal();,ActionContextThreadLocal是实现ThreadLocal的一个内部类。ThreadLocal可以命名为“线程局部变量”,它为每一个使用该变量的线程都提供一个变量值的副本,使每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。这样,我们ActionContext里的属性只会在对应的当前请求线程中可见,从而保证它是线程安全的。

下面我们看看怎么通过ActionContext取得我们的HttpSession:

Map session = ActionContext.getContext().getSession();

原来我们取得的session却是Map类型的对象,这是为什么?原来,我们的WebWork框架将与Web相关的很多对象重新进行了包装,比如这里就将HttpSession对象重新包装成了一个Map对象,供我们的Action使用,而不用直接和底层的HttpSession打交道。也正是框架的包装,让我们的Actoion可以完全的和Web层解藕。

如果我们的Action需要直接与JavaServlet的HttpSession、HttpServletRequest等一些对象进行操作,我们又该如何处理?请看下面的ServletActionContext。

ServletActionContext

ServletActionContext(com.opensymphony.webwork. ServletActionContext),这个类直接继承了我们上面介绍的ActionContext,它提供了直接与JavaServlet相关对象访问的功能,它可以取得的对象有:

1、javax.servlet.http.HttpServletRequest:HTTPservlet请求对象

2、javax.servlet.http.HttpServletResponse;:HTTPservlet相应对象

3、javax.servlet.ServletContext:Servlet 上下文信息

4、javax.servlet.ServletConfig:Servlet配置对象

5、javax.servlet.jsp.PageContext:Http页面上下文

ServletActionContext除了提供了上面这些对象访问,它当然也继承了它父类ActionContex的很多功能,比如:对OgnlValueStack、Action名字等的访问。

下面我们看看几个简单的例子,让我们了解如何从ServletActionContext里取得JavaServlet的相关对象:

1、取得HttpServletRequest对象:

HttpServletRequest request = ServletActionContext. getRequest();

2、取得HttpSession对象:

HttpSession session = ServletActionContext. getRequest().getSession();

ServletActionContext和ActionContext有着一些重复的功能,在我们的Action中,该如何去抉择呢?我们遵循的原则是:如果ActionContext能够实现我们的功能,那最好就不要使用ServletActionContext,让我们的Action尽量不要直接去访问JavaServlet的相关对象。在使用ActionContext时有一点要注意:不要在Action的构造函数里使用ActionContext.getContext(),因为这个时候ActionContext里的一些值也许没有设置,这时通过ActionContext取得的值也许是null。

 

原文链接 http://space.itpub.net/14734416/viewspace-485659

 

posted @ 2012-05-19 20:20 timelyxyz 阅读(1093) | 评论 (0)编辑 收藏

  参考文献:http://www.playframework.org/documentation/1.2.3/controllers

  当参数名和HTTP请求中的参数名(即界面中的name)相同时,后台Controller可以直接获取该变量的值。变量分两大类:

  1. Simple types

  所有的基本数据类型和一些常用的Java类型可以被自动绑定

  int, long, boolean, char, byte, float, double, Integer, Long, Boolean, Char, Byte, Float, Double, String

  以上数据类型可以被自动绑定,当参数为丢失时,默认会将变量的值赋为:null或0。

  2. Date

  当时间对象以一下格式展现时,可以被自动绑定到后台:

  • yyyy-MM-dd'T'hh:mm:ss'Z' //ISO8601 + timezone
  • yyyy-MM-dd'T'hh:mm:ss" //ISO8601
  • yyyy-MM-dd
  • yyyyMMdd'T'hhmmss
  • yyyyMMddhhmmss
  • dd'/'MM'/'yyyy
  • dd-MM-yyyy
  • ddMMyyyy
  • MMddyy
  • MM-dd-yy
  • MM'/'dd'/'yy

  引用@As 注释,可以直接定义时间格式。for example:

  archives?from=21/12/1980

  public static void articlesSince(@As("dd/MM/yyyy") Date from) {

    List<Article> articles = Article.findBy("date >= ?", from);

    render(articles);

  }

  另外也可以根据语言来格式化时间。See as follows:

  public static void articlesSince(@As(lang={"fr,de","*"}, value={"dd-MM-yyyy","MM-dd-yyyy"}) Date from) {

    List<Article> articles = Article.findBy("date >= ?", from);

    render(articles);

  }

  在这个例子中,我们将French和German语言对应的时间格式设置为dd-MM-yyyy和MM-dd-yyyy。需要注意的是,语言必须用都好分隔开,value和lang的个数要匹配。

  如果@As注释没写的话,时间会按照默认格式来转化。

  3.Calendar

  Calendar跟Date类似,它使用的注释是@Bind。

  4.Arrays or collections of supported types

  所有被支持的类型都可以作以Array的形式被绑定获取到。for example:

  public static void show(Long[] id){...}

  public static void show(List<Long> id){...}

  public static void show(Set<Long> id){...}

  Play也支持像是Map<String, String>这样子的特殊例子:

  public static void show(Map<String, String> client){...}

  在上面的这个例子中,传入的语句如下:

  ?client.name=John&client.phone=111-1111&client.phone=222-222

  此时后台获取到一个map元素,第一个元素的key为name,值为John,第二个元素的key为phone,值为111-1111,222-2222.

  5.POJO object binding

  play同样支持自动绑定任何model,只要该对象遵守相同的命名规则。for example:

  public static void create(Client client){

    client.save();

    show(client);

  }

  在页面端,一个保存client的action需要规定如下:

  ?client.name=Zenexity&client.email=contact&zenexity.fr

  play可以创建一个Client对象,并且从HTTP请求中读取相关的属性值赋到Client对象上。一些不能解决/读取的参数会被play安全的忽略掉,类型不匹配也会被自动忽略。

  参数绑定也可以递归的进行,只要你列出完整的参数列表:

  ?client.name=Zenexity

  &client.address.street=64+rue+taitbout

  &client.address.zip=75009

  &client.address.country=France

  有时候为了更新对象列表,会使用一个存放了对象id的数组。For example,假设我们已经有了一个Customer的对象列表,声明List Customer customers,为了更新Customers,我们需要提供如下一串String:

  ?client.customers[0].id=123

  &client.customers[1].id=456

  &client.customers[2].id=789

   6.JPA object binding

   7.File

File upload is easy with Play. Use a multipart/form-data encoded request to post files to the server, and then use the java.io.File type to retrieve the file object:

public static void create(String comment, File attachment) { String s3Key = S3.post(attachment); Document doc = new Document(comment, s3Key); doc.save(); show(doc.id); } 

The created file has the same name as the original file. It’s stored in a temporary directory and deleted at the end of the request. So you have to copy it in a safe directory or it will be lost.

The uploaded file’s MIME type should normally be specified by the HTTP request’s Content-type header. However, when uploading files from a web browser, this might not happen for uncommon types. In this case, you can map the file name’s extension to a MIME type, using the play.libs.MimeTypes class.

String mimeType = MimeTypes.getContentType(attachment.getName()); 

The play.libs.MimeTypes class looks up the MIME type for the given file name’s extension in the file $PLAY_HOME/framework/src/play/libs/mime-types.properties

You can also add your own types using the Custom MIME types configuration.

 

ps:还没写完,以后再继续。


posted @ 2012-05-18 08:54 timelyxyz 阅读(174) | 评论 (0)编辑 收藏

本课题参考自《Spring in action》。并非应用系统中发生的所有事情都是由用户的动作引起的。有时候,系统自己也需要发起一些动作。例如,集抄系统每天早上六点把抄表数据传送 给营销系统。我们有两种选择:或者是每天由用户手动出发任务,或者让应用系统中按照预定的计划自动执行任务。
在Spring中有两种流行配置:Java的Timer类和OpenSymphony的Quartz来执行调度任务。下面以给商丘做的接口集抄900到中间库的日冻结数据传输为例:
1. Java Timer调度器
首先定义一个定时器任务,继承java.util.TimerTask类实现run方法
import java.util.TimerTask;
import xj.service.IJdbc1Service;
import xj.service.IJdbc2Service;
public class DayDataTimerTask extends TimerTask{
private IJdbc2Service jdbc2Service=null;
private IJdbc1Service jdbc1Service=null;
public void run(){
SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("日冻结转接任务开始时间:"+df.format(Calendar.getInstance().getTime()));
System.out.println("日冻结转接任务结束时间:"+df.format(Calendar.getInstance().getTime()));
}

//通过set方法获取service服务,如果没有该方法,则为null
public void setJdbc2Service(IJdbc2Service jdbc2Service) {
this.jdbc2Service = jdbc2Service;
}

public void setJdbc1Service(IJdbc1Service jdbc1Service) {
this.jdbc1Service = jdbc1Service;
}
}
Run()方法定义了当任务运行时该做什么。jdbc1Service,jdbc2Service通过依赖注入的方式提供给DayDataTimerTask。如果该任务中没有service服务的set方法,则取到的该service服务为null。
其次,在Spring配置文件中声明 dayDataTimerTask:
<!-- 声明定时器任务 -->
<bean id="dayDataTimerJob" class="xj.action.DayDataTimerTask">
<property name="jdbc1Service">
<ref bean="jdbc1Service"/>
</property>
<property name="jdbc2Service">
<ref bean="jdbc2Service"/>
</property>
</bean>
该声明将DayDataTimerTask放到应用上下文中,并在jdbc1Service、jdbc2Service属性中分别装配jdbc1Service、jdbc2Service。在调度它之前,它不会做任何事情。
<!-- 调度定时器任务 -->
<bean id="scheduledDayDataTimerJob" class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="timerTask">
<ref bean="dayDataTimerJob"/>
</property>
<property name="delay">
<value>3000</value>
</property>
<property name="period">
<value>864000000</value>
</property>
</bean>
属性timerTask告诉ScheduledTimerTask运行哪个TimerTask。再次,该属性装配了指向 scheduledDayDataTimerJob的一个引用,它就是DayDataTimerTask。属性period告诉 ScheduledTimerTask以怎样的频度调用TimerTask的run()方法。该属性以毫秒作为单位,它被设置为864000000,指定 这个任务应该每24小时运行一次。属性delay允许你指定当任务第一次运行之前应该等待多久。在此指定DayDataTimerTask的第一次运行相 对于应用程序的启动时间延迟3秒钟。
<!-- 启动定时器 -->
<bean class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<list>
<ref bean="scheduledDayDataTimerJob"/>
</list>
</property>
</bean>
Spring的TimerFactoryBean负责启动定时任务。属性scheduledTimerTasks要求一个需要启动的定时器任务的列表。在此只包含一个指向scheduledDayDataTimerJob的引用。
    Java Timer只能指定任务执行的频度,但无法精确指定它何时运行,这是它的一个局限性。要想精确指定任务的启动时间,就需要使用Quartz[kwɔ:ts]调度器。
2.Quartz调度器
Quartz调度器不仅可以定义每隔多少毫秒执行一个工作,还允许你调度一个工作在某个特定的时间或日期执行。
首先创建一个工作,继承QuartzJobBean类实现executeInternal方法
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.scheduling.quartz.QuartzJobBean;

import xj.service.IJdbc1Service;
import xj.service.IJdbc2Service;
public class DayDataQuartzTask extends QuartzJobBean{
private IJdbc2Service jdbc2Service=null;
private IJdbc1Service jdbc1Service=null;
protected void executeInternal(JobExecutionContext context) throws JobExecutionException{
SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("日冻结转接任务开始时间:"+df.format(Calendar.getInstance().getTime()));
System.out.println("日冻结转接任务结束时间:"+df.format(Calendar.getInstance().getTime()));
}

//通过set方法获取service服务,如果没有该方法,则为null
public void setJdbc2Service(IJdbc2Service jdbc2Service) {
this.jdbc2Service = jdbc2Service;
}

public void setJdbc1Service(IJdbc1Service jdbc1Service) {
this.jdbc1Service = jdbc1Service;
}

}

在Spring配置文件中按照以下方式声明这个工作:
<!-- 定时启动任务 Quartz-->
<!—声明工作-->
<bean id="dayDataJob" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass">
<value>xj.action.DayDataQuartzTask</value>
</property>
<property name="jobDataAsMap">
<map>
<entry key="jdbc1Service">
<ref bean="jdbc1Service"/>
</entry>
<entry key="jdbc2Service">
<ref bean="jdbc2Service"/>
</entry>
</map>
</property>
</bean>
Quartz的org.quartz.Trigger类描述了何时及以怎样的频度运行一个Quartz工作。Spring提供了两个触发器 SimpleTriggerBean和CronTriggerBean。SimpleTriggerBean与scheduledTimerTasks类 似。指定工作的执行频度,模仿scheduledTimerTasks配置。
<!-- 调度Simple工作 -->
<bean id="simpleDayDataJobTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail">
<ref bean="dayDataJob"/>
</property>
<property name="startDelay">
<value>1000</value>
</property>
<property name="repeatInterval">
<value>86400000</value>
</property>
</bean>
<!—调度cron工作-->
<bean id="dayDataJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<ref bean="dayDataJob"/>
</property>
<property name="cronExpression">
<value>0 30 2 * * ?</value>
</property>
</bean>
一个cron表达式有6个或7个由空格分隔的时间元素。从左至右,这些元素的定义如下:1、秒(0-59);2、分(0-59);3、小时 (0-23);4、月份中的日期(1-31);5、月份(1-12或JAN-DEC);6、星期中的日期(1-7或SUN-SAT);7、年份 (1970-2099)。
每一个元素都可以显式地规定一个值(如6),一个区间(如9-12),一个列表(如9,11,13)或一个通配符(如*)。“月份中的日期”和“星期中的日期”这两个元素互斥,应该通过设置一个问号(?)来表明你不想设置的那个字段。

corn表达式API具体见

http://www.quartz-scheduler.org/documentation/quartz-1.x/tutorials/crontrigger

我们在此定义该任务在每天凌晨两点半开始启动。
<!—启动工作-->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="simpleDayDataJobTrigger"/>
<ref bean="dayDataJobTrigger"/>
</list>
</property>
</bean>
属性triggers接受一组触发器,在此只装配包含simpleDayDataJobTrigger bea和dayDataJobTrigger bean的一个引用列表。

posted @ 2012-05-17 23:59 timelyxyz 阅读(126) | 评论 (0)编辑 收藏

题目:吸血鬼数字是指位数为偶数的数字,可以由一对数字相乘而得到,而对数字各包含乘积的一半数的数字,其中从最初的数字中选取的数字可以任意排序。以两个0结尾的数字是不允许的,列如:
1260=21*60;
1827=21*87;
2187=27*81;
请写出一个程序,找出所有的4位吸血鬼数字。
解:反过来想,
不从考虑某个数(1001到9999)是不是吸血鬼数,而是遍历2位数相乘,看是否符合某种规则,符合的话,他们的积就是吸血鬼数

package test1;

import java.util.Arrays;
import java.util.Scanner;

/**
 * 吸血鬼数字:位数为偶数,可以由一对数字相乘而得,这对数字分别是吸血鬼数字的一半位数的,顺序不规定<br>
 * 1260=12*60, 1827=21*87
 */
public class Vampire {

    public static void main(String[] args) {
        System.out.printf("Please enter the length of the num : ");
        Scanner s = new Scanner(System.in);
        int x = s.nextInt();
        calVampire(x);
    }

    public static void calVampire(int n) {
        if (n % 2 != 0)
            return;
        else {
            int subLength = n / 2;
            int total = 0;
            int min = (int) Math.pow(10, subLength - 1);
            int max = (int) Math.pow(10, subLength) - 1;
            for (int p = min; p <= max; p++) {
                for (int k = p + 1; k <= max; k++) {
                    int val = p * k;
                    if (val > 9999 || val < 1000)
                        continue;
                    String[] s1 = String.valueOf(val).split("");
                    String[] s2 = (String.valueOf(p) + String.valueOf(k))
                            .split("");
                    Arrays.sort(s1);
                    Arrays.sort(s2);
                    if (Arrays.equals(s1, s2)) {
                        total++;
                        System.out.println(p + " * " + k + "=" + val);
                    }
                }
            }
            System.out.println("Total num is : " + total);
        }
    }

}

posted @ 2012-05-15 09:53 timelyxyz 阅读(136) | 评论 (0)编辑 收藏

一、find(String queryString);

示例:this.getHibernateTemplate().find(”from bean.User”);

返回所有User对象

二、find(String queryString , Object value);

示例:this.getHibernateTemplate().find(”from bean.User u where u.name=?”, “test”);

或模糊查询:this.getHibernateTemplate().find(”from bean.User u where u.name like ?”, “%test%”);

返回name属性值为test的对象(模糊查询,返回name属性值包含test的对象)

三、find(String queryString, Object[] values);

示例:String hql= “from bean.User u where u.name=? and u.password=?”

this.getHibernateTemplate().find(hql, new String[]{”test”, “123″});

返回用户名为test并且密码为123的所有User对象

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

四、findByExample(Object exampleEntity)

示例:

User u=new User();

u.setPassword(”123″);//必须符合的条件但是这两个条件时并列的(象当于sql中的and)

u.setName(”bb”);

list=this.getHibernateTemplate().findByExample(u,start,max);

返回:用户名为bb密码为123的对象

五、findByExample(Object exampleEntity, int firstResult, int maxResults)

示例:

User u=new User();

u.setPassword(”123″);//必须符合的条件但是这两个条件时并列的(象当于sql中的and)

u.setName(”bb”);

list=this.getHibernateTemplate().findByExample(u,start,max);

返回:满足用户名为bb密码为123,自start起共max个User对象。(对象从0开始计数)

—————————————————

六、findByNamedParam(String queryString , String paramName , Object value)

使用以下语句查询:

String queryString = “select count(*) from bean.User u where u.name=:myName”;

String paramName= “myName”;

String value= “xiyue”;

this.getHibernateTemplate().findByNamedParam(queryString, paramName, value);

System.out.println(list.get(0));

返回name为xiyue的User对象的条数

七、findByNamedParam(String queryString , String[] paramName , Object[] value)

示例:

String queryString = “select count(*) from bean.User u where u.name=:myName and u.password=:myPassword”;

String[] paramName= new String[]{”myName”, “myPassword”};

String[] value= new String[]{”xiyue”, “123″};

this.getHibernateTemplate().findByNamedParam(queryString, paramName, value);

返回用户名为xiyue密码为123的User对象

八、findByNamedQuery(String queryName)

示例:

1、首先需要在User.hbm.xml中定义命名查询

<hibernate-mapping>

<class>……</class>

<query name=”queryAllUser”><!–此查询被调用的名字–>

<![CDATA[

from bean.User

]]>

</query>

</hibernate-mapping>

2、如下使用查询:

this.getHibernateTemplate().findByNamedQuery(”queryAllUser”);

九、findByNamedQuery(String queryName, Object value)

示例:

1、首先需要在User.hbm.xml中定义命名查询

<hibernate-mapping>

<class>……</class>

<query name=”queryByName”><!–此查询被调用的名字–>

<![CDATA[

from bean.User u where u.name = ?

]]>

</query>

</hibernate-mapping>

2、如下使用查询:

this.getHibernateTemplate().findByNamedQuery(”queryByName”, “test”);

十、findByNamedQuery(String queryName, Object[] value)

示例:

1、首先需要在User.hbm.xml中定义命名查询

<hibernate-mapping>

<class>……</class>

<query name=”queryByNameAndPassword”><!–此查询被调用的名字–>

<![CDATA[

from bean.User u where u.name =? and u.password =?

]]>

</query>

</hibernate-mapping>

2、如下使用查询:

String[] values= new String[]{”test”, “123″};

this.getHibernateTemplate().findByNamedQuery(”queryByNameAndPassword” , values);

十一、findByNamedQueryAndNamedParam(String queryName, String paramName, Object value)

示例:

1、首先需要在User.hbm.xml中定义命名查询

<hibernate-mapping>

<class>……</class>

<query name=”queryByName”><!–此查询被调用的名字–>

<![CDATA[

from bean.User u where u.name =:myName

]]>

</query>

</hibernate-mapping>

2、如下使用查询:

this.getHibernateTemplate().findByNamedQuery(”queryByName” , “myName”, “test”);

十二、findByNamedQueryAndNamedParam(String queryName, String[] paramName, Object[] value)

示例:

1、首先需要在User.hbm.xml中定义命名查询

<hibernate-mapping>

<class>……</class>

<query name=”queryByNameAndPassword”><!–此查询被调用的名字–>

<![CDATA[

from bean.User u where u.name =:myName and u.password=:myPassword

]]>

</query>

</hibernate-mapping>

2、如下使用查询:

String[] names= new String[]{”myName”, “myPassword”};

String[] values= new String[]{”test”, “123″};

this.getHibernateTemplate().findByNamedQuery(”queryByNameAndPassword” , names, values);

十三、findByValueBean(String queryString , Object value);

示例:

1、定义一个ValueBean,属性名必须和HSQL语句中的:后面的变量名同名,此处必须至少有两个属性,分别为myName和 myPassword,使用setter方法设置属性值后

ValueBean valueBean= new ValueBean();

valueBean.setMyName(”test”);

valueBean.setMyPasswrod(”123″);

2、

String queryString= “from bean.User u where u.name=:myName and u.password=:myPassword”;

this.getHibernateTemplate().findByValueBean(queryString , valueBean);

十四、findByNamedQueryAndValueBean(String queryName , Object value);

示例:

1、首先需要在User.hbm.xml中定义命名查询

<hibernate-mapping>

<class>……</class>

<query name=”queryByNameAndPassword”><!–此查询被调用的名字–>

<![CDATA[

from bean.User u where u.name =:myName and u.password=:myPassword

]]>

</query>

</hibernate-mapping>

2、定义一个ValueBean,属性名必须和User.hbm.xml命名查询语句中的:后面的变量名同名,此处必须至少有两个属性,分别为 myName和myPassword,使用setter方法设置属性值后

ValueBean valueBean= new ValueBean();

valueBean.setMyName(”test”);

valueBean.setMyPasswrod(”123″);

3、

String queryString= “from bean.User u where u.name=:myName and u.password=:myPassword”;

this.getHibernateTemplate().findByNamedQueryAndValueBean(”queryByNameAndPassword”, valueBean);

 

原文摘自http://holoblog.iteye.com/blog/1245768

posted @ 2012-05-14 17:01 timelyxyz 阅读(109) | 评论 (0)编辑 收藏

1. 引言
JUnit4提供的新断言语法具有很多优点且使用简单,这已经不再是新鲜事了,可发现在实际测试代码中仍未被普及应用,特发此文,以期更多的人能掌握运用。
2. assertThat基本语法
Hamcrest 是一个测试辅助工具,提供了一套通用的匹配符 Matcher,灵活使用这些匹配符定义的规则,程序员可以更加精确的表达自己的测试思想,指定所想设定的测试条件。
Junit4结合Hamcrest提供了新的断言语句-assertThat,只需一个assertThat语句,结合Hamcrest提供的匹配符,就可以表达全部的测试思想。
assertThat的基本语法如下:

assertThat(T actual, Matcher matcher)
assertThat(String reason, T actual, Matcher matcher)

actual 是接下来想要验证的值;
matcher是使用 Hamcrest 匹配符来表达的对前面变量所期望的值的声明,如果 actual值与 matcher 所表达的期望值相符,则断言成功,否则断言失败。
reason是自定义的断言失败时显示的信息。
一个简单的例子:
// 如果测试的字符串testedString包含子字符串"taobao"则断言成功
assertThat( testedString, containsString( "taobao" ) );

3. assertThat优点

  • 统一

只需一条assertThat语句即可替代旧有的其他语句(如 assertEquals,assertNotSame,assertFalse,assertTrue,assertNotNull,assertNull 等),使断言变得简单、代码风格统一,增强测试代码的可读性和可维护性。

  • 语法直观易懂

assertThat 不再像 assertEquals 那样,使用比较难懂的“谓宾主”语法模式(如:assertEquals(3, x);)。相反,assertThat 使用了类似于“主谓宾”的易读语法模式(如:assertThat(x,is(3));),使得代码更加直观、易读,符合人类思维习惯。

  • 错误信息更具描述性

旧的断言语法如果断言失败,默认不会有额外的提示信息,如
assertTrue(testedString.indexOf(“taobao”) > -1);
如果该断言失败,只会抛出无用的错误信息,如java.lang.AssertionError: ,除此之外不会有更多的提示信息。
新的断言语法会默认自动提供一些可读的描述信息,如
assertThat(testedString, containsString(“taobao”));
如果该断言失败,抛出的错误提示信息如下:
java.lang.AssertionError:
Expected: a string containing “taobao”
got: “taoba”

  • 跟Matcher匹配符联合使用更灵活强大

Matcher提供了功能丰富的匹配符,assertThat结合这些匹配符使用可更灵活更准确的表达测试思想。
// 验证字符串 s是否含有子字符串 "taobao" 或 "qa" 中间的一个
// 旧的断言,不直观,需要分析代码逻辑明白验证意图
assertTrue(s.indexOf("taobao")>-1||s.indexOf("qa")>-1);
// 新的断言,直观易懂,准确表达测试思想
assertThat(s,anyOf(containsString("taobao"),containsString("qa")));
// anyOf满足条件之一即成立,containsString包含字符串则成立

4. assertThat使用
要想发挥assetThat的威力,必须跟Hamcrest联合使用,JUnit4本身包含了一些自带了一些 Hamcrest 的匹配符 Matcher,但是只有有限的几个。因此建议你将Hamcrest包加入项目。
在pom里加入Hamcrest依赖。
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.1</version>
</dependency>

在测试类里导入包
import static org.junit.Assert.*;
import static org.hamcrest.Matchers.*;

通过例子学习是有效的学习方式之一,下面通过常用的示例演示如何使用assertThat,更详细的用法请参考Hamcrest相关文档。

  • 字符相关匹配符

/**equalTo匹配符断言被测的testedValue等于expectedValue,
* equalTo可以断言数值之间,字符串之间和对象之间是否相等,相当于Object的equals方法
*/
assertThat(testedValue, equalTo(expectedValue));

/**equalToIgnoringCase匹配符断言被测的字符串testedString
*在忽略大小写的情况下等于expectedString
*/
assertThat(testedString, equalToIgnoringCase(expectedString));

/**equalToIgnoringWhiteSpace匹配符断言被测的字符串testedString
*在忽略头尾的任意个空格的情况下等于expectedString,
*注意:字符串中的空格不能被忽略
*/
assertThat(testedString, equalToIgnoringWhiteSpace(expectedString);

/**containsString匹配符断言被测的字符串testedString包含子字符串subString**/
assertThat(testedString, containsString(subString) );

/**endsWith匹配符断言被测的字符串testedString以子字符串suffix结尾*/
assertThat(testedString, endsWith(suffix));

/**startsWith匹配符断言被测的字符串testedString以子字符串prefix开始*/
assertThat(testedString, startsWith(prefix));

  • 一般匹配符

/**nullValue()匹配符断言被测object的值为null*/
assertThat(object,nullValue());

/**notNullValue()匹配符断言被测object的值不为null*/
assertThat(object,notNullValue());

/**is匹配符断言被测的object等于后面给出匹配表达式*/
assertThat(testedString, is(equalTo(expectedValue)));

/**is匹配符简写应用之一,is(equalTo(x))的简写,断言testedValue等于expectedValue*/
assertThat(testedValue, is(expectedValue));

/**is匹配符简写应用之二,is(instanceOf(SomeClass.class))的简写,
*断言testedObject为Cheddar的实例
*/
assertThat(testedObject, is(Cheddar.class));

/**not匹配符和is匹配符正好相反,断言被测的object不等于后面给出的object*/
assertThat(testedString, not(expectedString));

/**allOf匹配符断言符合所有条件,相当于“与”(&&)*/
assertThat(testedNumber, allOf( greaterThan(8), lessThan(16) ) );

/**anyOf匹配符断言符合条件之一,相当于“或”(||)*/
assertThat(testedNumber, anyOf( greaterThan(16), lessThan(8) ) );

  • 数值相关匹配符

/**closeTo匹配符断言被测的浮点型数testedDouble在20.0¡À0.5范围之内*/
assertThat(testedDouble, closeTo( 20.0, 0.5 ));

/**greaterThan匹配符断言被测的数值testedNumber大于16.0*/
assertThat(testedNumber, greaterThan(16.0));

/** lessThan匹配符断言被测的数值testedNumber小于16.0*/
assertThat(testedNumber, lessThan (16.0));

/** greaterThanOrEqualTo匹配符断言被测的数值testedNumber大于等于16.0*/
assertThat(testedNumber, greaterThanOrEqualTo (16.0));

/** lessThanOrEqualTo匹配符断言被测的testedNumber小于等于16.0*/
assertThat(testedNumber, lessThanOrEqualTo (16.0));

  • 集合相关匹配符

/**hasEntry匹配符断言被测的Map对象mapObject含有一个键值为"key"对应元素值为"value"的Entry项*/
assertThat(mapObject, hasEntry("key", "value" ) );

/**hasItem匹配符表明被测的迭代对象iterableObject含有元素element项则测试通过*/
assertThat(iterableObject, hasItem (element));

/** hasKey匹配符断言被测的Map对象mapObject含有键值“key”*/
assertThat(mapObject, hasKey ("key"));

/** hasValue匹配符断言被测的Map对象mapObject含有元素值value*/
assertThat(mapObject, hasValue(value));

转载务必注明出处Taobao QA Team,原文地址:http://qa.taobao.com/?p=3541

posted @ 2012-01-17 17:09 timelyxyz 阅读(102) | 评论 (0)编辑 收藏

  conf目录包含了各种应用配置文件,有必须的文件:application.conf和routes。

  • application.conf:应用的主配置文件,包含了
  • routes:路由定义文件

  你也可以在application.conf中添加一些自己的应用中的特殊的配置选项,配置可以在程序中通过Play.configuration.get("propertyName")来读取。当你需要新建一个新的应用程序,可以使用play new命令来讲一些默认配置从$PLAY_HOME/resources/application-skel/conf这个目录中复制一些相关的程序启动的默认配置,还有一些配置选项是被注释的,皆是可以选择相关的项目来用。

  任何一个类库需要的配置文件,尽量将其放置到conf这个目录中:这个目录被配置在了Java的环境变量里了。

  当然,你也可以在application.conf这个文件中引用其他的一些play配置,只要用@include.作为开头即可。例如,你定义了一个附加的MIME类型在conf/mime-types.conf里:

# Web fonts
mimetype.eot = application/vnd.ms-fontobject
mimetype.otf = application/octet-stream
mimetype.ttf = application/octet-stream
mimetype.woff = application/x-font-woff

  你可以通过如下命令讲文件导入到application.conf中:

@include.mime = mime-types.conf

 

文献参考:http://www.playframework.org/documentation/1.2.3/main

posted @ 2012-01-16 15:43 timelyxyz 阅读(106) | 评论 (0)编辑 收藏

  • 数据源概念
  • 数据库连接池 
  • jndi概念
  • 数据源与连接池关系
  • 数据源与jndi关系
  • jdbc基础

1.什么是数据源?

答: 数据源定义的是连接到实际数据库的一条路径而已,数据源中并无真正的数据,它仅仅记录的是你连接到哪个数据库,以及如何连接的,如odbc数据源。也就是 说数据源仅仅是数据库的连接名称,一个数据库可以有多个数据源连 接。                                                                                                                              

       在Java语言中,DataSource对象就是一个代表数据源实体的对象。一个数据源就是一个用来存储数据的工具,它可以是复杂的大型企业级数据库,也可以是简单得只有行和列的文件。数据源可以位于在服务器端,也可以位于客服端。

2.什么是数据库连接池?

答: 数据库连接是负责分配、管理和释放数据库连接。使用数据库连接池是因为数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现得尤 为突出。如weblogic、tomcat、WebSphere容器都实现了数据库连接池,但是数据库连接池是可以独立出来自己编码实现的。

        数据库连接池在系统启动时初始化了一定量maxIdle=idlenum的数据库连接,即没有他的使用中的链接被释放的情况下,连接池中保存的最大空闲链 接数。数据库连接请求如果没有超过idle的值则直接去连接池中获取;如果超过了maxIdle的值则新建一个数据库连接;但如果数据库连接池中的连接总 数超过了maxActive=activenum则 (如下处理);

    
  1   直接抛错  
  2   让想要借出连接的线程等待一段时间,如果等不到,再抛错  
  3   每隔一段检查一次pool,直到有可用连接,否则一直等下去  
  4   永远可以拿到(视情况需要maxActive不设置或0或负)  

但当没有可以使用的数据库链接的时候,连接池将要等待一个链接被返回的最长时间(毫秒)maxWait=waitnum,超过这个时间就要抛出异常。

3.什么是jndi?

答:jndi全称是java naming and directory interface。简单点就是你按命名规则给一个东西命名然后你就可以通过该名字在特定环境下直接查找到该东西了。

JNDI 是用于向Java程序提供目录和命名功能的API。可以简单地把JNDI理解为一种将对象和名字绑定的技术,对象工厂负责生产出对象,这些对象都和惟一的 名字绑定。外部程序可以通过名字来获取对某个对象的引用。在一个文件系统中,文件名被绑定给文件。在DNS中,一个IP地址绑定一个URL。在目录服务 中,一个对象名被绑定给一个对象实体。

在Intranets(企业内部网)和Internates(互联网)中 目录服务(Directory service)都非常重要,它规范了命名规则,让人们容易理解实体及之间的关系。JNDI是Java平台的一个标准扩展,提供了一组接口、类和关于命名 空间的概念。JNDI目前所支持的技术包括LDAP、CORBA Common Object Service(COS)名字服务、RMI、NDS、DNS、Windows注册表等等。

jndi被设计成独立于特定的目录服务,所以各种各样的目录都可以通过相同的方式进行访问。这样使用jndi的java程序员不仅可以获得统一规整的命名和目录,而且可以通过多层的命名方案无缝访问(seamless acess)目录对象。

4.数据源与数据库连接池关系?

答: 我们通过第三方工具来使用数据源来实现对数据库数据操作。一个数据库连接池可以给它创建多个数据源,如一个人有别名;如果单纯使用jdbc连接数据库是 web容器你要什么就去连什么。这样做没人看不耗内存,量大了你就死机。可以这样理解,数据源表示一个与数据库的连接(传统)或者表示很多与数据库的连接 (使用数据库连接池)。数据源是用于访问连接池或多池的JNDI对象,多池的主要目的是提高可用性和在一组连接池间实现负载均衡。

5.数据源与jndi关系?

答:数据源是在JDBC 2.0中引入的一个概念。 在JDBC 2.0扩展包中定义了javax.sql.DataSource接口来描述这个概念。如果用户希望建立一个数据库连接,通过查询在JNDI服务中的数据 源,可以从数据源中获取相应的数据库连接。这样用户就只需要提供一个逻辑名称(Logic Name),而不是数据库登录的具体细节。即DataSource采用Java的JNDI技术,来获得DataSource对象的引用。当然各种web容 器把DataSource作为一种可以配置的JNDI资源来处理如tomcat。生成DataSource对象的工厂为 org.apache.commons.dbcp.BasicDataSourceFactory。

6.jdbc基础

答:java database connectivity standard 是一套规范的面向应用程序的接口,通过它可以访问各类关系数据库。各个数据库会实现该接口作为驱动如jtds.jar,当然可以自己写实现。

jdbc 是低级api,提供访问数据库的接口,是构建高级api的基础,利用纯java编写可以在任何操作系统任何java环境下工作。JDBC API 中定义了一些Java类分别用来表示与数据库的连接(connections), SQL语句(SQL statements), 结果集(result sets)以及其它的数据库对象, 使得Java程序能方便地与数据库交互并处理所得的结果。

使用JDBC, 所有Java程序(包括Java applications , applets和servlet)都能通过SQL语句或存储在数据库中的过程(stored procedures)来存取数据库。要通过JDBC来存取某一特定的数据库,必须有相应的JDBC driver,它往往是由生产数据库的厂家提供,是连接JDBC API与具体数据库之间的桥梁。JDBC driver 是用于特定数据库的一套实施了JDBC接口的类集。

简单的说,jdbc可以做三件事:与数据库建立连接,发送sql语句,处理结果。jdbc可以理解为odbc的纯java语言和面向对象的实现。

7.数据库访问方法?

答:在ASP中可以通过三种方式访问数据库:
1、IDC(Internet Database Connector)方式;
2、ADO(ActiveX Data Objects)方式;
3、RDS(Remote Data Service)方式。
        在jsp中访问数据库常用:
1、JDBC-ODBC桥接器;
2、特定数据库的jdbc驱动直接连接数据库;
3、经过池化维护一定量的连接数目,用jndi去访问数据源对应池获取连接;

 

参考:http://www.diybl.com/course/7_databases/database_other/2008126/97740.html

posted @ 2012-01-16 09:19 timelyxyz 阅读(133) | 评论 (0)编辑 收藏

1. 控制输出时间
<div>
    <p>this part is cached for 10 seconds. Note the timeout spec with invoke overrides CacheFor annotation. </p>
    `a controllers.more.Portlets.panel2(b), "10s"
</div>
<p>内文字显示十秒钟然后进入panel2action

2.log:log directives are used to print a line of information to the console. It can take an argument of String
`log
`log a + i
`log "a message "
log命令用来在控制台输出一行信息,后面可以添加参数,输出结果如下:
japidviews/templates/log.html(line 5):
japidviews/templates/log.html(line 14): a10
japidviews/templates/log.html(line 18): a message

3.stopwatch m 输出render到模板所需的时间

4.~i  直接输出i的值

5.`each posts | String p 与`for String p : posts等价,
`for String p : posts
    <p>index: $_index, parity: $_parity, is odd? $_isOdd, is first? $_isFirst, is last? $_isLast, total size: $_size </p>
    call a tag:  `tag SampleTag p
`
输出index: 6, parity: even, is odd? false, is first? false, is last? true, total size: 6
另一种格式
`for (final Post p : posts) {
    another notation for invoking actions:  
    `invoke Application.echoPost(p)
`}

6.if-else循环语法:
    `if expr            `if(asBoolean(expr)){
        xxx                xxx    
    `else if expr        `} else if(asBoolean(expr)){
        yyy                yyy
    `else            `} else {
        zzz                zzz
    `            `

7.` suppressNull on如果下面出现了null的意外,如
` a = null;
safe to do a.something too: $a.length()
输出safe to do a.something too:

8.dontRedirect();控制不跳转页面,即停留在原页面。

说明:

∵在play运行时,调用一个action必须出发一个Http重定向

∴如果不想重定向,必须调用JapidController.dontRedirect()来避免

9.${a}, ~a, $a and ${escape(a)} and ~{a}这几种表达式的值相等

10.页面读取异常
    `for (Error e: errors()){
        <p>$e.getKey() : $e</p>
    `}

11.“Elvis操作符”是Java三目运算符的简写。一个便捷的用法是,如果表达式的值为false或者null,则返回一个合乎情理的默认值。好吧,我所实现的Elvis操作符确实不像Java中的一样:)我所添加的?:组合符号只在${}标签内起作用。
name ?: “empty”

12.`doBody m:带着参数回到原先界面。该命令中的参数列表必须与调用处的“|”之后的参数声明匹配,doBody通过匹配的参数传递到模板。

13.join(Strings, "|"):Strings是list,该方法为list中的每个元素见添加一个“|”,形成一个字符串。

14.`invoke与`a触发的action返回的结果直接插入到原先界面中,作为界面参数的一部分。注意:invoke出发的action不跳转页面。

15.renderJapid(Object... Objects):带着参数跳转到原先界面

16.renderJapidWith(String template, Object... args):带着参数跳转到指定模板,可以实现在一个action中渲染多种模板。

posted @ 2012-01-14 15:40 timelyxyz 阅读(298) | 评论 (0)编辑 收藏

junit4使用时导入的主要包org.junit.Assert.*;

1. setUp与tearDown:这两个方法是junit framework中提供初始化和反初始化每个测试方法的。
setUp是在每个测试方法调用前被调用,负责初始化测试方法所需要的测试环境;
tearDown是在每个测试方法被调用后被调用,负责撤销测试环境。
基本测试步骤如下:
测试开始 -> setUp -> testXXX -> tearDown -> 测试结束

2. public static void fail(java.lang.String message)输出错误信息

3.TestSuite 组装测试。可以讲所有的TestCase的调用添加到TestSuite中,同样,也可以添加另外的TestSuite到TestSuite中。

4.静态导入:就是在import关键字后面加上static,然后可以调用这个类中的方法就和调用自己的方法没有什么区别,例如assertEqual(excepted, actual),这个函数可以直接调
用,不需要加上类名或者实例对象等。

5.@Test(arg ...)被该annotation修士的方法,在JUint终将会被自动执行,该annotation只能修饰public void 方法。

6.@Test参数timeout:规定该方法执行的时间,如果设置参数,则被修饰方法必须在该事件被执行结束,否则会抛出异常。语法:@Test(timeout=1)// 时间的单位为毫秒

7.@Test参数expected:规定该方法排除异常,如果设置该参数,责备修饰方法在排除该参数规定的异常的情况下才可能通过测试,否则测试失败。for example
@Test(expected=ArithmeticException.class)
public void testExceptedF(){
    int i = 1/0;
}
此时,testExceptionF抛出了ArithmeticException异常,所以测试通过;如果测试失败,Failure Trace面板中会列出错误轨迹。

8.@After:被该annotation修饰的方法,将会在每个测试方法执行之后执行一次。该annotation只能修饰public void 方法。

9.@Before:被该annotation修饰的方法,将会在每个测试方法执行之前执行一次。该annotation只能修饰public void 方法。

10.@AfterClass:被该annotation修饰的方法,将会在所有测试方法执行结束后执行一次。该annotation只能修饰public static void 方法。

11.@BeforeClass:被该annotation修饰的方法,将会在所有测试方法执行前执行一次。该annotation只能修饰public static void 方法。

posted @ 2012-01-14 14:53 timelyxyz 阅读(99) | 评论 (0)编辑 收藏