Hibernate research

xiaoxiao2021-03-06  21

Maybe you have heard of Hibernate's name, but may not know it, maybe you have been eager to use it for development, then this article is what you need! In this article, I will focus on the core API call library of Hibernate and explain its basic configuration. After reading this article, I believe that you have a profound understanding of what is ORM (Object / Relationship map) and its advantages, let us start to show its power through a simple example. As some traditional classic computer articles will begin through a "Hello, World", we are not exception, we will also explain Hibernate development methods from a relatively simple example, but if you want to truly explain Hibernate Some important ideas, only printed on the screen is far less than enough, in our sample program, we will create some objects and save it in the database and then update and query them.

"Hello World" hibernate application defines some persistent classes and defines the mapping relationships of these classes and database tables. In our "Hello World" sample program contains a class and a mapping file. Let us see what this simple persistence class contains? How is the mapping file defined? Also, how should we use Hibernate to operate this persistent class. The purpose of our simple sample program is to store some persistent classes in the database and then take it out from the database and display the text body to the user. Where Message is a simple lasting class: which contains the information we have to display, the source code is as follows: List 1 Message.java a simple lasting class

package hello; public class Message {private Long id; private String text; private Message nextMessage; private Message () {} public Message (String text) {this.text = text;} public Long getId () {return id;} private void setId (Long id) {this.id = id;} public String getText () {return text;} public void setText (String text) {this.text = text;} public Message getNextMessage () {return nextMessage;} public Void setNextMessage (Message nextMessage) {this.nextMessage = nextMESSAGE;}} Message class has three properties: Message ID, message body, and a pointer to the next message. The id attribute allows our application to identify this message, usually it is equivalent to the primary key in the database, and if the instance object of multiple Message classes has the same ID, then they represent the same record for a table of the database. Here we have chosen long integer as our ID value, but this is not required. Hibernate allows us to use any type as an ID value of the object, and we will describe it in detail later. You may notice the code of the Message class similar to the Javabean code style, and it has a constructor without parameters. In our future code, I will continue to use this style to write a long-lasting code. Hibernate automatically manages the instance of the Message class, and makes it permanently through the internal mechanism, but the Message object does not implement any classes or interfaces about Hibernate, so we can use it as a normal Java class: Message Message = New Message ("Hello World"); System.Out.println (Message.getText ()); above this code is the result we expect: it prints "Hello World" to the screen. But this is not our ultimate goal; in fact, Hibernate is very different from the environment such as EJB containers in a persistent layer. Our persistent class (Message class) can be used in an environment that is not related to the container, unlike EJBs that must have an EJB container to execute. In order to make it clearer, the following code saves our new messages to the database:

Session session = getsessionFactory (). OpenSession (); transaction tx = session.begintransaction (); message message = new message ("Hello World"); session.save (Message); tx.commit (); session.close () The above code calls Hibernate's Session and Transaction interfaces (About GetSessionFactory () methods. We will mention it immediately). It is equivalent to we have implemented the following SQL statement:

Insert Into Messages (Message_ID, Message_text, Next_MESSAGE_ID) VALUES (1, 'Hello World', NULL) In the above SQL statement, what is the value of the Message_ID field to the end? Since we don't have the ID attribute of the message object in the previous code, is it null? In fact, Hibernate has handled specially for ID attributes: because it is a unique identifier of an object, Hibernate will automatically give it a unique value for it (we will tell it in the later content. How to generate this value). We assume that you have created a table called Message in the database, so since the previous section allows us to store the Message object into the database, then we will take them one by one. The following code will take all the Message objects in the database, and print them on the screen to the screen: session new assion = getsessionFactory () () (); transaction newTransaction = newsession.BegintransAction () List message = newssion.find ("from message as m order by m.text asc"); system.Sout.println (Messages.Size () "for (Iterator iter = message); Iterator (); it.hasnext (); {message message = () iter.next (); system.get.println; newTransaction.commit (); newession.close (); In the above code, you may be plagued by this parameter by the Find () method: "from message as m order by m.text asc", in fact it is the query language of Hibernate, all called Hibernate Query Language (HQL ). Popularly, the relationship between HQL and SQL is almost the relationship between dialects and Mandarin. You will feel that it is a bit similar to the SQL statement. In fact, when Find () is called, Hibernate translates this HQL language into the following SQL statement:

Select M.Message_ID, M.Message_Text, M.Next_Message_IDFROM Messages Morder by M.Message_text ASC The following is the result:

1 Message (s) Found: Hello World If you have no development experience in ORM (object-relational map), you may want to find this SQL statement in some place in the code, but you may be disappointed in hibernate: It does not exist at all! All SQL statements are dynamically generated by Hibernate. Maybe you will feel the shortcomings, right! Just by the above code Hibernate is unable to hold our Message class. We also need some information, this is the mapping definition table! This table is reflected in the XML format in Hibernate. It defines how the property of the Message class performs one by one with the fields of the Messages table in the database, the list 2 is the mapping profile list of this sample program: List 2 : Sample program object - Relational mapping table The above document tells Hibernate how to map the Message class to the Messages table, where the Id property of the Message class corresponds to the Message_ID field of the table, the text property corresponds to the Message_Text field of the table, the nextMessage property is a multi-to-one relationship, it Compared with the next_message_id in the table. Compared to some open source projects, Hibernate's profile is actually very easy to understand. You can easily modify and maintain it. As long as you define the corresponding relationship between the persistent class and the table field in the database, Hibernate will automatically generate the SQL statement to insert, update, delete, find the Message object, and you can do not write a SQL statement, or even Need to understand SQL language! Now let's make a new test, let's take the first Message object first, then modify its message body, and finally we regenerate it into a new Message object and use it as the next message of the first Message object. The code is as follows: Listing 3 Updating a message

Session session = getSessionFactory () openSession ();. Transaction tx = session.beginTransaction (); // 1 is the generated id of the first messageMessage message = (Message) session.load (Message.class, new Long (1)) Message.Settext ("Greetings Earthling"); Message NextMessage = New Message ("Take Me To Your Leader); Message.setNextMessage (NEXTMESSAGE); TX.CMmit (); session.close (); above when calling the code segment, generated automatically inside Hibernate following SQL statement: select m.MESSAGE_ID, m.MESSAGE_TEXT, m.NEXT_MESSAGE_IDfrom MESSAGES mwhere m.MESSAGE_ID = 1insert into MESSAGES (MESSAGE_ID, MESSAGE_TEXT, NEXT_MESSAGE_ID) values ​​(2, 'Take me to your leader (please) ', null) update MESSAGESset MESSAGE_TEXT =' Greetings Earthling ', NEXT_MESSAGE_ID = 2where MESSAGE_ID = 1 when the first text property and nextMessage Message object is to modify the program, please note that Hibernate is how to detect this Various and how to automatically update it in the database. This is actually a very valuable feature of Hibernate. We call it "automatic dirty data detection". This feature of Hibernate makes it easy to inform Hibernate when we modify the properties of a lasting object. Updates in the database. Similarly, when the first Message object calls the setNextMessage () method When the second Message object is a reference to its next message, the second message can be automatically saved in the database without calling the save () method. . This feature is called "cascaded preservation", which also relies on our explicitly call the Save () method to call the second Message object. If we run the previous paragraph to print the code in all the Message objects in the database, the results of its operation are as follows:

2 Message (s) Found: Greetings EarthlingTake Me To Your Leader "Hello World" sample program is now introduced. We finally have a simple understanding of Hibernate. Here we will go back, and the main API tuning for Hibernate is a brief introduction: understanding Hibernate architecture When you want to use Hibernate to develop your own persistent layer-based application, One thing should be a programming interface that is familiar with it. Hibernate's API interface is designed as much as possible to facilitate developers. However, due to the complexity of ORM, its API is generally impossible to design very simple. But don't worry, you don't have to know all the Hibernate's API interface. The following figure describes some important interface classes in the application layer and persistence:

In the above figure, we put the application layer in the upper part of the persistence layer, in fact, in the traditional item, the application layer acts as a client role of the persistent layer. But for some simple projects, application layers and persistence layers do not distinguish it as clear, this is nothing, in which case you can combine the application layer and the lasting layer into a layer. In the above figure, Hibernate's interface can be roughly divided into the following types: • Some interfaces that are called by the user to complete basic creation, read, update, delete operation, and query operations. These interfaces are the main interface of Hibernate to implement the business logic of user programs, including session, transaction, and query. · Hibernate is used to read interfaces such as mapping tables, typical representatives have the Configuration class. · Callback interface. It allows applications to operate corresponding to some events, such as Interceptor, Lifecycle, and Validatable are all interfaces. Some interfaces that can be used to extend the mapping mechanism of Hibernate, such as Usertype, CompositeUsertype, and Identifiergenerator. These interfaces can be implemented by the user program (if necessary). Hibernate uses the following technique in the J2EE architecture: JDBC, JTA, JNDI. Where JDBC is a base layer that supports relational database operations; it combines with JNDI and JTA, making Hibernate to easily integrate into the J2EE application server. Here, we will not discuss all the methods in the Hibernate API interface in detail, we only briefly talk about the function of each primary interface. If you want to know more, you can in the hibernate source package. The source code for these interfaces in the sf.hibernate subparacket. Let's take a look at all the main interfaces: 5 core interfaces below the core interface are almost in any actual development. With these interfaces, you can store and get persistent objects, but also can perform transactional control. The Session Interface Session Interface is the most important interface for Hibernate developers. However, in Hibernate, instantiated session is a lightweight class, creating and destroying it will not take up a lot of resources. This is really important in the actual project, because in the customer program, it may be constantly created and destroyed, if the SESSION is overhead, it will bring adverse effects to the system. But it is worth noting that the session object is non-threaded, so in your design, it is best to create only one session object. In the minds of Hibernate designers, they think of the session as an intermediate interface between data connection and transaction management. We can imagine the session into a buffer of a lasting object, and Hibernate can detect changes in these persistent objects and refresh the database in time. We sometimes call the session is a persistent layer manager because it contains this persistent layer-related operations, such as storage persistent objects to the database, and from the database from the database. Note that Hibernate's session is different from HttpSession in the JSP app. When we use the session this term, we refer to the session in hibernate, and we will refer to the httpsesion object as user session later. The sessionFactory interface uses a design pattern - factory mode, and the user program acquires the instance of the session from the factory class sessionFactory.

What is strange that sessionFactory is not a lightweight! In fact, its designer's intent is to let it share throughout the app. Typically, a project usually only requires a sessionFactory enough, but when your project is to operate multiple databases, then you must specify a sessionFactory for each database. SessionFactory actually played a buffer role in Hibernate, buffering Hibernate automatically generated SQL statements and some other mapping data, and buffered some data that may be repeated in the future. The Configuration Interface The function of the Configuration interface is to configure Hibernate and start it. During the startup of Hibernate, the instance of the Configuration class first locates the location of the map document, reads these configurations, and then creates a sessionFactory object. Although the Configuration interface only plays a small role in the entire Hibernate project, it is the object you have encountered when you start Hibernate. Transaction Interface Transaction Interface is an optional API, you can choose not to use this interface, replaced by Hibernate designers write underlying transaction processing code. The Transaction interface is an abstraction of the actual transaction implementation, including JDBC transactions, useertransaction in JTA, and even CORBA transactions. This is designed to make developers can use a unified operational interface that makes their own projects can easily remove between different environments and containers. Query and Criteria Interface Query interface allows you to easily query the database and persistent objects, which can have two ways: HQL language or local database SQL statement. Query is often used to bind query parameters, limit query records, and finally perform query operations. The Criteria interface is very similar to the Query interface, which allows you to create and perform object-oriented standardized queries. It is worth noting that the query interface is also lightweight, it cannot be used outside the session. The Callback interface When some useful events occur, such as the load, storage, deletion of persistent objects, the Callback interface notifies Hibernate to receive a notification message. In general, the Callback interface is not necessary in the user program, but when you create an audit log in your project, you may use it. An important term: Type Hibernate designers invented a term: Type, which is a very foundation in the entire framework, with powerful elements. A Type object can map a Java type into a field in a table in the database (actually, it can be mapped to multiple fields of the table). All attributes of persistent classes correspond to a TYPE. This design idea uses Hibernate with a high degree of flexibility and scalability. Hibernate has a built-in Type type, almost all Java basic types, such as java.util.currency, java.util.calendar, byte [], and java.io.serializable. Not only that, Hibernate also supports user-defined type, and you can join your own Type by implementing interface Usertype and Interface CompositeUsertype. You can use this feature to use Type, such as Address, Name, such as Address, Name, so you can get more convenient to make your code more elegant.

Custom Type is a core feature in Hibernate, which encourages you to use it to create a flexible, elegant project! Strategy Interface Hibernate has a different point-high scalability different from some other open source software, which is implemented through its built-in policy mechanism. When you feel some of Hibernate, or if you have some defects, you can develop your own strategy to replace it, and what you want to do is just inheriting a policy interface, then implement your new policy Yes, the following is its policy interface: • Generation of primary key (Identifiergenerator interface) · Local SQL language support (Diagect abstraction class) · Buffer mechanism (Cache and CacheProvider interface) · JDBC Connection Management (ConnectionProvider Interface) · Transaction Management ( TransactionFactory, Transaction, and TransactionManagerLookup interface) • ORM Policion (ClassPersister interface) • Property Access Policy (PropertyAccessor Interface) • Creation of the Agent Object (ProxyFactory Interface) Hibernate creates a default implementation for the above listed, so if You just have to enhance its functionality, just simply inherit this class, no need to write code from the beginning. The above is some core interfaces of Hibernate, but when we really start using it, your mind may always have a question: What way I passed, and where to get session? Let's answer this question. The basic configuration now reviews our previous content: We wrote an example program and briefly explain some of Hibernate's core classes. But to truly make your project run, there must be one thing to do: configuration. Hibernate can be configured to run in any Java environment, generally, it is usually used in a 2-3-layer C / S mode project and is deployed on the server. In this project, a web browser, or a Java GUI program is acting as a client. Although our focus is mainly concentrated in multi-layer web applications, it can actually use Hibernate in some command-based applications. Also, the configuration of Hibernate is different in different environments. Hibernate is running in two environments: manageable environments and unmanageable environments • Manage environments - such environment can manage: pool resource management, such as database connection Pool and business management, security definitions. Some typical J2EE servers (JBoss, WebLogic, WebSphere) have been implemented. · Unmanageable environments - just provide some basic functions, such as a servlet container environment like Jetty or Tomcat. An ordinary Java desktop app or command line program can also be considered in this environment. This environment cannot provide automatic transaction, resource management, or security management, which must be defined by the application. Hibernate designers designed these two environments, so there is only one environment for developers: manageable environment. If the actual project is built in an unmanable environment such as Tomcat, the Hibernate will use its own transaction code and JDBC connection pool to make it a manageable environment. For manageable environments, Hibernate integrates themselves in this environment. For developers, you have to do it very simple: just create a sessionFactory class from a Configuration class.

Creating a SessionFactory object In order to create a sessionFactory object, you must create an instance of a Configuration class when you started when Hibernate initializes, and handles the written map files. In this way, the Configuration object can create a sessionFactory object. After the SessionFactory object is successful, the Configuration object is useless, you can simply discard it. Sample code is as follows: Configuration cfg = new Configuration (); cfg.addResource ( "hello / Message.hbm.xml"); cfg.setProperties (System.getProperties ()); SessionFactory sessions = cfg.buildSessionFactory (); above In the code, the location.hb.xml of this mapping file is relatively special, which is related to the current classpath. For example, ClassPath contains the current directory, which can be saved in the Hello directory in the current directory in the message.hbm.xml mapping file in the above code. As a convention, Hibernate's mapping file is default .htm.xml as its extension. Another agreement is to hold a profile for each persistent class, think about if you write all persistent classes to a separate profile, then this configuration file is definitely very large, not easy to maintain. But there is a new question here: If you write a configuration file for each class, where should so many configuration files? Hibernate recommends that you save each mapping file in the same directory as your persistent class, and with your lasting class. For example, the Message persistence class in our first sample program is placed in the Hello directory, then you must store a mapping file named message.hbm.xml in this directory. Such a lasting class has its own mapping file to avoid the situation in which "struts-config.xml hell" like the Struts project is. If you don't follow this regulation, you must manually load a mapource () method to load a map file; however, if you follow this regulation, you can easily use the addclass () method to last for a long time and Its mapping file is loaded, the following is an example code that reflects this convenience:

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

New Post(0)