JakartaCommonBeanUtils研究心得.docx

上传人:b****1 文档编号:12476308 上传时间:2023-04-19 格式:DOCX 页数:21 大小:22.39KB
下载 相关 举报
JakartaCommonBeanUtils研究心得.docx_第1页
第1页 / 共21页
JakartaCommonBeanUtils研究心得.docx_第2页
第2页 / 共21页
JakartaCommonBeanUtils研究心得.docx_第3页
第3页 / 共21页
JakartaCommonBeanUtils研究心得.docx_第4页
第4页 / 共21页
JakartaCommonBeanUtils研究心得.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

JakartaCommonBeanUtils研究心得.docx

《JakartaCommonBeanUtils研究心得.docx》由会员分享,可在线阅读,更多相关《JakartaCommonBeanUtils研究心得.docx(21页珍藏版)》请在冰豆网上搜索。

JakartaCommonBeanUtils研究心得.docx

JakartaCommonBeanUtils研究心得

一、概述

第一次看到BeanUtils包,是在Struts项目中,作为Struts一个工具来使用的,

估计功能越弄越强,就移到Common项目中了吧。

BeanUtils一共有四个package:

mons.beanutils

mons.beanutils.converters

mons.beanutils.locale

mons.beanutils.locale.converters

后三个包主要是用于数据的转换,围绕着一个Converter接口,该接口只有一个方法:

java.lang.Objectconvert(java.lang.Classtype,java.lang.Objectvalue),

用于将一个value转换成另一个类型为type的Object。

在一些自动化的应用中应该会有用。

这里不作评论,以后有兴趣了,或者觉得有用了,再行研究。

这里只讲第一个包。

二、测试用的Bean

在开始所有的测试之前,我写了一个简单的Bean,以便于测试,代码如下:

packagemons.beanutils;

/**

 *@authorSonyMusic

 *

 */

publicclassMonth{

 privateintvalue;

 privateStringname;

 privateint[]days={11,22,33,44,55};

 publicMonth(intv,Stringn){

  value=v;

  name=n;

 }

 

 /**

 *Returnsthename.

 *@returnString

 */

 publicStringgetName(){

  returnname;

 }

 /**

 *Returnsthevalue.

 *@returnint

 */

 publicintgetValue(){

  returnvalue;

 }

 /**

 *Setsthename.

 *@paramnameThenametoset

 */

 publicvoidsetName(Stringname){

  this.name=name;

 }

 /**

 *Setsthevalue.

 *@paramvalueThevaluetoset

 */

 publicvoidsetValue(intvalue){

  this.value=value;

 }

 /**

 *@seejava.lang.Object#toString()

 */

 publicStringtoString(){

  returnvalue+"("+name+")";

 }

 publicint[]getDays(){

  returndays;

 }

 publicvoidsetDays(int[]is){

  days=is;

 }

}

三、BeanUtils

这是一个主要应用于Bean的Util(呵呵,这个解释很绝吧),以下是其中几个方法的例子

//staticjava.util.Mapdescribe(java.lang.Objectbean)

//这个方法返回一个Object中所有的可读属性,并将属性名/属性值放入一个Map中,另外还有

//一个名为class的属性,属性值是Object的类名,事实上class是java.lang.Object的一个属性

 Monthmonth=newMonth(1,"Jan");

 

 try{

  Mapmap=BeanUtils.describe(month);

  SetkeySet=map.keySet();

  for(Iteratoriter=keySet.iterator();iter.hasNext();){

   Objectelement=(Object)iter.next();

   System.out.println("KeyClass:

"+element.getClass().getName());

   System.out.println("ValueClass:

"+map.get(element).getClass().getName());

   System.out.print(element+"\t");

   System.out.print(map.get(element));

   System.out.println();

  }

 }catch(IllegalAccessExceptione){

  e.printStackTrace();

 }catch(InvocationTargetExceptione){

  e.printStackTrace();

 }catch(NoSuchMethodExceptione){

  e.printStackTrace();

 }

输出为:

KeyClass:

java.lang.String

ValueClass:

java.lang.String

value 1

KeyClass:

java.lang.String

ValueClass:

java.lang.String

class classmons.beanutils.Month

KeyClass:

java.lang.String

ValueClass:

java.lang.String

name Jan

注意到所有Map中的key/value都是String,而不管object中实际的值是多少。

与此对应的还有staticvoidpopulate(java.lang.Objectbean,java.util.Mapproperties)

用于将刚才describe出的Map再装配成一个对象。

再看这样一段代码

曹晓钢也许还记得,为了取一个不确定对象的property,着实花了不少时间,

难度不大,但要做到100%的正确,仍然需要付出很大的精力。

//staticjava.lang.StringgetProperty(java.lang.Objectbean,java.lang.Stringname)

 Monthmonth=newMonth(1,"Jan");

 

 try{

  System.out.println(BeanUtils.getProperty(month,"value"));

 }catch(Exceptione){

  e.printStackTrace();

 }

//输出是:

1

与getProperty类似的还有getIndexedProperty,getMappedProperty,

以getIndexedProperty为例:

 Monthmonth=newMonth(1,"Jan");

 

 try{

  System.out.println(BeanUtils.getIndexedProperty(month,"days",1));

  System.out.println(BeanUtils.getIndexedProperty(month,"days[1]"));

 }catch(Exceptione){

  e.printStackTrace();

 }

这两个调用是相同的。

BeanUtils中还有一个方法:

staticvoidcopyProperties(java.lang.Objectdest,java.lang.Objectorig)

它真是太有用,还记得struts中满天飞的都是copyProperties,我甚至怀疑整个BeanUtils最初

是不是因为这个方法的需求才写出来的。

它将对象orig中的属性复制到dest中去。

四、PropertyUtils

这个类和BeanUtils类很多的方法在参数上都是相同的,但返回值不同。

BeanUtils着重于"Bean",返回值通常是String,而PropertyUtils着重于属性,

它的返回值通常是Object。

五、ConstructorUtils

这个类中的方法主要分成两种,一种是得到构造方法,一种是创建对象。

事实上多数时候得到构造方法的目的就是创建对象,这里只介绍一下创建对象。

//staticjava.lang.ObjectConstructorUtils.invokeConstructor

//(java.lang.Classklass,java.lang.Object[]args)

//根据一个java.lang.Class以及相应的构造方法的参数,创建一个对象。

 Objectobj=ConstructorUtils.invokeConstructor(Month.class,{newInteger

(1),"Jan"});

 Monthmonth=(Month)obj;

 try{

  System.out.println(BeanUtils.getProperty(month,"value"));

 }catch(Exceptione){

  e.printStackTrace();

 }

输出证明,构造方法的调用是成功的。

如果需要强制指定构造方法的参数类型,可以这样调用:

  Object[]args={newInteger

(1),"Jan"};

  Class[]argsType={int.class,String.class};

  Objectobj;

  obj=ConstructorUtils.invokeExactConstructor(Month.class,args,argsType);

  Monthmonth=(Month)obj;

  System.out.println(BeanUtils.getProperty(month,"value"));

argsType指定了参数的类型。

六、ConstructorUtils补遗

创建对象还有一个方法:

invokeExactConstructor,该方法对参数要求

更加严格,传递进去的参数必须严格符合构造方法的参数列表。

例如:

Object[]args={newInteger

(1),"Jan"};

Class[]argsType={int.class,String.class};

Objectobj;

//下面这句调用将不会成功,因为args[0]的类型为Integer,而不是int

//obj=ConstructorUtils.invokeExactConstructor(Month.class,args);

//这一句就可以,因为argsType指定了类型。

obj=ConstructorUtils.invokeExactConstructor(Month.class,args,argsType);

Monthmonth=(Month)obj;

System.out.println(BeanUtils.getProperty(month,"value"));

七、MethodUtils

与ConstructorUtils类似,不过调用的时候,通常需要再指定一个methodname的参数。

八、DynaClass/DynaBean

这似乎是BeanUtils中最有趣的部分之一了,很简单,简单到光看这两个接口中的方法会不明白

为什么要设计这两个接口。

不过看到ResultSetDynaClass后,就明白了。

下面是javadoc中的代码:

   ResultSetrs=...;

   ResultSetDynaClassrsdc=newResultSetDynaClass(rs);

   Iteratorrows=rsdc.iterator();

   while(rows.hasNext())  {

     DynaBeanrow=(DynaBean)rows.next();

     ...processthisrow...

   }

   rs.close();

原来这是一个ResultSet的包装器,ResultSetDynaClass实现了DynaClass,它的iterator方法返回一个

ResultSetIterator,则是实现了DynaBean接口。

在获得一个DynaBean之后,我们就可以用

     DynaBeanrow=(DynaBean)rows.next();

     System.out.println(row.get("field1"));//field1是其中一个字段的名字

再看另一个类RowSetDynaClass的用法,代码如下:

Stringdriver="com.mysql.jdbc.Driver";

Stringurl="jdbc:

mysql:

//localhost/2hu?

useUnicode=true&characterEncoding=GBK";

Stringusername="root";

Stringpassword="";

java.sql.Connectioncon=null;

PreparedStatementps=null;

ResultSetrs=null;

try{

Class.forName(driver).newInstance();

con=DriverManager.getConnection(url);

ps=con.prepareStatement("select*fromforumlist");

rs=ps.executeQuery();

//先打印一下,用于检验后面的结果。

while(rs.next()){

System.out.println(rs.getString("name"));

}

rs.beforeFirst();//这里必须用beforeFirst,因为RowSetDynaClass只从当前位置向前滚动

RowSetDynaClassrsdc=newRowSetDynaClass(rs);

rs.close();

ps.close();

Listrows=rsdc.getRows();//返回一个标准的List,存放的是DynaBean

for(inti=0;i

DynaBeanb=(DynaBean)rows.get(i);

System.out.println(b.get("name"));

}

}catch(Exceptione){

e.printStackTrace();

}

finally{

try{

con.close();

}catch(Exceptione){

}

}

是不是很有趣?

封装了ResultSet的数据,代价是占用内存。

如果一个表有10万条记录,rsdc.getRows()

就会返回10万个记录。

@_@

需要注意的是ResultSetDynaClass和RowSetDynaClass的不同之处:

1,ResultSetDynaClass是基于Iterator的,一次只返回一条记录,而RowSetDynaClass是基于

List的,一次性返回全部记录。

直接影响是在数据比较多时ResultSetDynaClass会比较的快速,

而RowSetDynaClass需要将ResultSet中的全部数据都读出来(并存储在其内部),会占用过多的

内存,并且速度也会比较慢。

2,ResultSetDynaClass一次只处理一条记录,在处理完成之前,ResultSet不可以关闭。

3,ResultSetIterator的next()方法返回的DynaBean其实是指向其内部的一个固定

对象,在每次next()之后,内部的值都会被改变。

这样做的目的是节约内存,如果你需要保存每

次生成的DynaBean,就需要创建另一个DynaBean,并将数据复制过去,下面也是javadoc中的代码:

   ArrayListresults=newArrayList();//Toholdcopiedlist

   ResultSetDynaClassrsdc=...;

   DynaPropertyproperties[]=rsdc.getDynaProperties();

   BasicDynaClassbdc=

     newBasicDynaClass("foo",BasicDynaBean.class,

                        rsdc.getDynaProperties());

   Iteratorrows=rsdc.iterator();

   while(rows.hasNext()){

     DynaBeanoldRow=(DynaBean)rows.next();

     DynaBeannewRow=bdc.newInstance();

     PropertyUtils.copyProperties(newRow,oldRow);

     results.add(newRow);

   }

事实上DynaClass/DynaBean可以用于很多地方,存储各种类型的数据。

自己想吧。

嘿嘿。

九、自定义的CustomRowSetDynaClass

两年前写过一个与RowSetDynaClass目标相同的类,不过多一个功能,就是分页,只取需要的数据,

这样内存占用就会减少。

先看一段代码:

Stringdriver="com.mysql.jdbc.Driver";

Stringurl="jdbc:

mysql:

//localhost/2hu?

useUnicode=true&characterEncoding=GBK";

Stringusername="root";

Stringpassword="";

java.sql.Connectioncon=null;

PreparedStatementps=null;

ResultSetrs=null;

try{

Class.forName(driver).newInstance();

con=DriverManager.getConnection(url);

ps=con.prepareStatement("select*fromforumlistorderbyname");

rs=ps.executeQuery();

/*

while(rs.next()){

System.out.println(rs.getString("name"));

}

rs.beforeFirst();

*/

//第二个参数表示第几页,第三个参数表示页的大小

CustomRowSetDynaClassrsdc=newCustomRowSetDynaClass(rs,2,5);

//RowSetDynaClassrsdc=newRowSetDynaClass(rs);

rs.close();

ps.close();

Listrows=rsdc.getRows();

for(inti=0;i

DynaBeanb=(DynaBean)rows.get(i);

System.out.println(b.get("name"));

}

}catch(Exceptione){

e.printStackTrace();

}

finally{

try{

con.close();

}catch(Exceptione){

}

}

在这里用到了一个CustomRowSetDynaClass类,构造方法中增加了page和pageSize两个参数,

这样,不管数据库里有多少条记录,最多只取pageSize条记录,若pageSize==-1,则功能和

RowSetDynaClass一样。

这在大多数情况下是适用的。

该类的代码如下:

packagemons.beanutils;

importjava.io.*;

importjava.sql.*;

importjava.util.*;

importmons.beanutils.*;

/**

*@authorSonyMusic

*

*Tochangethisgeneratedcommenteditthetemplatevariable"typecomment":

*Window>Preferences>Java>Templates.

*Toenableanddisablethecreationoftypecommentsgoto

*Window>Preferences>Java>CodeGeneration.

*/

publicclassCustomRowSetDynaClassimplementsDynaClass,Serializable{

//-----------------------------------------------------------Constructors

/**

*

Constructanew{@linkRowSetDynaClass}forthespecified

*ResultSet.  Thepropertynamescorresponding

*tocolumnnamesintheresultsetwillbelowercased.

*

*@paramresultSetTheresultsettobewrapped

*

*@exceptionNullPointerExceptionifresultSet

*  isnull

*@exceptionSQLExceptionifthemetadatafort

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 教育学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1