Spring JDBC Query returns object code tracking

Source: Internet
Author: User

In the encapsulation method when suddenly found through the ResultSetMetaData getColumnCount () to get a column (Rowstat), and each time the value is 1, there is no relevant information found on the foreign web site to see a similar situation, But no one answered. Then I thought about how the JDBC part of spring implemented the mapping, so we discovered the approximate process through spring's source code:

(Here's what you get: Spring's query queries return object T by first getting all the writemethod of the object to be returned, that is, the set method, and then storing it in an array of PropertyDescriptor, The field with the set method is then stored in a mappedfields variable of type map (string,string), gets the number of columns through the getcolumncount of ResultSetMetaData, and then iterates through the number of columns to get the name of the column. Gets the set method of the field from the Mappedfields by the name of the column to assign the object property. )

Here I am. The method entry is query (SQL, new Beanpropertyrowmapper (Voclass))

and tracked it down.

Public <T> T Query (final String SQL, final resultsetextractor<t> rse) throws DataAccessException {Assert.notn ull (SQL, "SQL must not is null"); Assert.notnull (RSE, "ResultSetExtractor must not is null"), if (logger.isdebugenabled ()) {Logger.debug ("executing SQL query ["+ SQL +"] ");} Class Querystatementcallback implements Statementcallback<t>, SQLProvider {public T doinstatement (Statement stmt ) throws SQLException {ResultSet rs = null;try {rs = stmt.executequery (SQL); ResultSet rstouse = rs;if (nativejdbcextractor! = null) {Rstouse = Nativejdbcextractor.getnativeresultset (RS);} Return Rse.extractdata (Rstouse);} Finally {Jdbcutils.closeresultset (RS);}} Public String GetSQL () {return SQL;}} Return Execute (New Querystatementcallback ());}

The method returned is already a T object, you can see that it is return Rse.extractdata (rstouse), this code plays a role, so continue to follow the Extractdata method, where the parameters are found Resultsetextractor<t > RSE is an interface that returns the previous layer of discovery code that calls the Query method as follows:

Public <T> list<t> Query (String sql, rowmapper<t> rowmapper) throws DataAccessException {return query ( SQL, new rowmapperresultsetextractor<t> (RowMapper));}

The parameter is the Rowmapperresultsetmapper object, and continues inside the object to view the Extractdata method:

Public list<t> Extractdata (ResultSet rs) throws SQLException {list<t> results = (this.rowsexpected > 0? ne W arraylist<t> (this.rowsexpected): New Arraylist<t> ()), int rowNum = 0;while (Rs.next ()) {Results.add ( This.rowMapper.mapRow (RS, rownum++));} return results;}

The discovery is RowMapper's Maprow method to map a row of records into an object, where the Rowmaper is an interface, so we need to return to the top to see who implemented the interface, and then we call the place to pass a new Beanpropertyrowmapper (Voclass) object, look inside the object, first see the constructor:

Public Beanpropertyrowmapper (class<t> mappedclass) {initialize (mappedclass);} protected void Initialize (class<t> mappedclass) {this.mappedclass = Mappedclass;this.mappedfields = new HashMap <string, propertydescriptor> (); this.mappedproperties = new hashset<string> (); propertydescriptor[] pds = beanutils.getpropertydescriptors (Mappedclass); for (PropertyDescriptor Pd:pds) {if ( Pd.getwritemethod ()! = null) {This.mappedFields.put (Pd.getname (). toLowerCase (), PD); String underscoredname = Underscorename (Pd.getname ()), if (!pd.getname (). toLowerCase (). Equals (Underscoredname)) { This.mappedFields.put (Underscoredname, PD);} This.mappedProperties.add (Pd.getname ());}}}

It is shown from the constructor that the Initialize method is used to implement the Voclass field and set method in the variables of Mappedfields and PDS, and then we find Maprow this method, which is to set the property value of VO

Public T Maprow (ResultSet rs, int rowNumber) throws SQLException {assert.state (This.mappedclass! = NULL, "Mapped class was Not specified "); T mappedobject = beanutils.instantiate (This.mappedclass); Beanwrapper bw = propertyaccessorfactory.forbeanpropertyaccess (mappedobject); Initbeanwrapper (BW); ResultSetMetaData RSMD = Rs.getmetadata (); int columnCount = Rsmd.getcolumncount ();  Set<string> populatedproperties = (ischeckfullypopulated () New hashset<string> (): null); for (int index = 1; Index <= ColumnCount; index++) {String column = Jdbcutils.lookupcolumnname (RSMD, index); PropertyDescriptor PD = This.mappedFields.get (Column.replaceall ("", ""). toLowerCase ()); if (PD! = null) {try {Object Valu E = GetColumnValue (RS, index, PD), if (logger.isdebugenabled () && RowNumber = = 0) {logger.debug ("Mapping column") + column + "' to-property '" +pd.getname () + "' of type" + Pd.getpropertytype ());} try {bw.setpropertyvalue (Pd.getname (), value);} catch (Typemismatchexception e) {if (VAlue = = NULL && primitivesdefaultedfornullvalue) {logger.debug ("intercepted typemismatchexception for row" + row Number + "and column" + column + "' with value ' + Value +" When setting property ' "+ pd.getname () +" ' of type "+ PD. Getpropertytype () + "on object:" + Mappedobject);} else {throw e;}} if (populatedproperties! = null) {Populatedproperties.add (Pd.getname ());}} catch (Notwritablepropertyexception ex) {throw new Dataretrievalfailureexception ("Unable to map column" + column + "to P Roperty "+ pd.getname (), ex);}}} if (populatedproperties! = null &&!populatedproperties.equals (this.mappedproperties)) {throw new Invaliddataaccessapiusageexception (' Given ResultSet does not ' contain all fields ' + ' necessary to populate object of class ["+ This.mappedclass +"]: "+ this.mappedproperties);} return mappedobject;}

From this method, you can see that spring is the first to get the column, find the field according to the list, and set the value for Vo by the set method of the field. This is the process of spring returning objects.

Spring JDBC Query returns object code tracking

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.