Author: sonymusic 2003.05.13
Vi. constructorutils Addendum
There is another way to create an object: invokeexactconstructor, which requires Parameters
More strict, the passed parameters must strictly comply with the parameter list of the constructor.
For example:
Object [] ARGs = {New INTEGER (1), "Jan "};
Class [] argstype = {Int. Class, String. Class };
Object OBJ;
// The following call will not succeed, because the ARGs [0] type is integer, not int
// OBJ = constructorutils. invokeexactconstructor (month. Class, argS );
// This statement is acceptable because argstype specifies the type.
OBJ = constructorutils. invokeexactconstructor (month. Class, argS, argstype );
Month = (month) OBJ;
System. Out. println (beanutils. getproperty (month, "value "));
VII. methodutils
Similar to constructorutils, a method name parameter must be specified during a call.
8. dynaclass/dynabean
This seems to be one of the most interesting parts of beanutils, which is very simple, simply put, the methods in these two interfaces do not understand
Why are these two interfaces designed. But after seeing resultsetdynaclass, you will understand. The following 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...
}< br>
Rs. close ();
it turns out to be a resultset package. resultsetdynaclass implements dynaclass, and its iterator method returns
resultsetiterator implements the dynabean interface.
after obtaining a dynabean, we can use
dynabean ROW = (dynabean) rows. next ();
system. out. println (row. get ("field1"); // field1 is the name of a field.
Let's look at the usage of rowsetdynaclass in another class. 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 ");
Rsw.ps.exe cutequery ();
// Print the result first.
While (Rs. Next ()){
System. Out. println (Rs. getstring ("name "));
}
Rs. beforefirst (); // beforefirst must be used here, because rowsetdynaclass only rolls forward from the current position
Rowsetdynaclass RSDC = new rowsetdynaclass (RS );
Rs. Close ();
PS. Close ();
List rows = RSDC. getrows (); // return a standard list containing dynabean.
For (INT I = 0; I <rows. Size (); I ++ ){
Dynabean B = (dynabean) rows. Get (I );
System. Out. println (B. Get ("name "));
}
} Catch (exception e ){
E. printstacktrace ();
}
Finally {
Try {
Con. Close ();
} Catch (exception e ){
}
}
Is it interesting? The data of the resultset is encapsulated at the cost of memory usage. If a table has 0.1 million records, RSDC. getrows ()
0.1 million records are returned. @_@
Note the differences between resultsetdynaclass and rowsetdynaclass:
1. resultsetdynaclass is based on iterator. Only one record is returned at a time, while rowsetdynaclass is based on
List, all records are returned at one time. The direct effect is that resultsetdynaclass is faster when there are many data records,
Rowsetdynaclass needs to read all the data in the resultset (and store it inside it), which consumes too much
Memory, and the speed is also slow.
2. resultsetdynaclass processes only one record at a time. Before processing is complete, resultset cannot be closed.
3. The dynabean returned by the next () method of resultsetiterator actually points to a fixed
Object. The internal value is changed after each next () operation. The purpose of this operation is to save memory.
The next generation of dynabean requires you to create another dynabean and copy the data. The following is the code in Java Doc:
Arraylist Results = new arraylist (); // to hold copied list
Resultsetdynaclass RSDC = ...;
Dynaproperty properties [] = RSDC. getdynaproperties ();
Basicdynaclass BDC =
New basicdynaclass ("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 (newrow );
}
In fact, dynaclass/dynabean can be used in many places to store various types of data. Think about it. Hey.
9. Custom mmrowsetdynaclass
Two years ago, I wrote a class with the same target as rowsetdynaclass. However, one more feature is paging, which only retrieves the required data,
In this way, the memory usage will be reduced.
First look at a piece of 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 ");
Rsw.ps.exe cutequery ();
/*
While (Rs. Next ()){
System. Out. println (Rs. getstring ("name "));
}
Rs. beforefirst ();
*/
// The second parameter indicates the page number, and the third parameter indicates the page size.
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 <rows. Size (); I ++ ){
Dynabean B = (dynabean) rows. Get (I );
System. Out. println (B. Get ("name "));
}
} Catch (exception e ){
E. printstacktrace ();
}
Finally {
Try {
Con. Close ();
} Catch (exception e ){
}
}
A customrowsetdynaclass class is used here. The page and pagesize parameters are added to the constructor,
In this way, no matter how many records exist in the Database, only pagesize records can be retrieved. If pagesize =-1, the function and
Rowsetdynaclass is the same. This is applicable in most cases. The code for 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.
* To enable and disable the creation of Type comments go
* WINDOW> preferences> JAVA> code generation.
*/
Public class customrowsetdynaclass implements dynaclass, serializable {
// ------------------------------------------------------------- Constructors
/**
* <P> construct a new {@ link rowsetdynaclass} for the specified
* <Code> resultset </code>. The property names corresponding
* To column names in the result set will be lower cased. </P>
*
* @ Param resultset the result set to be wrapped
*
* @ Exception nullpointerexception If <code> resultset </code>
* Is <code> null </code>
* @ Exception sqlexception if the metadata for this result set
* Cannot be introspected
*/
Public customrowsetdynaclass (resultset) throws sqlexception {
This (resultset, true );
}
/**
* <P> construct a new {@ link rowsetdynaclass} for the specified
* <Code> resultset </code>. The property names corresponding
* To the column names in the result set will be lower cased or not,
* Depending on the specified <code> lowercase </code> value. </P>
*
* <P> <strong> warning </strong>-if you specify <code> false </code>
* For <code> lowercase </code>, 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 using. </P>
*
* @ Param resultset the result set to be wrapped
* @ Param lowercase shocould property names be lower cased?
*
* @ Exception nullpointerexception If <code> resultset </code>
* Is <code> null </code>
* @ Exception sqlexception if the metadata for this result set
* Cannot be introspected
*/
Public customrowsetdynaclass (resultset, Boolean lowercase)
Throws sqlexception {
This (resultset, 1,-1, lowercase );
}
Public customrowsetdynaclass (
Resultset,
Int page,
Int pagesize,
Boolean lowercase)
Throws sqlexception {
If (resultset = NULL ){
Throw new nullpointerexception ();
}
This. lowercase = lowercase;
This. Page = page;
This. pagesize = pagesize;
Introspect (resultset );
Copy (resultset );
}
Public customrowsetdynaclass (resultset, int page, int pagesize)
Throws sqlexception {
This (resultset, page, pagesize, true );
}
// --------------------------------------------------------- Instance variables
/**
* <P> flag defining whether column names shocould be lower cased when
* Converted to property names. </P>
*/
Protected Boolean lowercase = true;
Protected int page = 1;
Protected int pagesize =-1;
/**
* <P> the set of dynamic properties that are part of this
* {@ Link dynaclass}. </P>
*/
Protected dynaproperty properties [] = NULL;
/**
* <P> the set of dynamic properties that are part of this
* {@ Link dynaclass}, keyed by the property name. Individual Descriptor
* Instances will be the same instances as those in
* <Code> properties </code> list. </P>
*/
Protected map propertiesmap = new hashmap ();
/**
* <P> the list of {@ link dynabean} s representing the contents
* The original <code> resultset </code> on which this
* {@ Link rowsetdynaclass} was based. </P>
*/
Protected list rows = new arraylist ();
// ---------------------------------------------------------- Dynaclass Methods
/**
* <P> return the name of this dynaclass (analogous to
* <Code> getname () </code> method of <code> JAVA. Lang. Class </Code), which
* Allows the same <code> dynaclass </code> Implementation class to support
* Different dynamic classes, with different sets of properties. </P>
*/
Public String getname (){
Return (this. getclass (). getname ());
}
/**
* <P> return a property descriptor for the specified property, if it
* Exists; otherwise, return <code> null </code>. </P>
*
* @ Param name of the dynamic property for which a descriptor
* Is requested
*
* @ 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 ));
}
/**
* <P> return an array of <code> properydescriptors </code> FOR THE PROPERTIES
* Currently defined in this dynaclass. If no properties are defined,
* Zero-length array will be returned. </P>
*/
Public dynaproperty [] getdynaproperties (){
Return (properties );
}
/**
* <P> instantiate and return a new dynabean instance, associated
* With This dynaclass. <strong> note </strong>-this operation is not
* Supported, and throws an exception. </P>
*
* @ 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 illegalaccessexception, instantiationexception {
Throw new unsupportedoperationexception ("newinstance () not supported ");
}
// ----------------------------------------------------------- Public methods
/**
* <P> return a <code> List </code> containing the {@ link dynabean} s that
* Represent the contents of each <code> row </code> from
* <Code> resultset </code> 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 values of the Properties
* Of These {@ link dynabean} s. However, it is the application's
* Responsibility to persist any such changes back to the database,
* If it so desires. </P>
*/
Public list getrows (){
Return (this. Rows );
}
// ---------------------------------------------------------- Protected Methods
/**
*
copy the column values 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
* @ exc Eption sqlexception if an error is encountered copying the data
*/
protected void copy (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 <properties. length; I ++ ){
String name = properties [I]. getname ();
Bean. Set (name, resultset. GetObject (name ));
}
Rows. Add (bean );
}
}
/**
* <P> introspect the metadata associated with our result set, and populate
* The <code> properties </code> and <code> propertiesmap </code> instance
* Variables. </P>
*
* @ Param resultset the <code> resultset </code> whose metadata is
* Be introspected
*
* @ Exception sqlexception if an error is encountered processing
* Result set metadata
*/
Protected void introspect (resultset) throws sqlexception {
// Accumulate an ordered list of dynaproperties
Arraylist list = new arraylist ();
Resultsetmetadata metadata = resultset. getmetadata ();
Int n = metadata. getcolumncount ();
For (INT I = 1; I <= N; I ++) {// JDBC is one-relative!
Dynaproperty = createdynaproperty (metadata, I );
If (dynaproperty! = NULL ){
List. Add (dynaproperty );
}
}
// Convert this list into the internal data structures we need
Properties =
(Dynaproperty []) List. toarray (New dynaproperty [list. Size ()]);
For (INT I = 0; I <properties. length; I ++ ){
Propertiesmap. Put (properties [I]. getname (), properties [I]);
}
}
/**
* <P> factory method to create a new dynaproperty for the given Index
* Into the result set metadata. </P>
*
* @ Param metadata is the result set metadata
* @ Param I is the column index in the metadata
* @ Return the newly created 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 implementation
}
// Default to object type if no class name cocould be retrieved
// From the metadata
Class clazz = object. Class;
If (classname! = NULL ){
Clazz = loadclass (classname );
}
Return new dynaproperty (name, clazz );
}
/**
* <P> loads and returns the <code> class </code> of the given name.
* By default, a load from the thread context class loader is attempted.
* If there is no such class loader, the Class Loader used to load this
* Class will be utilized. </P>
*
* @ 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 );
}
}
}
Most of the Code is obtained from the beanutils source code, and only simple modifications are made without additional comments. To be officially used,
Finishing is required.
================================================= ===< br>
about this package, I only want to test it here, but I already have a general impression. At least I know what this package can do.
In fact, this note only plays this role. @