Before writing the spring implementation principle, today we continue to talk about Hibernate implementation principle, this article is just a simple simulation of hibernate principle, mainly simulates the Hibernate session class. Well, the nonsense is not much to say, first look at our code:
Package Com.tgb.hibernate;import Java.lang.reflect.method;import Java.sql.connection;import Java.sql.DriverManager ; Import Java.sql.preparedstatement;import java.sql.sqlexception;import java.util.hashmap;import java.util.List; Import Java.util.map;import org.jdom.document;import Org.jdom.element;import Org.jdom.input.saxbuilder;import Org.jdom.xpath.xpath;import Com.tgb.hibernate.model.user;public class Session {//table name string tableName = "User"; Store database connection Configuration private map<string, string> conconfig = new hashmap<string, string> ();//Store Entity Properties Private map< String, string > columns = new hashmap<string, string > (); Set of Get methods for entities string methodnames[]; Public Session () {//Initialize the entity, there is no way to read the configuration file, a bit of trouble. Columns.put ("id", "id"); Columns.put ("name", "name"); Columns.put ("Password", "password"); Methodnames = new String[columns.size ()]; /** * CREATE DATABASE connection * @return * @throws Exception */public Connection createconnection () throws Excep tion {//parse XML file, read numberAccording to the Library connection configuration Saxbuilder SB = new Saxbuilder (); Document doc = Sb.build (This.getclass (). getClassLoader (). getResourceAsStream ("Hibernate.cfg.xml")); Element root = Doc.getrootelement (); List List = Xpath.selectnodes (Root, "/hibernate-configuration/property"); for (int i = 0; i < list.size (), i++) {element property = (Element) list.get (i); String name = Property.getattributevalue ("name"); String value = Property.gettext (); Conconfig.put (name, value); }//Get database connection Class.forName (Conconfig.get ("driver") according to the configuration file; Connection con = drivermanager.getconnection (conconfig.get ("url"), Conconfig.get ("username"), Conconfig.get (" Password ")); return con;} /** * Save method, persisted object * @param user */public void Save (user user) {String sql = Createsql (); SYSTEM.OUT.PRINTLN (SQL); try {Connection con = createconnection (); PreparedStatement state = (preparedstatement) con.preparestatement (SQL); for (int i=0;i<methodnames.length;i++) {//Gets the object of each method means = User.getclass (). GetMethod (Methodnames[i]); Get his return type Class CLA = Method.getreturntype (); Sets each property value in the inserted database according to the return type. if (Cla.getname (). Equals ("java.lang.String")) {String returnvalue = (string) method.invoke (user); State.setstring (i+1, returnvalue); } else if (Cla.getname () equals ("int")) {Integer returnvalue = (integer) method.invoke (user); State.setint (i+1, returnvalue); }} state.executeupdate (); State.close (); Con.close (); } catch (ClassNotFoundException e) {e.printstacktrace (); } catch (SQLException e) {e.printstacktrace (); } catch (Exception e) {e.printstacktrace (); }}/** * Get SQL statement * @return RETURN SQL statement */private String Createsql () {//strcolumn represents the attribute column in the table in the database. and connect it together. String strcolumn = ""; int index=0; For (String Key:columns.keySet ()) {Strcolumn +=key+ ","; String v = columns.get (key); To get the property's Get method, you need to capitalize the first letter of the property, such as: getId () v = "Get" + character.touppercase (V.charat (0)) + v.substring (1); Methodnames[index] = v; index++; } StrcoLumn = strcolumn.substring (0, Strcolumn.length ()-1); Stitching parameter placeholders, i.e.: (?,?,?) String strvalue = ""; for (int i=0;i<columns.size (); i++) strvalue + = "?,"; strvalue = strvalue.substring (0,strvalue.length ()-1); String sql = "INSERT INTO" + TableName + "(" + Strcolumn + ")" + "values (" + strvalue + ")"; return SQL; } }
The above code is mainly to complete the hibernate Save () method, the class has a construction method, a method of building a SQL statement, a method to obtain a database connection. Finally, the Save () method is used in conjunction with the previous methods to obtain the result, persisting the entity object to the database.
The basic principle is: first, to obtain the fundamental information of the database connection, and then to obtain the mapping information of the entity, and then, the most critical step, according to the information obtained earlier, the Assembly of various SQL statements (in this case only simple insert), the entity according to different requirements to find or update (increase, up, change) to the database.
Of course, the specific implementation of Hibernate is not so simple, hibernate in a large number of use of cglib dynamic agent, where the load () method is an example. As we all know, the call to load () method is hibernate does not send SQL statements to the database, the load () method is a proxy class for the target entity, until the actual use of the entity object will not go to the database query. This is also a lazy-loading implementation of hibernate.
To summarize, these frameworks can be flexible because they are good use of lazy loading mechanism, in the runtime to determine who instantiated, who needs to instantiate who, when and when to instantiate. Is it not flexible to design? These ideas deserve to be studied and applied to our design.