JAKARTA-Common-beanUtils study experience

xiaoxiao2021-03-06  43

I. Overview

For the first time, I saw the beanutils package, in the Struts project, as a tool for Struts, used,

The more you get the stronger, you move to the CommON project.

Beanutils has four packages:

Org.apache.commons.beanutils

Org.apache.commons.beanutils.converters

Org.apache.commons.beanutils.locale

Org.apache.commons.beanutils.locale.Converters

The latter three packs are mainly used for data conversion, surrounding a CONVERTER interface, only one way:

Java.Lang.object Convert (java.lang.class type, java.lang.object value),

Used to convert a value into another type of objects for Type. It should be useful in some automated applications.

It is not commented here, I have been interested, or I feel useful, and then study.

Here is only the first package.

Second, Bean for testing

Before I started all the tests, I wrote a simple bean for tested, the code is as follows:

Package test.jakarta.commons.beanutils;

/ **

* @Author Sonymusic

*

* /

Public class month {

Private int value;

PRIVATE STRING NAME;

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

Public Month (int V, string n) {

Value = v;

Name = n;

}

/ **

* Returns the name.

* @Return String

* /

Public string getname () {

Return Name;

}

/ **

* Returns the value.

* @Return Int

* /

Public Int getValue () {

Return Value;

}

/ **

* Sets the name.

* @Param Name the name to set

* /

Public void setname (String name) {

THIS.NAME = Name;

}

/ **

* Sets the value.

* @Param Value The Value To Set

* /

Public void setValue (int value) {

THIS.VALUE = VALUE;

}

/ **

* @see java.lang.Object # toString ()

* /

Public string toString () {

RETURN VALUE "(" Name ")";

}

Public int [] getDays () {

Return day;

}

Public void setdays (int [] is) {

Days = IS;

}

}

Third, beanutils

This is a main application to bean Util (huh, this explanation is very good), the following is the example of several methods

// static java.util.map describ (java.lang.object bean)

/ / This method returns all readable properties in an object, and puts the property name / attribute value in a map, and there are

// A property named Class, the property value is the class name of Object, in fact, Class is a property of java.lang.object month month = new month (1, "jan");

Try {

Map map = beanutils.describe (Month);

Set keyset = map.keyset ();

ITerator it = keyset.iterator (); it.hasnext ();) {

Object element = (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 (IllegaCcessException E) {

E.PrintStackTrace ();

} catch (invocationTargeTexception E) {

E.PrintStackTrace ();

} catch (nosuchmethodexception e) {

E.PrintStackTrace ();

}

The output is:

KeyClass: java.lang.string

ValueClass: java.lang.string

Value 1

KeyClass: java.lang.string

ValueClass: java.lang.string

Class class test.jakarta.commons.beanutils.month

KeyClass: java.lang.string

ValueClass: java.lang.string

Name Jan

Note that key / value in all MAP is String, regardless of the actual value in the object of Object.

There is also static void populate (java.ient.ubject bean, java.util.map property)

Used to put the MAP that DESCRIBE is replaced into an object.

Look at such a code

Cao Xiao Gang may still remember that in order to take an unstertic object, it has a lot of time,

The difficulty is not difficult, but it is necessary to do 100%, still need to pay great effort.

// static java.lang.string getProperty (java.lang.object bean, java.lang.string name)

Month Month = New Month (1, "Jan");

Try {

System.out.println (beanutils.getProperty);

} catch (exception e) {

E.PrintStackTrace ();

}

// Output is: 1

Similar to getproperty and getIndexedProperty, GetMappedProperty,

Take GetIndexedProperty as an example:

Month Month = New Month (1, "Jan");

Try {

System.out.println (beanutils.getIndexedProperty (Month, "Days", 1)); System.Out.println (beanutils.getIndexedProperty);

} catch (exception e) {

E.PrintStackTrace ();

}

These two calls are the same.

There is also a method in BeanUtils:

Static void CopyProperties (java.lang.object dest, java.lang.object orig)

It is really useful, I still remember that Struts is full of CopyProperties, I even doubt the entire beanutils original

Is it because the needs of this method are written.

It copies the properties in the object orig to DEST.

Four, PropertyUtils

Many methods of this class and beanutils classes are the same on the parameters, but the return value is different.

Beanutils focuses on "bean", the return value is usually String, and PropertyUtils focuses on attributes.

Its return value is usually Object.

Five, constructorutils

The method in this class is mainly divided into two, one is to obtain a construction method, one is to create an object.

In fact, most of the time to get a constructor is to create an object, here only introduce the creation of objects.

// static java.lang.Object Constructorutils.InvokeConstructor

//(java.lang.class klass, java.lang.object [] args

// Create an object based on a java.lang.class and the corresponding constructor parameters.

Object Obj = constructorutils.invokeconstructor (Month.class, {new integer (1), "jan"});

Month Month = (MONTH) OBJ;

Try {

System.out.println (beanutils.getProperty);

} catch (exception e) {

E.PrintStackTrace ();

}

The output is proved that the call to the constructor is successful.

If you need to force the parameter type of the constructor, you can call:

Object [] args = {new integer (1), "jan"};

Class [] argstype = {INT.CLASS, STRING.CLASS}

Object obj;

Obj = constructorutils.invokeexactConstructor (Month.class, args, argstype);

Month Month = (MONTH) OBJ;

System.out.println (beanutils.getProperty);

ArgStype specifies the type of parameters.

Sixth, constructorutils supplement

There is also a method for creating an object: InvokeExactConstructor, the method requires parameter requirements

More stringent, the passing parameters must strictly meet the parameters of the constructor.

E.g:

Object [] args = {new integer (1), "jan"};

Class [] argstype = {INT.CLASS, STRING.CLASS}

Object obj;

// The call will not succeed, because the type of Args [0] is Integer instead of int // Obj = constructorutils.invokeexactConstructor (Month.class, Args);

// This sentence can be, because ArgStype specifies the type.

Obj = constructorutils.invokeexactConstructor (Month.class, args, argstype);

Month Month = (MONTH) OBJ;

System.out.println (beanutils.getProperty);

Seven, MethodUtils

Similar to constructorutils, but when called, you typically need to specify a parameter of Method Name.

Eight, Dynaclass / Dynabean

This seems to be one of the most interesting parts in Beanutils, very simple, simple to look at these two interfaces in these two interfaces, do not understand

Why design these two interfaces. However, after seeing ResultSetDynaclass, I understand. Here is the code in Java DOC:

ResultSet RS = ...

ResultSetdyNaclass RSDC = New ResultSetDynaclass (RS);

Iterator rows = rsdc.iterator ();

While (rows.hasnext ()) {

Dynabean row = (Dynabean) rows.next ();

... Process this Row ...

}

Rs.close ();

It turns out that this is a RESULTSET wrapper, resultSetdyNaclass implements Dynaclass, and its Iterator method returns one

ResultSetiterator, the Dynabean interface is implemented.

After getting a Dynabean, we can use

Dynabean row = (Dynabean) rows.next ();

System.out.println (Row.get ("Field1")); // Field1 is the name of one of the fields

Look at another type of RowSetDynaclass, the code is as follows:

String driver = "com.mysql.jdbc.driver";

String url = "jdbc: mysql: // localhost / 2hu? Useunicode = true & characterencoding = GBK";

String Username = "root";

String password = ""

Java.sql.connection con = NULL;

PreparedStatement PS = NULL;

ResultSet RS = NULL;

Try {

Class.Forname (driver) .newinstance ();

Con = DriverManager.getConnection (URL);

PS = con.preparestatement ("Select * from forumlist");

RS = ps.executeQuery ();

// Print it first, used to check the results behind.

While (rs.next ()) {

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

}

rs.beforefirst (); // must use BeforeFirst, because rowsetdynaclass only scrolls RowSetDynaclass RSDC = New RowSetDynaclass (RS) only from the current location.

Rs.close ();

ps.close ();

List rows = rsdc.getrows (); // Returns a standard List, stored Dynabean

For (int i = 0; i

Dynabean B = (Dynabean) Rows.get (i);

System.out.println (B.Get ("Name");

}

} catch (exception e) {

E.PrintStackTrace ();

}

Finally {

Try {

C. close ();

} catch (exception e) {

}

}

Is it very interesting? Encapsulated the result of ResultSet, the cost is occupied memory. If a table has 100,000 records, rsdc.getrows ()

It will return 100,000 records. @ _ @

It should be noted that the difference between ResultSetdyNaclass and RowSetDynaclass:

1. ResultSetdyNaclass is based on Iterator, only one record is returned once, and RowSetDynaclass is based on

List, one time returns all records. The direct impact is that the RESULTSETDYNACLASS will compare quickly in the data comparison.

RowSetdyNaclass needs to read all the data in the Resultset (and stored inside), will take up too much

Memory, and speed is slow.

2, ResultSetdyNaclass only processes a record at a time, and the resultSet cannot be turned off before processing is completed.

3. The Dynabean returned by the resultSetiterator's next () method is actually a fixed point to its internal

Object, after each next (), the internal value will be changed. The purpose of this is to save memory if you need to save each

The subsequent Dynabean needs to create another Dynabean and copy the data in the past. The following is the code in Java DOC:

ArrayList Results = New ArrayList (); // to Hold Copied List

ResultSetDynaclass RSDC = ...

Dynaproperty property [] = rsdc.getDynaproperties ();

Basic Dynaclass BDC =

New Basic Dynaclass ("foo", BasicDynabean.class,

RSDC.GETDYNAPROPERTIES ());

Iterator rows = rsdc.iterator ();

While (rows.hasnext ()) {

Dynabean Oldrow = (Dynabean) rows.next ();

Dynabean newrow = bdc.newinstance ();

PropertyUtils.copyProperties (Newrow, Oldrow);

Results.add (new);

}

In fact, Dynaclass / DynaBean can be used in many places to store various types of data. I think I think.嘿嘿.

Nine, custom CustomrowSetDynaclass writes a class with the RowSetDynaclass target two years ago, but more features, it is paging, only required data,

This memory is reduced.

First see a code:

String driver = "com.mysql.jdbc.driver";

String url = "jdbc: mysql: // localhost / 2hu? Useunicode = true & characterencoding = GBK";

String Username = "root";

String password = ""

Java.sql.connection con = NULL;

PreparedStatement PS = NULL;

ResultSet RS = NULL;

Try {

Class.Forname (driver) .newinstance ();

Con = DriverManager.getConnection (URL);

PS = con.preparestatement ("Select * from forumlist order by name);

RS = ps.executeQuery ();

/ *

While (rs.next ()) {

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

}

Rs.beforefirst ();

* /

// Second parameter represents the second page, the third parameter represents the size of the page

CustomrowSetdynaclass RSDC = New CustomrowSetDynaclass (RS, 2, 5);

// RowSetDynaclass RSDC = New RowsetDynaclass (RS);

Rs.close ();

ps.close ();

List rows = rsdc.getrows ();

For (int i = 0; i

Dynabean B = (Dynabean) Rows.get (i);

System.out.println (B.Get ("Name");

}

} catch (exception e) {

E.PrintStackTrace ();

}

Finally {

Try {

C. close ();

} catch (exception e) {

}

}

Here, there is a CustomrowSetDynaclass class, and two parameters of Page and PageSize are added to the constructor.

In this way, only the number of records in the database is recorded, only the PageSize strip record is recorded, if PageSize == - 1, the function and

RowsetDynaclass is the same. This is suitable in most cases. The code of this class is as follows:

Package test.jakarta.commons.beanutils;

Import java.io. *;

Import java.sql. *;

Import java.util. *;

Import org.apache.commons.BeanUtils. *;

/ **

* @Author Sonymusic

*

* To change this generated comment edit the template variable "typecomment":

* Window> Preferences> Java> Templates.

* TOEABLE AND DISABLE The CREATION OF TYPE Comments Go To * Window> Preferences> Java> Code Generation.

* /

Public Class CustomrowSetDynaclass Implements Dynaclass, Serializable {

/ / -------------------------------------------------------------------------------------------- ----------- Constructionors

/ **

*

construct a new {@link rowsetdynaclass} for the specified

* ResultSet . The property names Corresponding

* To column name in the result set will be lower cased.

*

* @Param Resultset The Result set to be wrappe

*

* @Exception nullpointersRexception if ResultSet

* IS null

* @Exception SQLEXCEPTION IF The Metadata for this Result Set

* Cannot be introspected

* /

Public CustomrowSetDynaclass (Resultset Resultset) throws Sqlexception {

This (resultSet, true);

}

/ **

*

construct a new {@link rowsetdynaclass} for the specified

* ResultSet . The property names Corresponding

* To the column name in the result set will be lower canceled or not,

* Depending on the specified Lowercase value.

*

*

Warning - if you specify false

* for LowerCase , The Returned Property Names Will

* EXACTLY MATCH The Column Names Returned by Your JDBC Driver.

* Because Different Drivers Might Return Column Names in Different

* Cases, The Property Names Seen by Your Application Will Vary

* Depending on Which JDBC Driver You are use.

*

* @Param Resultset The Result set to be wrappe

* @PARAM LOWERCASE SHOLD PROPERTY NAMES BE LOWER CASED?

*

* @Exception nullpointerException if resultset * is null

* @Exception SQLEXCEPTION IF The Metadata for this Result Set

* Cannot be introspected

* /

Public CustomrowSetDynaclass (Resultset Resultset, Boolean Lowercase)

Throws sqlexception {

This (ResultSet, 1, -1, LowerCase);

}

Public CustomrowSetDynaclass (

Resultset ResultSet,

Int page,

Int PageSize,

Boolean LowerCase)

Throws sqlexception {

if (ResultSet == Null) {

Throw new nullpointerserException ();

}

this.Lowercase = LowerCase;

THIS.PAGE = Page;

THIS.PAGESIZE = Pagesize;

Introspect (ResultSet);

Copy (ResultSet);

}

Public CustomrowSetDynaclass (Resultset Resultset, Int page, int pageSize)

Throws sqlexception {

This (ResultSet, Page, PageSize, True);

}

/ / -------------------------------------------------------------------------------------------- ----- Instance Variables

/ **

*

flag defining WHETHER column names shop be lower case

* Converted to Property Names.

* /

Protected Boolean Lowercase = True;

protected int point = 1;

Protected int Pagesize = -1;

/ **

*

The set of dynamic printies That Are Part of this

* {@link dynaclass}.

* /

Protected Dynaproperty Properties [] = NULL;

/ **

*

The set of dynamic printies That Are Part of this

* {@link dynaclass}, keyed by the property name. Individual Descriptor

* Instances Will Be The Same Instances As Those in The

* Properties list.

* /

Protected Map PropertiesMap = new hashmap ();

/ **

*

the list of {@link dynabean} s representing the contents of

* The Original ResultSet on Which this

* {@link rowsetdynaclass} WAS Based. * /

Protected List rows = new arraylist ();

/ / -------------------------------------------------------------------------------------------- ------ DYNACLASS METHODS

/ **

*

return the name of this Dynaclass (Analog to the

* getname () method of java.lang.class

* Allows the Same Dynaclass Implementation Class To Support

* DiffERENT DYNAMIC CLASSES, WITH DIFFERENT SETS OF Properties.

* /

Public string getname () {

Return (this.getclass (). getname ());

}

/ **

*

return a property descriptor for the specified property, if IT

* EXISTS; OtherWise, Return NULL .

*

* @Param Name Name of the Dynamic Property for Which A Descriptor

* Is Requester

*

* @Exception IllegalargumentException if no property name is specified

* /

Public Dynaproperty getDynaproperty (String name) {

IF (name == null) {

Throw New IllegalargumentException ("No Property Name Specified";

}

Return (Dynaproperty) PropertiesMap.Get (Name));

}

/ **

*

return an array of ProPERYDESCRIPTORS for the Properties

* Currently Defined in this Dynaclass. if no property it defined, A

* Zero-Length Array Will Be Returned.

* /

Public Dynaproperty [] getDynaproperties () {

Return (Properties);

}

/ **

*

instantiate and return a new Dynabean Instance, Associated

* with this Dynaclass. Note - this Operation is not

* Supported, and throws an exception.

*

* @Exception illegalaccessException if the class or the appropriate

* Constructor is Not Accessible

* @Exception InstantiationException if this class represents an abstract * Class, an Array Class, a primitive type, or void; or if instantiation

* Fails for Some Other REASON

* /

Public Dynabean newInstance ()

Throws IllegaCcessException, InstantiationException {

Throw new unsupportedOperationException ("NewInstance () Not supported;

}

/ / -------------------------------------------------------------------------------------------- --------- Public Methods

/ **

*

return a list containing the {@link dynabean} s

* Repesent the contents of each ROW from the

* ResultSet That Was the Basis of this

* {@link rowsetdynaclass} instance. these {@Link Dynabean} S Are

* Disconnected from the Database Itself, So There is no problem

* Modifying the contents of the list, or the value of the profmenties

* of these {@link dynabean} s. however, it is the application.

* Responsibility to persist Any Such Changes Back to the Database,

* if it so desires.

* /

Public List getRows () {

Return (this.Rows);

}

/ / -------------------------------------------------------------------------------------------- ------ Protected Methods

/ **

*

Copy the column value for each row in the specified

* resultset INTO A newly created {@link dynabean}, and add

* this bean to the list of {@Link Dynabean} S That Will Later by

* Returned by a call to getRows () .

*

* @Param ResultSet the ResultSet whose data is to be

* Copied

*

* @Exception sqlexception if an error is encountered Copying The Data

* /

Protected Void Copy (ResultSet Resultset) throws sqlexception {

INT ABS = 0;

INT rowscount = 0; int currentpagerows = 0;

ResultSet.last ();

RowsCount = resultSet.Getrow ();

IF (PageSize! = -1) {

INT TOTALPAGES = (int) Math.ceil ((Double) Rowscount) / pageSize;

IF (Page> Totalpages)

Page = Totalpages;

IF (Page <1)

Page = 1;

ABS = (PAGE - 1) * Pagesize;

// CurrentPagerows = (Page == Totalpages? RowsCount-Pagesize * (Totalpages-1): pagesize

Else

PageSize = rowscount;

IF (ABS == 0)

ResultSet.beforefirst ();

Else

ResultSet.Absolute (ABS);

// int

While (ResultSet.Next () && currentpagerows <= pagesize) {

Dynabean bean = new basicdynabean (this)

For (INT i = 0; i

String name = proties [i] .GetName ();

Bean.set (name, resultset.getObject (name);

}

Rows.Add (bean);

}

}

/ **

*

Introspect the metadata associated with our results, and populate

* The Properties and PropertiesMap instance

* Variables.

*

* @Param Resultset The ResultSet whose metadata is to

* Be introspected

*

* @Exception SQLEXCEPTION IF An Error Is Encountered Processing The

* Result set metadata

* /

Protected Void Introspect (ResultSet Resultset) throws sqlexception {

// Accumulate An Ordered List of Dynaproperties

ArrayList List = New ArrayList ();

ResultSetMetadata metadata = result.getMetAdata ();

INT n = metadata.getcolumncount ();

For (int i = 1; i <= n; i ) {// jdbc is one-relative!

Dynaproperty Dynaproperty = CreateDynaproperty (Metadata, i);

IF (Dynaproperty! = NULL) {

List.add (dynaproperty);

}

}

// Convert this List Into The Internal Data Structures We needproperties =

(Dynaproperty []) List.toArray (New Dynaproperty [list.size ()]);

For (INT i = 0; i

PropertiesMap.Put (Properties [i] .getname (), Properties [i]);

}

}

/ **

*

factory method to create a new Dynaproperty for the Given Index

* INTO The Result set metadata.

*

* @Param metadata is the result set metadata

* @Param I is the column index in the metadata

* @Return the newly create Dynaproperty Instance

* /

Protected Dynaproperty CreateDynaproperty

ResultSetmetaData metadata,

INT i)

Throws sqlexception {

String name = NULL;

IF (lowercase) {

Name = metadata.getcolumnname (i) .tolowercase ();

} else {

Name = metadata.getcolumnname (i);

}

String classname = NULL;

Try {

ClassName = metadata.getcolumnclassname (i);

} catch (sqlexception e) {

// this is a patch for hsqldb to ignore exceptions

// thrown by its metadata ustementation

}

// default to object Type if no class name could be retrieved

// from the metadata

Class Clazz = Object.class;

IF (classname! = null) {

Clazz = loadingClass (classname);

}

Return New Dynaproperty (Name, Clazz);

}

/ **

*

loads and returns the class of the given name.

* By Default, a loading from the thread context class loadinger is attempted.

* If there is no claim class loader, the class loader used to loading this

* Class Will Be utilized.

*

* @Exception SQLEXCEPTION IF An Exception Was Thrown Trying to Load

* The Specified Class

* /

Protected class loadclass (string classname) throws sqlexception {

Try {

ClassLoader Cl = thread.currentthread (). GetContextClassLoader (); if (cl == null) {

CL = this.getClass (). getClassLoader ();

}

Return (Cl.LoadClass (ClassName);

} catch (exception e) {

Throw new sqlexception

"Cannot Load Column Class '" ClassName "':" E);

}

}

}

转载请注明原文地址:https://www.9cbs.com/read-53840.html

New Post(0)