午后星期午

2013年12月31日 #

Java 单例模式详解

     摘要: 概念:  java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。  单例模式有一下特点:  1、单例类只能有一个实例。  2、单例类必须自己自己创建自己的唯一实例。  3、单例类必须给所有其他对象提供这一实例。  单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对...  阅读全文

posted @ 2014-03-27 01:20 午后星期午 阅读(82) | 评论 (0)编辑 收藏

值传递、引用传递的区别

所谓值传递,就是说仅将对象的值传递给目标对象,就相当于copy;系统将为目标对象重新开辟一个完全相同的内存空间。
所谓引用,就是说将对象在内存中的地址传递给目标对象,就相当于使目标对象和原始对象对应同一个内存存储空间。此时,如果对目标对象进行修改,内存中的数据也会改变。
值传递,例如:
class TestT1 
public static void main(String[] args) 
int i = 5; 
int j = 6; 
System.out.println("before exchange i = "+i);//交换前
exchange(i, j); 
System.out.println("after exchange i = "+i);//交换后
}
public static void exchange(int a,int b) 
int k;
k = a;a = b; b = k; 
程序的结果是5!!! 
这说明,原始数据类型是按值传递的,这个按值传递也是指的是进行赋值时的行为。 
Java语言明确说明取消了指针,因为指针往往是在带来方便的同时也是导致代码不安全的根源,同时也会使程序的变得非常复杂难以理解,但这只是在Java语言中没有明确的指针定义,实质上每一个new语句返回的都是一个指针的引用。
引用传递,例如:
class TestT2
public static void main(String[] args) 
StringBuffer s= new StringBuffer("good"); 
StringBuffer s2=s; 
s2.append(" afternoon."); 
System.out.println(s); 
对象s和s2指向的是内存中的同一个地址因此指向的是同一个对象。 
这里的意思是进行对象赋值操作是传递的是对象的引用,因此对象是按引用传递的。 
程序运行的输出是: 
good afternoon. 
这说明s2和s是同一个对象。
总结: 
大家都知道,在JAVA中变量有以下两种:
基本类型变量,包括boolean、byte、char、short、int、long、float、double。
引用类型变量,包括类、接口、数组(基本类型数组和对象数组)。
对于基本类型和基本类型变量被当作参数传递给方法时,是值传递。在方法实体中,无法给原变量重新赋值,也无法改变它的值。
而对象作为参数,如果在方法中把对象作为参数,方法调用时,参数传递的是对象的引用,即在方法调用时,实际参数把对对象的引用传递给形式参数。这是实际参数与形式参数指向同一个地址,即同一个对象,方法执行时,对形式参数的改变实际上就是对实际参数的改变,这个结果在调用结束后被保留了下来。

形参和实参有以下显著的区别:
    1、形参不能离开方法。形参只有在方法内才会发生作用,也只有在方法中使用,不会在方法外可见。而实参可以再程序的任何地方都使用。
    2、形参代表一个合集,具有不确定性,而形参代表一个独立事物,具有确定性(即使是为null)。也就是说,形参不能代表具体的对象,只能代表这些对象共同的属性(比如超类、各种其他自定义属性等等),而实参则是具体的对象(比如超类的实例)。
    3、形参的值在调用时根据调用者更改,实参则用自身的值更改形参的值(指针、引用皆在此列)

posted @ 2014-03-26 22:29 午后星期午 阅读(128) | 评论 (0)编辑 收藏

使用Spring mvc 利用java的反射技术,来扫描对应包下的注解请求url 统一保存在数据库中

仅对  @requestMapping("/xxxx/其他参数")  的格式
 package cc.wshao.springmvc.util;
import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import cc.wshao.springmvc.service.RightService;
public class RegRightUtils {
private static final String rootUrl = "/spring";
private static RightService rightService;
public static void main(String[] args) throws Exception {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
  rightService = context.getBean(RightService.class);
ClassLoader classLoader = RegRightUtils.class.getClassLoader();
URL url = classLoader.getResource("com/er07/book/springmvc/controller");
String rootPath = url.getPath().toString();
File rootFile = new File(rootPath);
File [] files = rootFile.listFiles();
for(File f: files) {
System.err.println(f.getName());
String className = f.getName().substring(0, f.getName().indexOf(".class"));
Class clazz = Class.forName("com.er07.book.springmvc.controller."+className);
parseClass(clazz);  //解析  出url
}
 
}
public  static void parseClass(Class clazz) {
 
if(clazz.isAnnotationPresent(Controller.class)) {   //是否为一个controller ? 
String classUrl ="";
 if(clazz.isAnnotationPresent(RequestMapping.class)) {
 RequestMapping requestMapping_clazz = (RequestMapping) clazz.getAnnotation(RequestMapping.class);
  classUrl = requestMapping_clazz.value()[0];
  
  if(classUrl.equals("/")) {  //如果是"/" 的话  制空    
  classUrl ="";
  }
 }
 Method [] ms = clazz.getDeclaredMethods();
 
 for(Method m :ms) {
 
 if(m.isAnnotationPresent(RequestMapping.class)) {
 RequestMapping requestMapping_method = m.getAnnotation(RequestMapping.class);
 String methodUrl = requestMapping_method.value()[0];
 
   int  index = methodUrl.indexOf("/");
   index = methodUrl.indexOf("/",index+1);
   if(index!=-1) {  //如果存在 则进行截取前面的url 
   
    methodUrl = methodUrl.substring(0, index);
   }
 String resultUrl = rootUrl+classUrl+methodUrl;
 rightService.appendRightByUrl(resultUrl);
 }
 }
}
}
}
//实现方法: 
public void appendRightByUrl(String url) {
//查询 此url 在数据库中是否存在  此权限
String hql = "from Right where rightUrl =?";
Right r = (Right) this.rightDao.uniqueResult(hql, url);
if(r==null) { //不存在 , 插入数据库中
Right newRight = new Right();
newRight.setRightUrl(url);
this.saveOrUpdateRight(newRight);
}
}

posted @ 2014-03-25 14:54 午后星期午 阅读(1235) | 评论 (0)编辑 收藏

使用jQuery解析JSON数据

在本篇中,我们将使用jQuery进行数据解析。JSON数据如下,是一个嵌套JSON:

{"comments":[{"content":"很不错嘛","id":1,"nickname":"纳尼"},{"content":"哟西哟西","id":2,"nickname":"小强"}]}

获取JSON数据,在jQuery中有一个简单的方法 $.getJSON() 可以实现。

下面引用的是官方API对$.getJSON()的说明:

jQuery.getJSON( url, [data,] [success(data, textStatus, jqXHR)] )

urlA string containing the URL to which the request is sent.

dataA map or string that is sent to the server with the request.

success(data, textStatus, jqXHR)A callback function that is executed if the request succeeds.

回调函数中接受三个参数,第一个书返回的数据,第二个是状态,第三个是jQuery的XMLHttpRequest,我们只使用到第一个参数。

$.each()是用来在回调函数中解析JSON数据的方法,下面是官方文档:

jQuery.each( collection, callback(indexInArray, valueOfElement) )

collectionThe object or array to iterate over.

callback(indexInArray, valueOfElement)The function that will be executed on every object.

$.each()方法接受两个参数,第一个是需要遍历的对象集合(JSON对象集合),第二个是用来遍历的方法,这个方法又接受两个参数,第一个是遍历的index,第二个是当前遍历的值。哈哈,有了$.each()方法JSON的解析就迎刃而解咯。(*^__^*) 嘻嘻……

 

复制代码
function loadInfo() {
$.getJSON(
"loadInfo", function(data) {
$(
"#info").html("");//清空info内容
$.each(data.comments, function(i, item) {
$(
"#info").append(
"<div>" + item.id + "</div>" +
"<div>" + item.nickname + "</div>" +
"<div>" + item.content + "</div><hr/>");
});
});
}
复制代码

正如上面,loadinfo是请求的地址,function(data){...}就是在请求成功后的回调函数,data封装了返回的JSON对象,在下面的$.each(data.comments,function(i,item){...})方法中data.comments直接到达 JSON数据内包含的JSON数组:

[{"content":"很不错嘛","id":1,"nickname":"纳尼"},{"content":"哟西哟西","id":2,"nickname":"小强"}]

$.each()方法中的function就是对这个数组进行遍历,再通过操作DOM插入到合适的地方的。在遍历的过程中,我们可以很方便的访问当前遍历index(代码中的”i“)和当前遍历的值(代码中的”item“)。

上例的运行结果如下:

如果返回的JSON数据比较复杂,则只需多些$.each()进行遍历即可,嘿嘿。例如如下JSON数据:

{"comments":[{"content":"很不错嘛","id":1,"nickname":"纳尼"},{"content":"哟西哟西","id":2,"nickname":"小强"}],"content":"你是木头人,哈哈。","infomap":{"性别":"","职业":"程序员","博客":"http:\/\/www.cnblogs.com\/codeplus\/"},"title":"123木头人"}

js如下:

复制代码
function loadInfo() {
$.getJSON(
"loadInfo", function(data) {
$(
"#title").append(data.title+"<hr/>");
$(
"#content").append(data.content+"<hr/>");
//jquery解析map数据
$.each(data.infomap,function(key,value){
$(
"#mapinfo").append(key+"----"+value+"<br/><hr/>");
});
//解析数组
$.each(data.comments, function(i, item) {
$(
"#info").append(
"<div>" + item.id + "</div>" +
"<div>" + item.nickname + "</div>" +
"<div>" + item.content + "</div><hr/>");
});
});
}
复制代码

值得注意的是,$.each()遍历Map的时候,function()中的参数是key和value,十分方便。

上例的运行效果:

jQuery很强大,so...更多的了解还得参考文档,(ˇˍˇ) 想~

posted @ 2013-12-31 14:29 午后星期午 阅读(116) | 评论 (0)编辑 收藏

Spring的JNDI数据源连接池配置示例及Spring对JNDI实现分析

     摘要: 个人学习参考所用,勿喷!   在使用 Tomcat服务器 + SpringFramework 进行JavaEE项目的开发部署的时候可以在Tomcat的配置文件中进行JDBC数据源的配置,具体步骤如下(这里省略了工程的建立步骤):   1) 添加如下代码到tomcat的conf目录下的server.xml中: Xml代码   <Con...  阅读全文

posted @ 2013-12-31 14:28 午后星期午 阅读(340) | 评论 (0)编辑 收藏

重复提交、重复刷新、防止后退的问题以及处理方式

重复提交、重复刷新、防止后退的问题以及处理方式

一。前言
你在任何一个比较专业的BBS都会看到这样的问题,即使你Google一下,也会发现有很多的人在关注和询问,但大家给出的解决方法却都是千差万别,(有的人主张采用脚本来解决;有的则想重定向到别的页面;有的则将此问题提升到Token的角度)为什么会有如此大的差异呢?

二。问题场景
首先,我们应该先了解为什么要处理这样的问题?或者专业一点就是它适合的场景是什么?(似乎只有人来问没有人来解释)

1。重复提交、重复刷新的场景
重复提交、重复刷新都是来解决系统重复记录的问题。也就是说某个人在多次的提交某条记录(为什么?也许是闲了没有事情干的;最有可能是用户根本就不知道自己的提交结果是否已经执行了?!)。

但出现了这样的问题并不见得就必须处理,要看你所开发的系统的类别而定。比如你接手的是某个资源管理系统,系统本身从需求的角度根本就不允许出现" 重复"的记录,在这样需求的约束条件下,去执行重复的提交动作只会引发“业务级异常”的产生,根本就不可能执行成功也就无所谓避免不避免的问题了。

 

2。防止后退的场景
了解了重复刷新、重复提交的场景,我们来了解一下"防止后退"操作的原因是什么?比如你在开发某个投票系统,它有很多的步骤,并且这些步骤之间是有联系的,比如第一步会将某些信息发送给第二步,第二步缓存了这些信息,同时将自身的信息发送给了第三步。。。。。等等,如果此时用户处在第三步骤下,我们想象一下某个淘气用户的用户点击了后退按钮,此时屏幕出现了第二步骤的页面,他再次的修改或者再次的提交,进入到下一个步骤(也就是第三步骤),错误就会在此产生?!什么错误呢?最为典型的就是这样的操作直接导致了对于第一个步骤信息的丢失!(如果这样的信息是依靠Request存放的话,当然你可以存放在 Session或者更大的上下文环境中,但这不是个好主意!关于信息存放的问题,下次在就这个问题详细的讨论)


三。如何处理的问题
当然很多的系统(比如订票系统从需求上本身是允许个人重复订票的)是必须要避免重复刷新、重复提交、以及防止后退的问题的,但即使是这样的问题,也要区分如何处理以及在哪里处理的(网上只是告诉你如何处理,但很少去区分在哪里处理的),显然处理的方式无非是客户端或者服务器端两种,而面对不同的位置处理的方式也是不同的,但有一点要事先声明:任何客户端(尤其是B/S端)的处理都是不可信任的,最好的也是最应该的是服务器端的处理方法。

客户端处理:
面对客户端我们可以使用Javascript脚本来解决,如下

1。重复刷新、重复提交
Ways One:设置一个变量,只允许提交一次。
<script language="javascript">
    var checkSubmitFlg = false;
    function checkSubmit() {
      if (checkSubmitFlg == true) {
         return false;
      }
      checkSubmitFlg = true;
      return true;
   }
   document.ondblclick = function docondblclick() {
    window.event.returnValue = false;
   }
   document.onclick = function doconclick() {
       if (checkSubmitFlg) {
         window.event.returnValue = false;
       }
   }
</script>
<html:form action="myAction.do" method="post" onsubmit="return checkSubmit();">

Way Two : 将提交按钮或者image置为disable
  <html:form action="myAction.do" method="post" 
    onsubmit="getElById('submitInput').disabled = true; return true;">  
  <html:image styleId="submitInput" src="images/ok_b.gif" border="0" />
  </html:form> 

2。防止用户后退
这里的方法是千姿百态,有的是更改浏览器的历史纪录的,比如使用window.history.forward()方法;有的是“用新页面的URL替换当前的历史纪录,这样浏览历史记录中就只有一个页面,后退按钮永远不会变为可用。”比如使用 javascript:location.replace(this.href); event.returnValue=false;


2.服务器端的处理(这里只说Struts框架的处理)
利用同步令牌(Token)机制来解决Web应用中重复提交的问题,Struts也给出了一个参考实现。

基本原理:
服务器端在处理到达的请求之前,会将请求中包含的令牌值与保存在当前用户会话中的令牌值进行比较,
看是否匹配。在处理完该请求后,且在答复发送给客户端之前,将会产生一个新的令牌,该令牌除传给
客户端以外,也会将用户会话中保存的旧的令牌进行替换。这样如果用户回退到刚才的提交页面并再次
提交的话,客户端传过来的令牌就和服务器端的令牌不一致,从而有效地防止了重复提交的发生。

if (isTokenValid(request, true)) {
    // your code here
    return mapping.findForward("success");
} else {
    saveToken(request);
    return mapping.findForward("submitagain");
}

Struts根据用户会话ID和当前系统时间来生成一个唯一(对于每个会话)令牌的,具体实现可以参考
TokenProcessor类中的generateToken()方法。

1. //验证事务控制令牌,<html:form >会自动根据session中标识生成一个隐含input代表令牌,防止两次提交
2. 在action中:


       //<input type="hidden" name="org.apache.struts.taglib.html.TOKEN" 
       //  value="6aa35341f25184fd996c4c918255c3ae">
       if (!isTokenValid(request))
           errors.add(ActionErrors.GLOBAL_ERROR,
                      new ActionError("error.transaction.token"));
       resetToken(request); //删除session中的令牌

3. action有这样的一个方法生成令牌
   protected String generateToken(HttpServletRequest request) {
       HttpSession session = request.getSession();
       try {
           byte id[] = session.getId().getBytes();
           byte now[] =
               new Long(System.currentTimeMillis()).toString().getBytes();
           MessageDigest md = MessageDigest.getInstance("MD5");
           md.update(id);
           md.update(now);
           return (toHex(md.digest()));
       } catch (IllegalStateException e) {
           return (null);
       } catch (NoSuchAlgorithmException e) {
           return (null);
       }
   } 

总结
对于重复提交、重复刷新、防止后退等等都是属于系统为避免重复记录而需要解决的问题,在客户端去处理需要针对每一种的可能提出相应的解决方案,然而在服务器端看来只不过是对于数据真实性的检验问题,基于令牌的处理就是一劳永逸的方法。

同时我们也看到,从不同的角度去看待问题,其解决的方法也是不同的。客户端更追求的是用户的操作,而服务端则将注意力放在了数据的处理上,所以在某个对于服务器端看似容易的问题上,用客户端来解决却麻烦了很多!反之依然。所以在某些问题的处理上我们需要综合考虑和平衡,是用客户端来解决?还是用服务器端来处理?

[转载出处] http://blog.csdn.net/Killvin/

posted @ 2013-12-31 14:25 午后星期午 阅读(100) | 评论 (0)编辑 收藏

javascript 增,删,查,改 cookies

<script>

//写cookies函数 作者:翟振凯
function SetCookie(name,value)//两个参数,一个是cookie的名子,一个是值
{
    var Days = 30; //此 cookie 将被保存 30 天
    var exp  = new Date();    //new Date("December 31, 9998");
    exp.setTime(exp.getTime() + Days*24*60*60*1000);
    document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString();
}
function getCookie(name)//取cookies函数       
{
    var arr = document.cookie.match(new RegExp("(^| )"+name+"=([^;]*)(;|$)"));
     if(arr != null) return unescape(arr[2]); return null;

}
function delCookie(name)//删除cookie
{
    var exp = new Date();
    exp.setTime(exp.getTime() - 1);
    var cval=getCookie(name);
    if(cval!=null) document.cookie= name + "="+cval+";expires="+exp.toGMTString();
}



SetCookie ("xiaoqi", "3")
alert(getCookie('xiaoqi'));
</script>

一个非常实用的javascript读写Cookie函数

一个非常实用的javascript读写Cookie函数 
function  GetCookieVal(offset)
//获得Cookie解码后的值
{
var  endstr  =  documents.cookie.indexOf  (";",  offset);
if  (endstr  ==  -1)
endstr  =  documents.cookie.length;
return  unescape(documents.cookie.substring(offset,  endstr));
}
function  SetCookie(name,  value)
//设定Cookie值
{
var  expdate  =  new  Date();
var  argv  =  SetCookie.arguments;
var  argc  =  SetCookie.arguments.length;
var  expires  =  (argc  >  2)  ?  argv[2]  :  null;
var  path  =  (argc  >  3)  ?  argv[3]  :  null;
var  domain  =  (argc  >  4)  ?  argv[4]  :  null;
var  secure  =  (argc  >  5)  ?  argv[5]  :  false;
if(expires!=null)  expdate.setTime(expdate.getTime()  +  (  expires  *  1000  ));
documents.cookie  =  name  +  "="  +  escape  (value)  +((expires  ==  null)  ?  ""  :  (";  expires="+  expdate.toGMTString()))
+((path  ==  null)  ?  ""  :  (";  path="  +  path))  +((domain  ==  null)  ?  ""  :  (";  domain="  +  domain))
+((secure  ==  true)  ?  ";  secure"  :  "");
}
function  DelCookie(name)
//删除Cookie
{
var  exp  =  new  Date();
exp.setTime  (exp.getTime()  -  1);
var  cval  =  GetCookie  (name);
documents.cookie  =  name  +  "="  +  cval  +  ";  expires="+  exp.toGMTString();
}
function  GetCookie(name)
//获得Cookie的原始值
{
var  arg  =  name  +  "=";
var  alen  =  arg.length;
var  clen  =  documents.cookie.length;
var  i  =  0;
while  (i  <  clen)
{
var  j  =  i  +  alen;
if  (documents.cookie.substring(i,  j)  ==  arg)
return  GetCookieVal  (j);
i  =  documents.cookie.indexOf("  ",  i)  +  1;
if  (i  ==  0)  break;
}
return  null;
}


<SCRIPT  language="javascript">
<!--
function  openpopup(){
url="popup.htm"
window.open("gonggao.htm","gonggao","width=260,height=212,left=200,top=0")
}

function  get_cookie(Name)  {
var  search  =  Name  +  "="
var  returnvalue  =  "";
if  (documents.cookie.length  >  0)  {
offset  =  documents.cookie.indexOf(search)
if  (offset  !=  -1)  {
offset  +=  search.length
end  =  documents.cookie.indexOf(";",  offset);
if  (end  ==  -1)
end  =  documents.cookie.length;
returnvalue=unescape(documents.cookie.substring(offset,  end))
}
}
return  returnvalue;
}

function  helpor_net(){
if  (get_cookie('popped')==''){
openpopup()
documents.cookie="popped=yes"
}
}
helpor_net()
//-->
</SCRIPT>


如果点了确定,只要不清cookie,以后访问都不会再提示,如果不点确定则每次都会提示。放在js文件里,全站包含

<SCRIPT LANGUAGE="JavaScript">
<!--
var the_cookie = document.cookie;
var broken_cookie = the_cookie.split(":");
var the_visiteraccepted = unescape(broken_cookie[1]);
//
if (the_visiteraccepted=="undefined"){
        var tmp=confirm('中国人何时何地。');
        if(tmp==false){
                window.close();
        }else{
                var the_visiteraccepted = 1;        
        var the_cookie = "ILoveChina=visiteraccepted:" + escape(the_visiteraccepted);                                
        document.cookie = the_cookie;
        }
}
//-->
</SCRIPT>


1. Cookie的兼容性问题

Cookie的格式有2个不同的版本,第一个版本,我们称为Cookie Version 0,是最初由Netscape公司制定的,也被几乎所有的浏览器支持。而较新的版本,Cookie Version 1,则是根据RFC 2109文档制定的。为了确保兼容性,JAVA规定,前面所提到的涉及Cookie的操作都是针对旧版本的Cookie进行的。而新版本的Cookie目前还不被Javax.servlet.http.Cookie包所支持。

2. Cookie的内容

同样的 Cookie的内容的字符限制针对不同的Cookie版本也有不同。在Cookie Version 0中,某些特殊的字符,例如:空格,方括号,圆括号,等于号(=),逗号,双引号,斜杠,问号,@符号,冒号,分号都不能作为Cookie的内容。这也就是为什么我们在例子中设定Cookie的内容为"Test_Content"的原因。

虽然在Cookie Version 1规定中放宽了限制,可以使用这些字符,但是考虑到新版本的Cookie规范目前仍然没有为所有的浏览器所支持,因而为保险起见,我们应该在Cookie的内容中尽量避免使用这些字符

posted @ 2013-12-31 14:23 午后星期午 阅读(74) | 评论 (0)编辑 收藏

java的打包jar,war,ear包的作用,区别,打包方式(本文打jar)

一、java的打包jar,war,ear包的作用,区别,打包方式.

a)         作用与区别

                         i.              jar: 通常是开发时要引用通用(JAVA)类,打成包便于存放管理

                       ii.              war: 是做好一个(web)应用后,通常是网站,打成包部署到容器中

                      iii.              ear: 企业级应用,实际上EAR包中包含WAR包和几个企业级项目的配置文件而已,一般服务器选择WebSphere等,都会使用EAR包。通常是EJB打成ear包。

b)         打包方式

                         i.              所有的包都是用jar打的,只不过目标文件的扩展名不一样

                       ii.              也可以用Ant来安成构建

c)         JET编译成EXE

                         i.              JET   是要用钱买的,而且据说   JET   也不是能把所有的   Java   程序都编译成执行文件,性能也要打些折扣。所以,使用制作可执行   JAR   文件包的方法就是最佳选择了,何况它还能保持   Java   的跨平台特性。



二、实例

方法一:我现在有test/A.java
    道理虽然简单,但是在这过程中还是有很多细节需要注意的,哪一个细节注意不到,操作都不会成功。
package test;
public class A{
    
public static void main(String args[]){
        System.out.println(
"test java");
    }
}
    写好后,保存为A.java,存在D:\Java\jdk1.6\test_jar\test\目录下面,打开cmd,进入这个目录,即D:\Java \jdk1.6\test_jar\test\然后用javac命令编译,会生成一个A.class文件,此时类的编写工作已经完成。

    2,在D:\Java\jdk1.6\test_jar目录下新建一个文件夹META-INF,再新建mainclass.mf文件,在其中写入下面一行信息
    Main-Class: com/hp/HelloWorld
    这一句有两个注意的地方,首先行尾要有回车换行;其次“:”和“com”之间要有一个空格。
    这一行信息的作用是标明主类。

    3,最后就是生成jar包并测试了,在cmd中进入D:\Java\jdk1.6\test_jar目录,输入下列命令    
    jar cvfm test.jar META-INF/mainclass.mf test/A.class(这是指定文件,当然也可以test指向文件夹)
    上述命令执行成功的话,会提示“标明清单(manifest)...”,
    然后再在当前目录下输入java -jar test.jar 命令,可以看到“test java”。 
 


方法二:
    用简单的jar -cvf test.jar    test目录,jar会自动生成META-INF/mainclass.mf,我们只需要在里面去加一句 Main-Class: com/hp/HelloWorld
就可以了



方法三:myeclipse工具 (推荐
    右击项目--Export--Jar File-要选择Main-Class

方法四:ant

posted @ 2013-12-31 14:22 午后星期午 阅读(138) | 评论 (0)编辑 收藏

java枚举

1.枚举是jdk5.0以后的全新类,跟class,interface,annotation的级别一样;关键字enum。

2.第一个实例 
    public enum Color{ //定义
        Red,White,Blue;
        public static void main(){
            Color xx = Color.Red;//使用
        }
    }

3.enum 提供的常用方法
    //两个常用的静态方法 values(),valueOf()
    for(Color c : c.values()){
        System.out.println(c);
    }

4.enum 的构造方法
    publc enum Coin{
        penney(1),nickel(3),dime(10),quarter(25);

        private int value;
        public Coin(int value){
            this.value=value;
        }
        
        public static void main(String args[]){
            Coin c = Coin.quarter;
            System.out.println(c.getValue());
        } 
    }

5.enum的使用场所
    权限控制、游戏方向、需要固定产生类对象的数量

posted @ 2013-12-31 14:21 午后星期午 阅读(175) | 评论 (0)编辑 收藏

JavaScript中json对象和string对象之间的转化

json对象
var json = {aa:true,bb:true};
var json1 = {aa:'b',bb:{cc:true,dd:true}};
1:js操作json对象
   for(var item in json){
       alert(item);           //结果是 aa,bb, 类型是 string
       alert(typeof(item));
       alert(eval("json."+item));   //结果是true,true类型是boolean
       eval(("json."+item+"=false;"));   //改变json对象的值
   }

2:json对象转化为String对象的方法
1        /**
2          * json对象转字符串形式
3         */
4         function json2str(o) {
5             var arr = [];
6             var fmt = function(s) {
7                 if (typeof s == 'object' && s != null) return json2str(s);
8                 return /^(string|number)$/.test(typeof s) ? "'" + s + "'" : s;
9              }
10             for (var i in o) arr.push("'" + i + "':" + fmt(o[i]));
11             return '{' + arr.join(',') + '}';
12          }
3:string对象转化为json对象
function stringToJson(stringValue)
{
   eval("var theJsonValue = "+stringValue);
   return theJsonValue;
}

4:json数组转化为 String对象的方法(要掉要上面那个方法)
function JsonArrayToStringCfz(jsonArray)

   var JsonArrayString = "[";
   for(var i=0;i<jsonArray.length;i++){
   JsonArrayString=JsonArrayString+JsonToStringCfz(jsonArray[i])+",";
   }
   JsonArrayString = JsonArrayString.substring(0,JsonArrayString.length-1)+"]";
   return JsonArrayString;
}
5 利用json.js json转string

<script src="json2.js"></script>
<script>
var date = {myArr : ["a" , "b" , "c" , "d"] , count : 4};
var str = JSON.stringify(date);
alert(str);
</script>

posted @ 2013-12-31 14:20 午后星期午 阅读(101) | 评论 (0)编辑 收藏

SQL的四种连接-左外连接、右外连接、内连接、全连接

今天在看一个遗留系统的数据表的时候发现平时查找的视图是FULL OUT JOIN的,导致平时的数据记录要进行一些限制性处理,其实也可以设置视图各表为右外连接并在视图上设置各列的排序和筛选条件就可以达到效果。

 

联接条件可在FROM或WHERE子句中指定,建议在FROM子句中指定联接条件。WHERE和HAVING子句也可以包含搜索条件,以进一步筛选联接条件所选的行。    
联接可分为以下几类:    


1、内联接(典型的联接运算,使用像 =  或 <> 之类的比较运算符)。包括相等联接和自然联接。     
内联接使用比较运算符根据每个表共有的列的值匹配两个表中的行。例如,检索 students和courses表中学生标识号相同的所有行。   
    
2、外联接。外联接可以是左向外联接、右向外联接或完整外部联接。     
在 FROM子句中指定外联接时,可以由下列几组关键字中的一组指定:     

1)LEFT  JOIN或LEFT OUTER JOIN     
左向外联接的结果集包括  LEFT OUTER子句中指定的左表的所有行,而不仅仅是联接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值。       

2)RIGHT  JOIN 或 RIGHT  OUTER  JOIN     
右向外联接是左向外联接的反向联接。将返回右表的所有行。如果右表的某行在左表中没有匹配行,则将为左表返回空值。       
3)FULL  JOIN 或 FULL OUTER JOIN
完整外部联接返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表的选择列表列包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。   
    
3、交叉联接   
交叉联接返回左表中的所有行,左表中的每一行与右表中的所有行组合。交叉联接也称作笛卡尔积。    

FROM 子句中的表或视图可通过内联接或完整外部联接按任意顺序指定;但是,用左或右向外联接指定表或视图时,表或视图的顺序很重要。有关使用左或右向外联接排列表的更多信息,请参见使用外联接。     
    
例子:   

-------------------------------------------------
  a表     id   name     b表     id   job   parent_id   
              1   张3                   1     23     1   
              2   李四                 2     34     2   
              3   王武                 3     34     4       
  a.id同parent_id   存在关系   

--------------------------------------------------    
 1) 内连接   
  select   a.*,b.*   from   a   inner   join   b     on   a.id=b.parent_id       
  结果是     
  1   张3                   1     23     1   
  2   李四                  2     34     2   
    
  2)左连接   
  select   a.*,b.*   from   a   left   join   b     on   a.id=b.parent_id       
  结果是     
  1   张3                   1     23     1   
  2   李四                  2     34     2   
  3   王武                  null   

 

 3) 右连接   
  select   a.*,b.*   from   a   right   join   b     on   a.id=b.parent_id       
  结果是     
  1   张3                   1     23     1   
  2   李四                  2     34     2   
  null                       3     34     4   
    
 4) 完全连接   
  select   a.*,b.*   from   a   full   join   b     on   a.id=b.parent_id   

  结果是     
  1   张3                  1     23     1   
  2   李四                 2     34     2   
  null                   3     34     4   
  3   王武                 null

posted @ 2013-12-31 14:19 午后星期午 阅读(174) | 评论 (0)编辑 收藏

框架Quart在Java中任务调度的使用

Quartz框架是一个全功能、开源的任务调度服务,可以集成几乎任何的java应用程序—从小的单片机系统到大型的电子商务系统。Quartz可以执行上千上万的任务调度。

  核心概念

  Quartz核心的概念:scheduler任务调度、Job任务、Trigger触发器、JobDetail任务细节

  Job任务:其实Job是接口,其中只有一个execute方法:

  package org.quartz;

  public abstract interface Job

  {

  public abstract void execute(JobExecutionContext paramJobExecutionContext)

  throws JobExecutionException;

  }

  我们开发者只要实现此接口,实现execute方法即可。把我们想做的事情,在execute中执行即可。

  JobDetail:任务细节,Quartz执行Job时,需要新建个Job实例,但是不能直接操作Job类,所以通过JobDetail来获取Job的名称、描述信息。

  Trigger触发器:执行任务的规则;比如每天,每小时等。

  一般情况使用SimpleTrigger,和CronTrigger,这个触发器实现了Trigger接口。

  对于复杂的时间表达式来说,比如每个月15日上午几点几分,使用CronTrigger

  对于简单的时间来说,比如每天执行几次,使用SimpleTrigger

  scheduler任务调度:是最核心的概念,需要把JobDetail和Trigger注册到scheduler中,才可以执行。

  注意:

  不同的版本的jar包,具体的操作不太相同,但是tbw思路是相同的;比如1.8.6jar包中,JobDetail是个类,直接通过构造方法与Job类关联。SimpleTrigger和 CornTrigger是类;在2.0.2jar包中,JobDetail是个接口,SimpleTrigger和CornTrigger是接口

  不同版本测试:

  1.8.6jar包:
  package com.test;

  import java.util.Date;

  import org.quartz.Job;

  import org.quartz.JobExecutionContext;

  import org.quartz.JobExecutionException;

  /**

  * 需要执行的任务

  * @author lhy

  *

  */

  public class MyJob implements Job {

  @Override

  //把要执行的操作,写在execute方法中

  public void execute(JobExecutionContext arg0) throws JobExecutionException {

  System.out.println("测试Quartz"+new Date());

  }

  }
    
     使用SimpleTrigger触发器
  package com.test;

  import java.util.Date;

  import org.quartz.JobDetail;

  import org.quartz.Scheduler;

  import org.quartz.SchedulerException;

  import org.quartz.SchedulerFactory;

  import org.quartz.SimpleTrigger;

  import org.quartz.impl.StdSchedulerFactory;

  /**

  * 调用任务的类

  * @author lhy

  *

  */

  public class SchedulerTest {

  public static void main(String[] args) {

  //通过schedulerFactory获取一个调度器

  SchedulerFactory schedulerfactory=new StdSchedulerFactory();

  Scheduler scheduler=null;

  try{

  // 通过schedulerFactory获取一个调度器

  scheduler=schedulerfactory.getScheduler();

  // 创建jobDetail实例,绑定Job实现类

  // 指明job的名称,所在组的名称,以及绑定job类

  JobDetail jobDetail=new JobDetail("job1", "jgroup1", MyJob.class);

  // 定义调度触发规则,比如每1秒运行一次,共运行8次

  SimpleTrigger simpleTrigger=new SimpleTrigger("simpleTrigger","triggerGroup");

  // 马上启动

  simpleTrigger.setStartTime(new Date());

  // 间隔时间

  simpleTrigger.setRepeatInterval(1000);

  // 运行次数

  simpleTrigger.setRepeatCount(8);

  // 把作业和触发器注册到任务调度中

  scheduler.scheduleJob(jobDetail, simpleTrigger);

  // 启动调度

  scheduler.start();

  }catch(SchedulerException e){

  e.printStackTrace();

  }

  }

  }

     若使用CornTrigger触发器:

  [html]

  package com.test;

  import java.util.Date;

  import org.quartz.CronTrigger;

  import org.quartz.JobDetail;

  import org.quartz.Scheduler;

  import org.quartz.SchedulerException;

  import org.quartz.SchedulerFactory;

  import org.quartz.SimpleTrigger;

  import org.quartz.impl.StdSchedulerFactory;

  /**

  * 调用任务的类

  * @author lhy

  *

  */

  public class CronTriggerTest {

  public static void main(String[] args) {

  //通过schedulerFactory获取一个调度器

  SchedulerFactory schedulerfactory=new StdSchedulerFactory();

  Scheduler scheduler=null;

  try{

  // 通过schedulerFactory获取一个调度器

  scheduler=schedulerfactory.getScheduler();

  // 创建jobDetail实例,绑定Job实现类

  // 指明job的名称,所在组的名称,以及绑定job类

  JobDetail jobDetail=new JobDetail("job1", "jgroup1", MyJob.class);

  // 定义调度触发规则,每天上午10:15执行

  CronTrigger cornTrigger=new CronTrigger("cronTrigger","triggerGroup");

  // 执行规则表达式

  cornTrigger.setCronExpression("0 15 10 * * ? *");

  // 把作业和触发器注册到任务调度中

  scheduler.scheduleJob(jobDetail, cornTrigger);

  // 启动调度

  scheduler.start();

  }catch(Exception e){

  e.printStackTrace();

  }

  }

  }

  对于2.0.2jar包如下:

  其中的job类不变,主要是调度类如下:

  package com.test;

  import java.util.Date;

  import org.quartz.CronScheduleBuilder;

  import org.quartz.JobBuilder;

  import org.quartz.JobDetail;

  import org.quartz.Scheduler;

  import org.quartz.SchedulerException;

  import org.quartz.SchedulerFactory;

  import org.quartz.SimpleScheduleBuilder;

  import org.quartz.Trigger;

  import org.quartz.TriggerBuilder;

  import org.quartz.impl.StdSchedulerFactory;

  /**

  * 调用任务的类

  * @author lhy

  *

  */

  public class SchedulerTest {

  public static void main(String[] args) {

  //通过schedulerFactory获取一个调度器

  SchedulerFactory schedulerfactory=new StdSchedulerFactory();

  Scheduler scheduler=null;

  try{

  // 通过schedulerFactory获取一个调度器

  scheduler=schedulerfactory.getScheduler();

  // 创建jobDetail实例,绑定Job实现类

  // 指明job的名称,所在组的名称,以及绑定job类

  JobDetail job=JobBuilder.newJob(MyJob.class).withIdentity("job1", "jgroup1").build();

  // 定义调度触发规则

  // 使用simpleTrigger规则

  // Trigger trigger=TriggerBuilder.newTrigger().withIdentity("simpleTrigger", "triggerGroup")

  // .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(1).withRepeatCount(8))

  // .startNow().build();

  // 使用cornTrigger规则 每天10点42分

  Trigger trigger=TriggerBuilder.newTrigger().withIdentity("simpleTrigger", "triggerGroup")

  .withSchedule(CronScheduleBuilder.cronSchedule("0 42 10 * * ? *"))

  .startNow().build();

  // 把作业和触发器注册到任务调度中

  scheduler.scheduleJob(job, trigger);

  // 启动调度

  scheduler.start();

  }catch(Exception e){

  e.printStackTrace();

  }

  }

  }

  上述demo下载:1.8版本demo下载

  2.0版本demo下载

  对于CornExpress讲解如下:

  字段 允许值 允许的特殊字符

  秒 0-59 , - * /

  分 0-59 , - * /

  小时 0-23 , - * /

  日期 1-31 , - * ? / L W C

  月份 1-12 或者 JAN-DEC , - * /

  星期 1-7 或者 SUN-SAT , - * ? / L C #

  年(可选) 留空, 1970-2099 , - * /

  表达式 意义

  "0 0 12 * * ?" 每天中午12点触发

  "0 15 10 ? * *" 每天上午10:15触发

  "0 15 10 * * ?" 每天上午10:15触发

  "0 15 10 * * ? *" 每天上午10:15触发

  "0 15 10 * * ? 2005" 2005年的每天上午10:15触发

  "0 * 14 * * ?" 在每天下午2点到下午2:59期间的每1分钟触发

  "0 0/5 14 * * ?" 在每天下午2点到下午2:55期间的每5分钟触发

  "0 0/5 14,18 * * ?" 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发

  "0 0-5 14 * * ?" 在每天下午2点到下午2:05期间的每1分钟触发

  "0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:10和2:44触发

  "0 15 10 ? * MON-FRI" 周一至周五的上午10:15触发

  "0 15 10 15 * ?" 每月15日上午10:15触发

  "0 15 10 L * ?" 每月最后一日的上午10:15触发

  "0 15 10 ? * 6L" 每月的最后一个星期五上午10:15触发

  "0 15 10 ? * 6L 2002-2005" 2002年至2005年的每月的最后一个星期五上午10:15触发

  "0 15 10 ? * 6#3" 每月的第三个星期五上午10:15触发

  特殊字符 意义

  * 表示所有值;

  ? 表示未说明的值,即不关心它为何值;

  - 表示一个指定的范围;

  , 表示附加一个可能值;

  / 符号前表示开始时间,符号后表示每次递增的值;

  L("last") ("last") "L" 用在day-of-month字段意思是 "这个月最后一天";用在 day-of-week字段, 它简单意思是 "7" or "SAT"。 如果在day-of-week字段里和数字联合使用,它的意思就是 "这个月的最后一个星期几" – 例如: "6L" means "这个月的最后一个星期五". 当我们用“L”时,不指明一个列表值或者范围是很重要的,不然的话,我们会得到一些意想不到的结果。

  W("weekday") 只能用在day-of-month字段。用来描叙最接近指定天的工作日(周一到周五)。例如:在day-of-month字段用“15W”指“最接近这个月第15天的工作日”,即如果这个月第15天是周六,那么触发器将会在这个月第14天即周五触发;如果这个月第15天是周日,那么触发器将会在这个月第 16天即周一触发;如果这个月第15天是周二,那么就在tbw触发器这天触发。注意一点:这个用法只会在当前月计算值,不会越过当前月。“W”字符仅能在day-of-month指明一天,不能是一个范围或列表。也可以用“LW”来指定这个月的最后一个工作日。

  # 只能用在day-of-week字段。用来指定这个月的第几个周几。例:在day-of-week字段用"6#3"指这个月第3个周五(6指周五,3指第3个)。如果指定的日期不存在,触发器就不会触发。

  C 指和calendar联系后计算过的值。例:在day-of-month 字段用“5C”指在这个月第5天或之后包括calendar的第一天;在day-of-week字段用“1C”指在这周日或之后包括calendar的第一天

posted @ 2013-12-31 14:13 午后星期午 阅读(164) | 评论 (0)编辑 收藏

Java动态代理设计模式

 所谓动态代理类是在运行时生成的class,在生成它时,你必须提供一组interface给它,则动态代理类就宣称它实现了这些 interface。当然,动态代理类就充当一个代理,你不要企图它会帮你干实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。
  下面通过实例来说明:
  Subject.java 抽象借口:声明代理对象和真实对象的共同接口
  [java]
  public interface Subject {
  public void doSomething();
  }
  public interface Subject {
  public void doSomething();
  }
  RealSubject.java 真实被tb代理对象
  [java]
  public class RealSubject implements Subject {
  @Override
  public void doSomething() {
  System.out.println("RealSubject.doSomething");
  }
  }
  public class RealSubject implements Subject {
  @Override
  public void doSomething() {
  System.out.println("RealSubject.doSomething");
  }
  }

  DynamicProxy.java 代理对象
  [java]
  import java.lang.reflect.InvocationHandler;
  import java.lang.reflect.Method;
  public class DynamicProxy implements InvocationHandler {
  private Object object;
  public DynamicProxy(Object object) {
  this.object = object;
  }
  @Override
  public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
  System.out.println("Before Invoke ! method : " + method);
  //我们可以再代理方法调用前后添加功能
  Object result = method.invoke(object, args);
  System.out.println("object : " + object + " result : " + result + " args : " + args);
  System.out.println("After Invoke !");
  return result;
  }
  }
  import java.lang.reflect.InvocationHandler;
  import java.lang.reflect.Method;
  public class DynamicProxy implements InvocationHandler {
  private Object object;
  public DynamicProxy(Object object) {
  this.object = object;
  }
  @Override
  public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
  System.out.println("Before Invoke ! method : " + method);
  //我们可以再代理方法调用前后添加功能
  Object result = method.invoke(object, args);
  System.out.println("object : " + object + " result : " + result + " args : " + args);
  System.out.println("After Invoke !");
  return result;
  }
  }
  Client.java 测试
  [java]
  import java.lang.reflect.InvocationHandler;
  import java.lang.reflect.Proxy;
  public class Client {
  public static void main(String[] args) throws Exception {
  //创建目标对象,也就是被代理对象
  RealSubject realSubject = new RealSubject();
  //将目标对象交给代理
  InvocationHandler handler = new DynamicProxy(realSubject);
  // Class proxyClass = Proxy.getProxyClass(Subject.class.getClassLoader()
  // , new Class[]{Subject.class});
  // Subject subject = (Subject)proxyClass.getConstructor(new Class[]{InvocationHandler.class})
  // .newInstance(new Object[]{handler});
  //返回代理对象,相当于上面两句
  Subject subject = (Subject) Proxy.newProxyInstance(handler.getClass().getClassLoader(),
  realSubject.getClass().getInterfaces(),
  handler);
  //叫代理对象去doSomething(),其实在代理对象中的doSomething()中还是会
  //用handler来调用invoke(proxy, method, args) 参数proxy为调用者subject(this),
  //method为doSomething(),tb参数为方法要传入的参数,这里没有
  subject.doSomething();
  }
  }
  import java.lang.reflect.InvocationHandler;
  import java.lang.reflect.Proxy;
  public class Client {
  public static void main(String[] args) throws Exception {
  //创建目标对象,也就是被代理对象
  RealSubject realSubject = new RealSubject();
  //将目标对象交给代理
  InvocationHandler handler = new DynamicProxy(realSubject);
  // Class proxyClass = Proxy.getProxyClass(Subject.class.getClassLoader()
  // , new Class[]{Subject.class});
  // Subject subject = (Subject)proxyClass.getConstructor(new Class[]{InvocationHandler.class})
  // .newInstance(new Object[]{handler});
  //返回代理对象,相当于上面两句
  Subject subject = (Subject) Proxy.newProxyInstance(handler.getClass().getClassLoader(),
  realSubject.getClass().getInterfaces(),
  handler);
  //叫代理对象去doSomething(),其实在代理对象中的doSomething()中还是会
  //用handler来调用invoke(proxy, method, args) 参数proxy为调用者subject(this),
  //method为doSomething(),参数为方法要传入的参数,这里没有
  subject.doSomething();
  }
  }
  打印结果:
  Before Invoke ! method : public abstract void Subject.doSomething()
  RealSubject.doSomething
  object : RealSubject@ec6b00 result : null args : null
  After Invoke !
  注意:
  Java动态代理涉及到的两个类:
  InvocationHandler:该接口中仅定义了一个Object : invoke(Object proxy, Method method, Object[] args);参数proxy指代理类,method表示被代理的方法,args为method中的参数数组,返回值Object为代理实例的方法调用返回的值。这个抽象方法在代理类中动态实现。
  Proxy:所有动态代理类的父类,提供用于创建动态代理类和实例的静态方法。

posted @ 2013-12-31 14:07 午后星期午 阅读(109) | 评论 (0)编辑 收藏

Java数组使用实用的技巧

本文分享了关于Java数组最顶级的11大方法,帮助你解决工作流程问题,无论是运用在团队环境或是在私人项目中,你都可以直接拿来用!

0.  声明一个数组(Declare an array)
 
String[] aArray = new String[5];
String[] bArray = {"a","b","c", "d", "e"};
String[] cArray = new String[]{"a","b","c","d","e"};

1.  在Java中输出一个数组(Print an array in Java)
 
int[] intArray = { 1, 2, 3, 4, 5 };
String intArrayString = Arrays.toString(intArray);
 
// print directly will print reference value
System.out.println(intArray);
// [I@7150bd4d
 
System.out.println(intArrayString);
// [1, 2, 3, 4, 5]

2. 从数组中创建数组列表(Create an ArrayList from an array)
 
String[] stringArray = { "a", "b", "c", "d", "e" };
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(stringArray));
System.out.println(arrayList);
// [a, b, c, d, e]

3. 检查爱淘宝数组中是否包含特定值(Check if an array contains a certain value)
 
String[] stringArray = { "a", "b", "c", "d", "e" };
boolean b = Arrays.asList(stringArray).contains("a");
System.out.println(b);
// true
 
4. 连接两个数组( Concatenate two arrays)
 
int[] intArray = { 1, 2, 3, 4, 5 };
int[] intArray2 = { 6, 7, 8, 9, 10 };
// Apache Commons Lang library
int[] combinedIntArray = ArrayUtils.addAll(intArray, intArray2);
5. 声明一个数组内链(Declare an array inline )
 
method(new String[]{"a", "b", "c", "d", "e"});
 
6. 将数组元素加入到一个独立的字符串中(Joins the elements of the provided array into a single String)

// containing the provided list of elements
// Apache common lang
String j = StringUtils.join(new String[] { "a", "b", "c" }, ", ");
System.out.println(j);
// a, b, c
 
7. 将数组列表转换成一个数组 (Covnert an ArrayList to an array)
 
String[] stringArray = { "a", "b", "c", "d", "e" };
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(stringArray));
String[] stringArr = new String[arrayList.size()];
arrayList.toArray(stringArr);
for (String s : stringArr)
    System.out.println(s);
 
8. 将数组转换成一个集合(Convert an array to a set)
 
Set<String> set = new HashSet<String>(Arrays.asList(stringArray));
System.out.println(set);
//[d, e, b, c, a]
 
9. 反向数组(Reverse an array)
 
int[] intArray = { 1, 2, 3, 4, 5 };
ArrayUtils.reverse(intArray);
System.out.println(Arrays.toString(intArray));
//[5, 4, 3, 2, 1]
 
10. 删除数组元素(Remove element of an array)
 
int[] intArray = { 1, 2, 3, 4, 5 };
int[] removed = ArrayUtils.removeElement(intArray, 3);
//create a new array
System.out.println(Arrays.toString(removed));
 
One more – convert int to byte array
 
byte[] bytes = ByteBuffer.allocate(4).putInt(8).array();
 
for (byte t : bytes) {
   System.out.format("0x%x ", t);
}

posted @ 2013-12-31 14:07 午后星期午 阅读(92) | 评论 (0)编辑 收藏

JS计算包含英文与汉字的字符串长度(一个汉字=2个字节)

function countbCharacters(str)
{
    var totalCount = 0;
    for (var i=0; i<str.length; i++)
    {
        var c = str.charCodeAt(i);
        if ((c >= 0x0001 && c <= 0x007e) || (0xff60<=c && c<=0xff9f))
        {
             totalCount++;
        }
        else
            
             totalCount+=2;
        }
     }
    return totalCount;
}

posted @ 2013-12-31 14:06 午后星期午 阅读(230) | 评论 (0)编辑 收藏

JS截取字符长度(按字节)

  1.  处理过长的字符串,截取并添加省略号 
  2.  注:半角长度为1,全角长度为2 
  3.   
  4.  pStr:字符串 
  5.  pLen:截取长度 
  6.   
  7.  return: 截取后的字符串 
  8.  *
  9. function autoAddEllipsis(pStr, pLen)  
  10.   
  11.     var _ret cutString(pStr, pLen);  
  12.     var _cutFlag _ret.cutflag;  
  13.     var _cutStringn _ret.cutstring;  
  14.   
  15.     if ("1" == _cutFlag)  
  16.         return _cutStringn "..." 
  17.     else  
  18.         return _cutStringn;  
  19.      
  20.  
  21.   
  22. * 
  23.  取得指定长度的字符串 
  24.  注:半角长度为1,全角长度为2 
  25.   
  26.  pStr:字符串 
  27.  pLen:截取长度 
  28.   
  29.  return: 截取后的字符串 
  30.  *
  31. function cutString(pStr, pLen)  
  32.   
  33.     // 原字符串长度  
  34.     var _strLen pStr.length;  
  35.   
  36.     var _tmpCode;  
  37.   
  38.     var _cutString;  
  39.   
  40.     // 默认情况下,返回的字符串是原字符串的一部分  
  41.     var _cutFlag "1" 
  42.   
  43.     var _lenCount 0;  
  44.   
  45.     var _ret false 
  46.   
  47.     if (_strLen <= pLen/2)  
  48.         _cutString pStr;  
  49.         _ret true 
  50.      
  51.   
  52.     if (!_ret)  
  53.         for (var 0; _strLen i++  
  54.             if (isFull(pStr.charAt(i)))  
  55.                 _lenCount += 2;  
  56.             else  
  57.                 _lenCount += 1;  
  58.              
  59.   
  60.             if (_lenCount pLen)  
  61.                 _cutString pStr.substring(0, i);  
  62.                 _ret true 
  63.                 break 
  64.             else if (_lenCount == pLen)  
  65.                 _cutString pStr.substring(0, 1);  
  66.                 _ret true 
  67.                 break 
  68.              
  69.          
  70.      
  71.       
  72.     if (!_ret)  
  73.         _cutString pStr;  
  74.         _ret true 
  75.      
  76.   
  77.     if (_cutString.length == _strLen)  
  78.         _cutFlag "0" 
  79.      
  80.   
  81.     return {"cutstring":_cutString, "cutflag":_cutFlag};  
  82.  
  83.   
  84. * 
  85.  判断是否为全角 
  86.   
  87.  pChar:长度为1的字符串 
  88.  return: tbtrue:全角 
  89.           false:半角 
  90.  * 

  91.   
  92. function isFull (pChar) 
  93.   for (var 0; < pChar.strLen i++     
  94.     if ((pChar.charCodeAt(i) 128))  
  95.         return true 
  96.     else  
  97.         return false 
  98.     
  99. }
  100. }
  101. 用例:
  102. testStr = "测试1字符串";
    autoAddEllipsis(testStr, 1); // "测..."
    autoAddEllipsis(testStr, 2); // "测..."
    autoAddEllipsis(testStr, 3); // "测..."
    autoAddEllipsis(testStr, 4); // "测试..."
    autoAddEllipsis(testStr, 5); // "测试1..."
    autoAddEllipsis(testStr, 6); // "测试1..."
    autoAddEllipsis(testStr, 7); // "测试1字..."

posted @ 2013-12-31 14:04 午后星期午 阅读(110) | 评论 (0)编辑 收藏

JS 获取字符串长度,截取字符串(中英文,一个汉字相当于2个字符)

<script type="text/javascript">
//一个汉字相当于2个字符
    function get_length(s){
        var char_length = 0;
        for (var i = 0; i < s.length; i++){
            var son_char = s.charAt(i);
            encodeURI(son_char).length > 2 ? char_length += 1 : char_length += 0.5;
        }
        return char_length;
    }
    function cut_str(stbr, len){
        var char_length = 0;
        for (var i = 0; i < str.length; i++){
            var son_str = str.charAt(i);
            encodeURI(son_str).length > 2 ? char_length += 1 : char_length += 0.5;
            if (char_length >= len){
                var sub_len = char_length == len ? i+1 : i;
                return str.substr(0, sub_len);
                break;
            }
        }
    }
//  截取15个字(30个字符)
//  cut_str('aa啊啊啊啊啊啊啊啊啊啊啊啊啊k的啊是', 15);
</script>

posted @ 2013-12-31 14:04 午后星期午 阅读(181) | 评论 (0)编辑 收藏

通过JAVA获取优酷、土豆、酷6、6间房等视频

     摘要: 通过JAVA获取优酷、土豆、酷6、6间房、56视频,现在很多社会网站都有这个功能,用户输入优酷、土豆、酷6、6间房、56视频地址后,能找到对应的视频及视频的缩略图,有些社区网站还能获取到视频的时长。 比如:新浪微博就有这个功能,当用户输入优酷、土豆、酷6、6间房、56视频网址后,就能获取到相应的视频地址及视频的缩略图。代码如下: import org.jsoup.Jsoup;imp...  阅读全文

posted @ 2013-12-31 13:59 午后星期午 阅读(83) | 评论 (0)编辑 收藏

通过java获取mac地址

package  cc.wshao.util;

import  java.io.BufferedReader;
import  java.io.InputStreamReader;
import  java.util.regex.Matcher;
import  java.util.regex.Pattern;

public   class  GetMacAddress {
     
     
public   static  String callCmd(String[] cmd) {  
         String result 
=   "" ;  
         String line 
=   "" ;  
         
try  {  
             Process proc 
=  Runtime.getRuntime().exec(cmd);  
             InputStreamReader is 
=   new  InputStreamReader(proc.getInputStream());  
             BufferedReader br 
=   new  BufferedReader (is);  
             
while  ((line  =  br.readLine ())  !=   null ) {  
             result 
+=  line;  
             }  
         }  
         
catch (Exception e) {  
             e.printStackTrace();  
         }  
         
return  result;  
     }
     
     
     
     
     
/**  
      * 
      * 
@param  cmd  第一个命令 
      * 
@param  another 第二个命令 
      * 
@return    第二个命令的执行结果 
      
*/   
     
public   static  String callCmd(String[] cmd,String[] another) {  
         String result 
=   "" ;  
         String line 
=   "" ;  
         
try  {  
             Runtime rt 
=  Runtime.getRuntime();  
             Process proc 
=  rt.exec(cmd);  
             proc.waitFor();  
// 已经执行完第一个命令,准备执行第二个命令  
             proc  =  rt.exec(another);  
             InputStreamReader is 
=   new  InputStreamReader(proc.getInputStream());  
             BufferedReader br 
=   new  BufferedReader (is);  
             
while  ((line  =  br.readLine ())  !=   null ) {  
                 result 
+=  line;  
             }  
         }  
         
catch (Exception e) {  
             e.printStackTrace();  
         }  
         
return  result;  
     }
     
     
     
     
/**  
      * 
      * 
@param  ip  目标ip,一般在局域网内 
      * 
@param  sourceString 命令处理的结果字符串 
      * 
@param  macSeparator mac分隔符号 
      * 
@return   mac地址,用上面的分隔符号表示 
      
*/   
     
public   static  String filterMacAddress( final  String ip,  final  String sourceString, final  String macSeparator) {  
         String result 
=   "" ;  
         String regExp 
=   " ((([0-9,A-F,a-f]{1,2} "   +  macSeparator  +   " ){1,5})[0-9,A-F,a-f]{1,2}) " ;  
         Pattern pattern 
=  Pattern.compile(regExp);  
         Matcher matcher 
=  pattern.matcher(sourceString);  
         
while (matcher.find()){  
             result 
=  matcher.group( 1 );  
             
if (sourceString.indexOf(ip)  <=  sourceString.lastIndexOf(matcher.group( 1 ))) {  
                 
break ;   // 如果有多个IP,只匹配本IP对应的Mac.  
             }  
         }
   
         
return  result;  
     }
     
     
     
     
/**  
      * 
      * 
@param  ip 目标ip 
      * 
@return    Mac Address 
      * 
      
*/   
     
public   static  String getMacInWindows( final  String ip){  
         String result 
=   "" ;  
         String[] cmd 
=  {  
                 
" cmd " ,  
                 
" /c " ,  
                 
" ping  "   +   ip  
                 };  
         String[] another 
=  {  
                 
" cmd " ,  
                 
" /c " ,  
                 
" arp -a "   
                 };  
   
         String cmdResult 
=  callCmd(cmd,another);  
         result 
=  filterMacAddress(ip,cmdResult, " - " );  
   
         
return  result;  
     }  
   
   
     
/**  
     * 
     * 
@param  ip 目标ip 
     * 
@return    Mac Address 
     * 
     
*/   
     
public   static  String getMacInLinux( final  String ip){  
         String result 
=   "" ;  
         String[] cmd 
=  {  
                 
" /bin/sh " ,  
                 
" -c " ,  
                 
" ping  "   +   ip  +   "  -c 2 && arp -a "   
                 };  
         String cmdResult 
=  callCmd(cmd);  
         result 
=  filterMacAddress(ip,cmdResult, " : " );  
   
         
return  result;  
     }  
     
     
/**
      * 获取MAC地址 
      * 
@return  返回MAC地址
      
*/
     
public   static  String getMacAddress(String ip){
         String macAddress 
=   "" ;
         macAddress 
=  getMacInWindows(ip).trim();
         
if (macAddress == null || "" .equals(macAddress)){
             macAddress 
=  getMacInLinux(ip).trim();
         }
         
return  macAddress;
     }
   
     
/**  
     * 测试 
     
*/   
     
public   static   void  main(String[] args) {           
         System.out.println(getMacAddress(
" 192.168.10.203 " ));
     }
     

}

posted @ 2013-12-31 13:58 午后星期午 阅读(113) | 评论 (0)编辑 收藏

Ehcache详细解读

     摘要: Ehcache  是现在最流行的纯Java开源缓存框架,配置简单、结构清晰、功能强大,最初知道它,是从Hibernate的缓存开始的。网上中文的EhCache材料以简单介绍和配置方法居多,如果你有这方面的问题,请自行google;对于API,官网上介绍已经非常清楚,请参见官网;但是很少见到特性说明和对实现原理的分析,因此在这篇文章里面,我会详细介绍和分析EhCache的特性,加上一些自己...  阅读全文

posted @ 2013-12-31 13:56 午后星期午 阅读(107) | 评论 (0)编辑 收藏

忘掉jQuery,使用JavaScript原生API

     摘要: jQuery 目前已经成为最流行的JavaScript库,它可以让开发者“write less, do more(写得更少,做得更多)”,这也是它的核心理念。通过它,用户可以更方便地处理HTML documents、events,更轻松地实现动画效果、AJAX交互等。  尽管jQuery帮助开发者节省了大量的工作,但是并不是所有的产品都适合使用jQuery。jQu...  阅读全文

posted @ 2013-12-31 13:55 午后星期午 阅读(95) | 评论 (0)编辑 收藏

Hibernate ehcache配置二级缓存

     摘要:   1、首先设置EhCache,建立配置文件ehcache.xml,默认的位置在class-path,可以放到你的src目录下:<?xml version="1.0" encoding="UTF-8"?><ehcache> <diskStore path="java.io.tmpdir"/>   <defaultCache   maxEleme...  阅读全文

posted @ 2013-12-31 13:54 午后星期午 阅读(137) | 评论 (0)编辑 收藏

Spring邮件服务之附件:Maven + Spring SMTP Mail With Attachment

     摘要: 前言:说过了 Spring 如何发送 Email 之后,接着来说一下,怎么样用 Spring 来发送带有附件的邮件,其实实现这个也很简单,Spring 的官方文档也有给出例子,下面来说下我的实现。环境: Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/...  阅读全文

posted @ 2013-12-31 13:52 午后星期午 阅读(266) | 评论 (0)编辑 收藏

Spring邮件服务之Html:Maven + Spring SMTP Mail With Html

     摘要: 前言:谈过如何用 Spring 发送普通 Email 和带有附件的 Email 之后,接着来谈一下如何用 Spring 来发送 Html 式的 Email。发送 Html 格式的 Email 也是很必要的,现在的很多网站在用户注册之后都会发一封 Email 到用户的邮箱,用户需要点击邮件中的链接来完成注册,这个链接如果是用普通文本式的 Email 来发送的话,这个链接是不能被点击的,因为它是文本内...  阅读全文

posted @ 2013-12-31 13:52 午后星期午 阅读(213) | 评论 (0)编辑 收藏

Spring邮件服务:Maven + Spring SMTP Mail

     摘要: 前言:当然,发 email 不一定要用 Spring,直接用 javax.mail 的API 就能实现。但是由于 Spring 提供了一个发送电子邮件的高级抽象层,它向用户屏蔽了底层邮件系统的一些细节,同时负责低层次的代表客户端的资源处理。所以用 Spring 来发送 email 会省事很多和让发邮件变的简单许多。Spring邮件抽象层的主要包为org.springframework.mail。它...  阅读全文

posted @ 2013-12-31 13:50 午后星期午 阅读(296) | 评论 (0)编辑 收藏

java 插入排序

     摘要: 不扯太多概念性的东西,简单点来说,插入排序 将数组所有元素划分成了有序区和无序区,假设当前数组有 N 个元素,开始默认第一个元素(下标为0)所处的位置是有序区,这是局部有序,从第二个元素(i=1)至数组最后一个元素(i=N-1)属于无序区;假设数组元素是按从左至右存放的,如果用 i 来标记无序区中的第一个元素下标,也就是无序区中最左边或者说是无序区中下标值最小的下标,则每趟排序是将下标 i 所指向...  阅读全文

posted @ 2013-12-31 13:49 午后星期午 阅读(69) | 评论 (0)编辑 收藏

JFreeChart 生成 折线图(Struts2 + Maven3 + JFreeChart)

     摘要: 接上一篇随笔 JFreeChart 生成 柱状图 ,环境及其配置不变,只是将生成柱状图的核心类 CylinderAction 替换成 CurveAction,让 CurveAction来负责折线图的生成,看下代码: Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlig...  阅读全文

posted @ 2013-12-31 13:48 午后星期午 阅读(102) | 评论 (0)编辑 收藏

java 双向冒泡排序

     摘要: 与单向冒泡相似的,双向冒泡排序就是在一趟排序完成之后,同时向两端有序的将元素冒出,使得两端总是保持有序状态,中间无序。假设有 N 个待排序元素,则最多只需要 N /2 趟排序,就能使得所有元素变成有序的了。由于最近在搞排序算法,当然,在写这篇随笔之前也有在网上搜索过与双向冒泡排序相关的资料,我找到的都是通过嵌套了 while 循环语句来实现双向冒泡排序的,而我接下来的,并没有这样做,而是直接在单向...  阅读全文

posted @ 2013-12-31 13:48 午后星期午 阅读(118) | 评论 (0)编辑 收藏

JFreeChart 生成 饼状图(Struts2 + Maven3 + JFreeChart)

接上一篇随笔 JFreeChart 生成 柱状图 ,环境及其配置不变,只是将生成柱状图的核心类 CylinderAction 替换成 PieAction,让 PieAction 来负责饼状图的生成,看下代码:



package com.fancy.action;

import java.awt.Color;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.servlet.ServletUtilities;
import org.jfree.data.general.DefaultPieDataset;
/**
 * -----------------------------------------
 * @描述  饼状图
 * @作者  fancy
 * @邮箱  fancydeepin@yeah.net
 * @日期  2012-8-7 <p>
 * -----------------------------------------
 
*/

public class PieAction extends BaseAction{

    
private static final long serialVersionUID = 1L;
    
private String fileName;
    
    
public String execute() throws Exception{
        
        
//创建Dataset对象
        DefaultPieDataset dataset = new DefaultPieDataset();
        
//模拟数据
        dataset.setValue("E-1区"50);
        dataset.setValue(
"E-2区"150);
        dataset.setValue(
"E-3区"80);
        dataset.setValue(
"E-4区"140);
        dataset.setValue(
"E-5区"180);
        dataset.setValue(
"E-6区"130);
        dataset.setValue(
"E-7区"100);
        
//创建3D饼状图
        JFreeChart chart = ChartFactory.createPieChart3D("2011年A产品销售量", dataset, truefalsefalse);
        
//设置背景颜色
        chart.setBackgroundPaint(Color.WHITE);
        
//保存图表
        fileName = ServletUtilities.saveChartAsPNG(chart, 500300null, getHttpSession());
        
return "pie";
    }

    
    
public String getFileName() {
        
return fileName;
    }


}



将 cylinder.jsp 拷贝一份名字改成 pie.jsp,其余不变,访问:http://localhost:8080/jfreechart-demo/pie.html 的结果如图示:



从上图可以看出A产品在每个区销售的大概份额,但是默认并没有给显示所占的百分比,下面通过添加代码来使得所占百分比能够显示出来:


package com.fancy.action;

import java.awt.Color;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.servlet.ServletUtilities;
import org.jfree.data.general.DefaultPieDataset;
/**
 * -----------------------------------------
 * @描述  饼状图
 * @作者  fancy
 * @邮箱  fancydeepin@yeah.net
 * @日期  2012-8-7 <p>
 * -----------------------------------------
 
*/

public class PieAction extends BaseAction{

    
private static final long serialVersionUID = 1L;
    
private String fileName;
    
    
public String execute() throws Exception{
        
        
//创建Dataset对象
        DefaultPieDataset dataset = new DefaultPieDataset();
        
//模拟数据
        dataset.setValue("E-1区"50);
        dataset.setValue(
"E-2区"150);
        dataset.setValue(
"E-3区"80);
        dataset.setValue(
"E-4区"140);
        dataset.setValue(
"E-5区"180);
        dataset.setValue(
"E-6区"130);
        dataset.setValue(
"E-7区"100);
        
//创建3D饼状图
        JFreeChart chart = ChartFactory.createPieChart3D("2011年AA产品销售量", dataset, truefalsefalse);
        
//设置背景颜色
        chart.setBackgroundPaint(Color.WHITE);
        
        PiePlot plot 
= (PiePlot)chart.getPlot();
        
// 图片中显示百分比:自定义方式,{0} 表示选项, {1} 表示数值,{2} 表示所占比例 ,小数点后两位 
        plot.setLabelGenerator(new StandardPieSectionLabelGenerator("{0}={1}({2})", NumberFormat.getNumberInstance(),new DecimalFormat("0.00%")));
        
        
//保存图表
        fileName = ServletUtilities.saveChartAsPNG(chart, 500300null, getHttpSession());
        
return "pie";
    }

    
    
public String getFileName() {
        
return fileName;
    }


}



OK,再次访问的结果如图示:






   [ 转载出处:http://www.blogjava.net/fancydeepin ]

posted @ 2013-12-31 13:47 午后星期午 阅读(68) | 评论 (0)编辑 收藏

JFreeChart 生成 柱状图(Struts2 + Maven3 + JFreeChart)

     摘要: 准备环境: Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->eclipse   3.6maven   3.0.4struts     2.1.8JFreeCha...  阅读全文

posted @ 2013-12-31 13:46 午后星期午 阅读(92) | 评论 (0)编辑 收藏

java 泛型深入

     摘要: 泛型的好处:    泛型的主要好处就是让编译器保留参数的类型信息,执行类型检查,执行类型转换(casting)操作,编译器保证了这些类型转换(casting)的绝对无误。 Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.co...  阅读全文

posted @ 2013-12-31 13:45 午后星期午 阅读(100) | 评论 (0)编辑 收藏

Spring AOP + AspectJ framework

     摘要: AOP(Aspect Orient Programming),也就是常说的面向方面编程,它是作为面向对象编程的一种补充,专门用于处理系统中分布于各个模块(不同方法)中的交叉关注点的问题,在 Java EE 应用中,常常通过 AOP 来处理一些具有横切性质的系统级服务,如事务管理、安全检查、缓存、对象池管理等。简单点来说,它就是一个拦截器可以拦截一些进程,例如,当某个方法执行时,Spring AOP...  阅读全文

posted @ 2013-12-31 13:43 午后星期午 阅读(151) | 评论 (0)编辑 收藏

hibernate one-to-many many-to-one 双向注解

环境:
Hibernate 3.3.1 
Maven 3.0.4 
MySQL 5.5.13 
Myeclipse 8.6.1 

建表语句:

DROP TABLE IF EXISTS `t_company`;
CREATE TABLE `t_company` (
  `companyId` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `companyName` varchar(30) NOT NULL,
  PRIMARY KEY (`companyId`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=gb2312;

INSERT INTO `t_company` VALUES ('1', 'Sun');
INSERT INTO `t_company` VALUES ('2', 'Apache');
DROP TABLE IF EXISTS `t_employee`;
CREATE TABLE `t_employee` (
  `employeeId` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `employeeName` varchar(15) NOT NULL,
  `cid` int(10) unsigned NOT NULL,
  PRIMARY KEY (`employeeId`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=gb2312;

INSERT INTO `t_employee` VALUES ('1', 'Tom', '1');
INSERT INTO `t_employee` VALUES ('2', 'Summ', '1');
INSERT INTO `t_employee` VALUES ('3', 'Cat', '2');
INSERT INTO `t_employee` VALUES ('4', 'Vinylon', '1');
INSERT INTO `t_employee` VALUES ('5', 'Dog', '2');

目录结构:

Employee.java

package com.fancy.po;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
/**
 * -----------------------------------------
 * @文件: Employee.java
 * @作者: fancy
 * @邮箱: fancyzero@yeah.net
 * @时间: 2012-6-10
 * @描述: 实体类
 * -----------------------------------------
 */
/**
 * 下面只说@ManyToOne,如需了解其他注解,
 * 可以参考上一篇:http://www.cnblogs.com/fancyzero/archive/2012/06/10/hibernate-one-to-one-annotation.html
 */
@Entity
@Table(name = "t_employee")
public class Employee {

    private Integer employeeId;
    private String  employeeName;
    private Company company;
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Integer getEmployeeId() {
        return employeeId;
    }
    /**
     * @ManyToOne:多对一,cascade:级联,请参考上一篇
      * fetch = FetchType.LAZY,延迟加载策略,如果不想延迟加载可以用FetchType.EAGER
     */
    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH},fetch = FetchType.LAZY)
    @JoinColumn(name = "cid")
    public Company getCompany() {
        return company;
    }
    public String getEmployeeName() {
        return employeeName;
    }
    public void setEmployeeId(Integer employeeId) {
        this.employeeId = employeeId;
    }
    public void setEmployeeName(String employeeName) {
        this.employeeName = employeeName;
    }
    public void setCompany(Company company) {
        this.company = company;
    }
}

 

Company.java

package com.fancy.po;

import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
/**
 * -----------------------------------------
 * @文件: Company.java
 * @作者: fancy
 * @邮箱: fancyzero@yeah.net
 * @时间: 2012-6-10
 * @描述: 实体类
 * -----------------------------------------
 */
/**
 * 下面只说@OneToMany,如需了解其他注解,
 * 可以参考上一篇:http://www.cnblogs.com/fancyzero/archive/2012/06/10/hibernate-one-to-one-annotation.html
 */
@Entity
@Table(name = "t_company")
public class Company {

    private Integer companyId;
    private String  companyName;
    private Set<Employee> employees;
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Integer getCompanyId() {
        return companyId;
    }
    /**
     * @OneToMany 与 OneToOne相似的也用mappedBy,参考了Employee
     * 可以参考上一篇
     */
    @OneToMany(mappedBy = "company")
    public Set<Employee> getEmployees() {
        return employees;
    }
    public String getCompanyName() {
        return companyName;
    }
    public void setCompanyId(Integer companyId) {
        this.companyId = companyId;
    }
    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }
    public void setEmployees(Set<Employee> employees) {
        this.employees = employees;
    }
}

 

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.fancy</groupId>
  <artifactId>hibernate-annotation-many-to-one-example</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
  <name>hibernate-annotation-many-to-one-example</name>
  <url>http://maven.apache.org</url>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  
  <dependencies>
    <!-- hibernate jar -->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-entitymanager</artifactId>
      <version>3.3.1.ga</version>
    </dependency>
    <!-- hibernate annotation jar -->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-annotations</artifactId>
      <version>3.3.1.GA</version>
    </dependency>
    <!-- mysql -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.17</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  
</project>


Test.java

package com.fancy.test;

import java.util.Iterator;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
import com.fancy.po.Company;
import com.fancy.po.Employee;
/**
 * -----------------------------------------
 * @文件: Test.java
 * @作者: fancy
 * @邮箱: fancyzero@yeah.net
 * @时间: 2012-6-10
 * @描述: 测试类
 * -----------------------------------------
 */
public class Test {

    public static void main(String[] args) {
        //读取hibernate配置,默认读取classpath下的hibernate.cfg.xml
        Configuration conf = new AnnotationConfiguration();    
        //构建session工厂
         SessionFactory sessionFactory = conf.configure().buildSessionFactory();
        //打开session
        Session session = sessionFactory.openSession();
        //开始事务
         session.beginTransaction();
        // * * * * * * * * * * * * * * * * * * * * * * * * * * * *
        //test1(session);   //测试 1
        //test2(session);  //测试  2
        test3(session);   //测试   3
        // * * * * * * * * * * * * * * * * * * * * * * * * * * * *
        //提交事务
         session.getTransaction().commit();
        //关闭session工厂
         sessionFactory.close();
        //关闭session
        session.close();
    }
    public static void test1(Session session){
        Company company = (Company)session.get(Company.class, 1); //发出Company的select语句
         Set<Employee> employee = company.getEmployees();         //不发出Employee的select语句
         System.out.println("Company :" + company.getCompanyName());
        System.out.println("CountSum:" + employee.size()); //Employee初次被使用,发出select语句
         Iterator<Employee> it = employee.iterator(); //Employee不再发出select语句
         while(it.hasNext()){
          System.out.println("EmployeeName:" + it.next().getEmployeeName());
        }
    }
    public static void test2(Session session){
       Company company = (Company)session.get(Company.class, 2);//发出Company的select语句
        Set<Employee> employee = company.getEmployees();        //不发出Employee的select语句
        Iterator<Employee> it = employee.iterator(); //发出Employee的select语句
        Employee e = null;
       Boolean first = false;
       while(it.hasNext()){
          e = it.next();
          if(!first){
              System.out.println("EmployeeId:[" + e.getEmployeeId() + "] information will be change");
              e.setEmployeeName("fancy"); //更改雇员名字
            //  session.save(e);  //发出Employee的update语句,不发出Company的update语句
                session.save(company);    //发出Employee的update语句,不发出Company的update语句
                first = true;
            }
            System.out.println("EmployeeName:" + e.getEmployeeName());
        }
    }
    public static void test3(Session session){
        Employee employee = (Employee)session.get(Employee.class, 1);//发出Employee的select语句
         Company  company  = (Company)session.get(Company.class, 1);//发出Company的select语句
         company.setCompanyName("Oracle"); //更改公司名字
    //  session.save(company);//发出Company的update语句,不发出Employee的update语句
         session.save(employee);//发出Company的update语句,不发出Employee的update语句
    }
}

 




   [ 转载出处:http://www.blogjava.net/fancydeepin ]

posted @ 2013-12-31 13:34 午后星期午 阅读(107) | 评论 (0)编辑 收藏

hibernate annotation 双向 one-to-one 注解

环境:
Hibernate 3.3.1 
Maven 3.0.4 
MySQL 5.5.13 
Myeclipse 8.6.1 

 

 建表语句:

DROP TABLE IF EXISTS `t_card`;
CREATE TABLE `t_card` (
  `cardId` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `cardNumber` char(18) NOT NULL,
  PRIMARY KEY (`cardId`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=gb2312;

INSERT INTO `t_card` VALUES ('1', '440911199008011122');
DROP TABLE IF EXISTS `t_person`;
CREATE TABLE `t_person` (
  `personId` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `personName` varchar(15) NOT NULL,
  `cid` int(10) unsigned NOT NULL,
  PRIMARY KEY (`personId`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=gb2312;

INSERT INTO `t_person` VALUES ('1', 'fancy', '1');

 

Person.java

package com.fancy.po;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
/**
 * -----------------------------------------
 * @文件: Person.java
 * @作者: fancy
 * @邮箱: fancyzero@yeah.net
 * @时间: 2012-6-10
 * @描述: 实体类
 * -----------------------------------------
 */
/**
 * @Entity 声明一个类为实体Bean
 * @Table(name = "xx")指定实体类映射的表,如果表名和实体类名一致,可以不指定
 */
@Entity
@Table(name = "t_person")
public class Person {

    private Integer personId;
    private String  personName;
    private Card    card;
    /**
     * @Id 映射主键属性,这里采用uuid的主键生成策略
      * @GeneratedValue —— 注解声明了主键的生成策略。该注解有如下属性
      * strategy 指定生成的策略,默认是GenerationType. AUTO
     * GenerationType.AUTO 主键由程序控制
      * GenerationType.TABLE 使用一个特定的数据库表格来保存主键
      * GenerationType.IDENTITY 主键由数据库自动生成,主要是自动增长类型
      * GenerationType.SEQUENCE 根据底层数据库的序列来生成主键,条件是数据库支持序列
      * generator 指定生成主键使用的生成器
      */
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Integer getPersonId() {
        return personId;
    }
    /**
     * @OneToOne:一对一关联
      * cascade:级联,它可以有有五个值可选,分别是:
      * CascadeType.PERSIST:级联新建
      * CascadeType.REMOVE : 级联删除
      * CascadeType.REFRESH:级联刷新
      * CascadeType.MERGE  : 级联更新
      * CascadeType.ALL    : 以上全部四项
      * @JoinColumn:主表外键字段
      * cid:Person所映射的表中的一个字段
      */
    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "cid")
    public Card getCard() {
        return card;
    }
    public String getPersonName() {
        return personName;
    }
    public void setPersonId(Integer personId) {
        this.personId = personId;
    }
    public void setPersonName(String personName) {
        this.personName = personName;
    }
    public void setCard(Card card) {
        this.card = card;
    }
}

 

Card.java

package com.fancy.po;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
/**
 * -----------------------------------------
 * @文件: Card.java
 * @作者: fancy
 * @邮箱: fancyzero@yeah.net
 * @时间: 2012-6-10
 * @描述: 实体类
 * -----------------------------------------
 */
@Entity
@Table(name = "t_card")
public class Card {

    private Integer cardId;
    private String  cardNumber;
    private Person  person;
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Integer getCardId() {
        return cardId;
    }
    /**
     * @OneToOne:一对一关联
      * mappedBy = "card":意思是说这里的一对一配置参考了card
     * card又是什么呢?card是Person类中的getCard(),注意不是Person类中的
      * card属性,Person类中的OneToOne配置就是在getCard()方法上面配的.
     * 如果Person类中的getCard()方法改成getIdCard(),其他不变的话,
     * 这里就要写成:mappedBy = "idCard"
     */
    @OneToOne(mappedBy = "card")
    public Person getPerson() {
        return person;
    }
    public String getCardNumber() {
        return cardNumber;
    }
    public void setCardId(Integer cardId) {
        this.cardId = cardId;
    }
    public void setCardNumber(String cardNumber) {
        this.cardNumber = cardNumber;
    }
    public void setPerson(Person person) {
        this.person = person;
    }
}

 

 pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.fancy</groupId>
  <artifactId>hibernate-annotation-on-to-one-example</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
  <name>hibernate-annotation-on-to-one-example</name>
  <url>http://maven.apache.org</url>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  
  <dependencies>
    <!-- hibernate jar -->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-entitymanager</artifactId>
      <version>3.3.1.ga</version>
    </dependency>
    <!-- hibernate annotation jar -->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-annotations</artifactId>
      <version>3.3.1.GA</version>
    </dependency>
    <!-- mysql -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.17</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  
</project>

 

Test.java

package com.fancy.test;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
import com.fancy.po.Card;
import com.fancy.po.Person;
/**
 * -----------------------------------------
 * @文件: Test.java
 * @作者: fancy
 * @邮箱: fancyzero@yeah.net
 * @时间: 2012-6-10
 * @描述: 测试类
 * -----------------------------------------
 */
public class Test {

    public static void main(String[] args) {
        
        //读取hibernate配置,默认读取classpath下的hibernate.cfg.xml
        Configuration conf = new AnnotationConfiguration();    
        //构建session工厂
         SessionFactory sessionFactory = conf.configure().buildSessionFactory();
        //打开session
        Session session = sessionFactory.openSession();
        //开始事务
         session.beginTransaction();
        // * * * * * * * * * * * * * * * * * * * * * * * * * * * *
        //test1(session);    //测试 1
        //test2(session);    //测试 2
        test3(session);      //测试 3
        // * * * * * * * * * * * * * * * * * * * * * * * * * * * *
        //提交事务
         session.getTransaction().commit();
        //关闭session工厂
         sessionFactory.close();
       //关闭session
       session.close();
    }
    /**
     * 数据库初始值:
      * personName:fancy
     * cardNumber:440911199008011122
     */
    //测试方法1
    public static void test1(Session session){
        Person person = (Person)session.get(Person.class, 1); //发出Person和Card的select语句
         Card card = person.getCard();
        System.out.println(person.getPersonName());
        System.out.println(card.getCardNumber());
        person.setPersonName("fancy");            //与初始值一致
         card.setCardNumber("440911199008011122");//与初始值一致
         session.save(person);    //不发出sql语句
       //session.save(card);     //不发出sql语句
    }
    //测试方法2
    public static void test2(Session session){
        Person person = (Person)session.get(Person.class, 1); //发出Person和Card的select语句
         Card card = person.getCard();
        System.out.println(person.getPersonName());
        System.out.println(card.getCardNumber());
        person.setPersonName("fancyzero");        //与初始值不一致
         card.setCardNumber("440911199008011122");//与初始值一致
         session.save(person);    //发出Person的update语句,数据库中personName被修改,不发出Card的update语句
       //session.save(card);     //发出Person的update语句,数据库中personName被修改,不发出Card的update语句
    }
    //测试方法3
    public static void test3(Session session){
        Person person = (Person)session.get(Person.class, 1); //发出Person和Card的select语句
         Card card = person.getCard();
        System.out.println(person.getPersonName());
        System.out.println(card.getCardNumber());
        person.setPersonName("fancy");           //与初始值不一致
         card.setCardNumber("440911199008080808");//与初始值不一致
         session.save(person);    //同时发出Person和Card的update语句,数据库中的数据相应被修改
       //session.save(card);     //同时发出Person和Card的update语句,数据库中的数据相应被修改
    }
}

 




   [转载出处:http://www.blogjava.net/fancydeepin ]

posted @ 2013-12-31 13:33 午后星期午 阅读(75) | 评论 (0)编辑 收藏

hibernate annotation 之 注解声明

@Entity

     将一个 POJO 类注解成一个实体 bean ( 持久化 POJO 类 )

@Table

    为实体 bean 映射指定具体的表,如果该注解没有被声明,系统将使用默认值 ( 即实体 bean 不带包名的短类名 )

@Id

    将实体bean中的某个属性定义为标识符 ( identifier )

@GeneratedValue

    该注解可以定义该标识符的生成策略 ( 默认是 AUTO 策略 ) :

    AUTO — 可以是 IDENTITY,或 SEQUENCETABLE 类型,这取决于不同的底层数据库。

    TABLE — 使用表保存id值

    IDENTITY — 自然递增

    SEQUENCE — 序列

@Transient

     被注解成 @Transient 的 getter 方法或属性,将不会被持久化,hibernate 会忽略这些字段和属性。

@Basic

    所有没有定义注解的属性,等价于在其上面添加了 @Basic 注解.。通过 @Basic注解可以声明属性的获取策略 ( fetch strategy )

@Temporal

    在核心的 Java API 中并没有定义时间精度 ( temporal precision )。因此处理时间类型数据时,你还需要定义将其存储在数据库中所预期的精度。

    在数据库中,表示时间类型的数据有 DATE,TIME,和 TIMESTAMP 三种精度 ( 即单纯的日期,时间,或者两者兼备 )。 可使用 @Temporal 注解来调整精度。

@Column 

    将实体 bean 中的属性映射到表中的列。

    @Column(

        name = "columnName";                                (1)

        boolean unique() default false                 (2)

        boolean nullable() default true               (3)

        boolean insertable() default true           (4)

        boolean updatable() default true           (5)

        String columnDefinition() default ""      (6)

        String table() default ""                               (7)

        int length() default 255                              (8)

        int precision() default 0                             (9)

        int scale() default 0                                     (10)

(1)     name 可选,列名(默认值是属性名)

(2)     unique 可选是否在该列上设置唯一约束(默认值false)

(3)     nullable 可选是否设置该列的值可以为空(默认值true)

(4)     insertable 可选该列是否作为生成的insert语句中的一个列(默认值true)

(5)     updatable 可选该列是否作为生成的update语句中的一个列(默认值true)

(6)     columnDefinition 可选为这个特定列覆盖SQL DDL片段 (这可能导致无法在不同数据库间移植)

(7)     table 可选定义对应的表(默认为主表)

(8)     length 可选列长度(默认值255)

(9)     precision 可选列十进制精度(decimal precision)(默认值0)

(10)  scale 可选如果列十进制数值范围(decimal scale)可用,在此设置(默认值0)

 [ 转载出处:http://www.blogjava.net/fancydeepin ]

posted @ 2013-12-31 13:30 午后星期午 阅读(109) | 评论 (0)编辑 收藏

hibernate annotation 之 主键生成策略

Hibernate 默认总共支持 13 种生成策略 :

1. increment        2.  identity        3. sequence

4. hilo                  5. seqhilo         6. uuid

7. uuid.hex          8. guid             9. native

10. assigned       11. select         12. foreign        13. sequence-identity

 

下面介绍几个较为常用的策略 :

① identity [ 自然递增 ]

         支持 DB2,MySQL,SQL Server,Sybase 和HypersonicSQL 数据库, 用于为 long 或 short 或 int 类型生成唯一标识。它依赖于底层不同的数据库,
       与 Hibernate 和 程序员无关。

注解示例 :

@Id

@GenericGenerator(name = "idGenerator", strategy = "identity")

@GeneratedValue(generator = "idGenerator")

 

② sequence [ 序列 ]

支持 Oracle,DB2,PostgreSql,SAPDb 等数据库,用于为 long 或 short 或 int 类型生成唯一标识。它需要底层数据库的支持,
       并由数据库来维护这个 sequence 序列。

注解示例 :

@Id

   @GenericGenerator(name = "idGenerator", strategy = "sequence",

parameters = {@Parameter(name = "sequence",value="seq_name")})

   @GeneratedValue(generator = "idGenerator")

注意 : 该策略要求设定序列名,否则 hibernate 将无法找到,这将引致抛出异常 :

org.hibernate.exception.SQLGrammarException: could not get next sequence value

 

③ native

         需底层数据库的支持,对于 MySQL,SQL Server 采用 identity 的生成策略,对于 Oracle,则采用 sequence 策略。

注解示例 :

@Id

   @GenericGenerator(name = "idGenerator", strategy = "native")

   @GeneratedValue(generator = "idGenerator")

 

④ increment [ 自然递增 ]

       与 identity 策略不同的是,该策略不依赖于底层数据库,而依赖于 hibernate 本身,用于为 long 或 short 或 int 类型生成唯一标识。
       主键计数器是由 hibernate 的一个实例来维护,每次自增量为 1,但在集群下不能使用该策略,
       否则将引起主键冲突的情况,该策略适用于所有关系型数据库使用。

注解示例 :

       @Id

   @GenericGenerator(name = "idGenerator", strategy = "increment")

   @GeneratedValue(generator = "idGenerator")

 

⑤ uuid [ 32位16进制数的字符串 ]

         采用128位UUID算法生成主键,能够保证网络环境下的主键唯一性,也就能够保证在不同数据库及不同服务器下主键的唯一性。
       uuid 最终被编码成一个32位16进制数的字符串,
       占用的存储空间较大。用于为 String 类型生成唯一标识,适用于所有关系型数据库。

注解示例 :

       @Id

   @GenericGenerator(name = "idGenerator", strategy = "uuid")

   @GeneratedValue(generator = "idGenerator")

 

⑤ assigned [ 手工分配主键ID值 ]

       该策略要求程序员必须自己维护和管理主键,当有数据需要存储时,程序员必须自己为该数据分配指定一个主键ID值,
       如果该数据没有被分配主键ID值或分配的值存在重复,则该数据都将无法被持久化且会引起异常的抛出。

注解示例 :

       @Id

   @GenericGenerator(name = "idGenerator", strategy = "assigned")

   @GeneratedValue(generator = "idGenerator")


 [转载出处:http://www.blogjava.net/fancydeepin ]

posted @ 2013-12-31 13:29 午后星期午 阅读(76) | 评论 (0)编辑 收藏

log4j 配置

Log4j ( Log for Java ) 是 Apache 下的一个开源项目,通过 Log4j,可以将程序运行的信息输送到指定的目的地。这个目的地可以是控制台、文件、邮箱等。

Log4j 支持两种格式的文件配置,即 properties 和 xml 两种格式的文件。下面将要介绍的是采用 properties 格式的配置。

 log4j.properties 配置示例  


log4j.rootLogger
= INFO, logOutput

log4j.appender.logOutput = org.apache.log4j.FileAppender

log4j.appender.logOutput.file = src/main/resources/log/demoLog.log

log4j.appender.logOutput.layout = org.apache.log4j.PatternLayout

log4j.appender.logOutput.layout.conversionPattern = %n%n%d{yyyy-MM-dd HH:mm:ss}%n%p  %c  %L%n%m



① [ 配置日志级别和输出源 ]

      log4j.rootLogger = 级别,输出源1,输出源2 … …

     日志信息优先级别 :  ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF

     常用优先级别 : DEBUG < INFO < WARN < ERROR

         DEBUG : 程序的调试信息

         INFO  程序的一般信息,例如,用户的登录、登出,方法执行成功信息等

         WARN 程序的警告信息

         ERROR 程序的严重错误信息,例如,程序的执行抛出异常

         Tips : 只有当日志信息的优先级别大于等于配置的日志信息级别,日志信息才会被记录到日志。

     日志输出源 : 

         日志输出源的个数可以是一个,也可以是多个,多个输出源的时候,输出源与输出源之间用逗号分隔

         日志输出源的名字可以根据需要,自定义起名

② [ 指定输出源辅助类 ]

      log4j.appender.输出源名称 = Appender.class

      常用的 Appender ( 在 log4j-version.jar 的 org.apache.log4j 包下 ) : 

      1. org.apache.log4j.FileAppender(文件)

      2. org.apache.log4j.ConsoleAppender(控制台)

      3. org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件)

      4. org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)

③ [ 指定输出源文件存放路径 ]

      log4j.appender.输出源名称.file = path ( 日志具体存放路径 )

④ [ 指定输出源文件的格式布局 ]

      log4j.appender.输出源名称.layout = Layout.class

     常用的 Layout ( 在 log4j-version.jar 的 org.apache.log4j 包下 ) : 

     1. org.apache.log4j.SimpleLayout  ( 简单的布局方式,含日志信息的级别和信息 )

     2. org.apache.log4j.PatternLayout  ( 可自定义的布局模式 )

     3. org.apache.log4j.HTMLLayout   ( 以 HTML 方式布局 )

⑤ [ 自定义布局模式,可选 ]

      log4j.appender.输出源名称.layout.conversionPattern

     %p : 输出日志信息优先级,即DEBUG,INFO,WARN,ERROR,FATAL …

     %d : 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,例如:%d{yyy-MMM-dd HH:mm:ss},输出类似:2012-10-10 12:20:18 

     %r : 输出自应用启动到输出该log信息耗费的毫秒数

     %c : 输出日志信息所属的类,通常就是所在类的全名

     %t : 输出产生该日志事件的线程名

     %l : 输出日志事件的发生位置

     %x : 输出和当前线程相关联的信息

     %% : 输出一个"%"字符

     %F : 输出日志消息产生时所在的文件名称

     %L : 输出代码中的行号

     %m : 输出代码中指定的消息,产生的日志具体信息

     %n : 换行

[ 转载出处:http://www.blogjava.net/fancydeepin ]

posted @ 2013-12-31 13:27 午后星期午 阅读(107) | 评论 (0)编辑 收藏

Java生成随机字符串

package cc.wshao.steer.util;

import java.util.Random;

public class StrUtils {

 public static final String str = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

 public static void main(String[] args) {
  System.out.print(getString(6));
 }

 public static String getString(int length) {
  StringBuffer sb = new StringBuffer();
  Random random = new Random();
  for (int i = 0; i < length; i++) {
   sb.append(str.charAt(random.nextInt(str.length())));
  }
  return sb.toString();
 }

}

posted @ 2013-12-31 13:22 午后星期午 阅读(114) | 评论 (0)编辑 收藏