Spring + hibernate data persistence layer (transfer)

xiaoxiao2021-03-06  72

For J2EE applications, the processing of transactions generally have two modes: 1. Transaction depends on a particular transaction resource is the most common mode in application development, that is, transaction management through the transaction mechanism provided by specific resources. For example, through JDBC, JTA's Rollback, Commit method; Hibernate Transaction's Rollback, Commit method, etc. This method is quite familiar. 2. Relying on the parametric transaction management of the container to achieve external management of the transaction through the intensive parametric transaction mechanism provided by the container, such as the transaction management mode in EJB. For example, in the following EJB transaction definition, the DOSSIONBEAN MySession is defined as a Required. That is, when the MySession.DoServer method is called by a thread, the container incorporates this thread into the transaction management container. If an exception occurs during the method call, the current transaction will be automatically rolled back by the container, and if the method is end, the container will Automatically submit the current transaction. MySession Remote DOSERVICE < Method-Param> Java.lang.String Required parameterized transaction for container management Program development provides considerable flexibility, while the application logic does not need to write transaction code because of the management of the transaction to the container, there is no need to save the transaction code, which greatly saves the amount of code (especially for the need to operate multiple transaction resources simultaneously), thereby improving Productivity. However, the cost of using EJB transaction is quite high, open the price of EJB containers, EJB learning costs, deployment, migration, maintenance difficulty, and performance overhead brought by container itself (this often means higher hardware configuration ) Brought us quite confused. At this time, the advantages of business management often cannot offset the above negative impacts.

What can Spring transaction management give us what? The XML configuration segment shows the transaction setting mode in Spring: JDBC: mysql: // localhost / sample user mypass < / property> < / bean> Springframework developer's Guide Version 0.6October 8, 2004 So many open source projects. Why not Open your Documents? PropAgation_required

Propagation_required, readonly configuration resource definitions such as DataSource, TransactionManager. These resources are a TransactionProxyFactoryBean service called UserDaoproxy, while UserDaoproxy has a transactional package for UserDao containing actual data logic. It can be seen that in the "TransactionAttributes" attribute of UserDaoproxy, we define the transaction policy for Userdao, which is intended to start the transaction management range in INSERT (such as the UserDao.insertuser method). If you throw an exception in this method, Spring rolls the current transaction, if the method is ended normally, the transaction is submitted. For all the methods starting with GET (such as the userDao.getuser method), the read-only transaction mechanism is processed. (Set as a read-only transaction, the persistence layer can be optimized for the data operation, such as for the only transaction Hibernate, and some database connection pools and JDBC drivers are also specialized for read-only operations. In conjunction with the sensibility cognition brought about by the above, see what is different from the transaction management in the EJB, or what is the advantage. There is naturally many aspects here, but the author believes that the two most critical is: 1. Spring can incorporate any Java Class into transaction management here Userdao just a normal Java Class we have written, which contains some basic data application logic. With Spring, we can simply implement the configurable transaction. That is, we can specify a transaction management mechanism at a certain approach. With the contrast, if the transaction management function provided by the EJB container, we have to modify Userdao in accordance with EJB specification, convert it to a standard EJB. 2. Spring transaction management does not rely on specific transaction resources. The EJB container must rely on JTA to provide transaction support. Spring's transaction management supports a variety of transaction resources such as JDBC, JTA. This provides us with more choices, making our system deployment more flexible. After simple analysis of the Spring transaction management mechanism, we will combine the specific transactional application mechanisms of the persistence layer package, and discuss the transaction management in Spring. The persistence layer package JDBCSpring has a good package for JDBC, which reduces the complexity of JDBC operations to a considerable extent by providing corresponding templates and auxiliary classes. And thanks to Spring well isolated design, JDBC package library can be used out of Spring Context independently, that is, even if the system does not use Spring as a structural frame, we can also use Spring's JDBC section (Spring-Dao. JAR) to improve our code.

As a contrast, let us first let us see a traditional JDBC code: Connection conn = null; statement stmt = null; try {conn = datasource.getConnection (); stmt = con.createstatement (); stmt.executeUpdate ("Update User Set Age = 18 where id = 'erica' ");} finally {if (stmt! = null) {Try {stmt.close ();} catch (sqlexception ex) {logger.warn (" Exception In Closing JDBC Statement, EX);}}} if (conn! = null) {Try {conn.close ();} catch (sqlexception ex) {logger.warn ("Exception in closing jdbc connection", EX);}}} Similar to the above code Very common. To perform a SQL statement, we must write 22 line code, and 21 lines are not associated with application logic, and such code will be repeated in the system else (perhaps each of the required database access). So everyone start looking for some design patterns to improve such design, the application of the Template mode is one of the typical improvements. Spring's JDBC packages, a large part is to achieve a Template mode, which provides an excellent JDBC template library, with this tool, we can easily improve traditional JDBC coding. Below is the code that modified by Spring JDBC Template, which completed the same function as the above code. JDBCTemplate JDBCTemplate = New JDBCTemplate (Datasource); JDBCTemplate.Update ("Update User Set Age = 10 Where ID = Erica '); It can be seen that the two lines of code have completed the functionality of the 19-line code implementation. All redundant code is brought into JDBCTemplate through reasonable abstract collection. Without sigh, with the Template mode, we can roughly achieve such a template, but Spring designers have completed this step in advance. Org.springframework.jdbc.core.jdbcTemplate contains this template implemented code, which is carefully designed by the Spring design team, which is a model for template applications. In particular, the use of callbacks, making the entire template structure clear and efficient. It is worth reading. TIPS: In actual development, the hard-encoded SQL statement in the code can be used as a String type property of the bean, which is defined in the configuration file with the DI mechanism to implement SQL parameterization configuration.

The above example again some improvements, by performing the update operation to avoid PrepareStatement SQLInjection vulnerabilities 9: JdbcTemplate jdbcTemplate = new JdbcTemplate (dataSource); jdbcTemplate.update ( "UPDATE user SET age = WHERE id =??", New PreparedStatementSetter () {public void setvalues ​​(preparedStatementSetter PS) throws sqlexception {ps.setint (1, 18); ps.setstring (2, "erica");}}); can be seen, the above reference is another version of the Update method, pass There are two parameters, the first SQL for creating PreparedStatement. The second parameter is the preparedStatementStter for the preparedStatement setting parameters. The method of the second parameter is more unique, and we are dynamically built a preparedStatementSetter class and implement this abstract setValues ​​method. Then passes this class into the Update as a parameter. After the UPDATE accepts the parameters, the method of the second parameter can be invoked to complete the initialization of PreparedStatement. Spring JDBC Template has used such a Callback mechanism, which brings great flexibility and scalability. The use of the UPDATE method is demonstrated (the same operation applies to Update, Insert, Delete). Below is an example of a query. final List userList = new ArrayList (); JdbcTemplate jdbcTemplate = new JdbcTemplate (dataSource); jdbcTemplate.query ( "SELECT name, sex, address FROM user WHERE age> 18", 9 SQL Injection: SQL statements directly lead to the introduction of parameter values System vulnerability, please refer to the following papers: http://www.governmentsecurity.org/articles/sqlinjectionmodesofattackdeFenceandWhyitmatters.php

SpringFrameWork Developer's Guide Version 0.6October 8, 2004 So many open source projects Why not Open your Documents new RowCallbackHandler () {public void processRow (ResultSet rs) throws SQLException {User user = new User ();.? User.setId (rs. GetString ("name")); user.setsex (rs.getstring ("SEX")); user.setaddress (rs.getstring ("address"); userlist.add (product);}}); here incoming There are two parameters of the Query method, the first is the SELECT query statement, the second is a RowCallbackHandler instance, and we parsed each row record obtained by RowCallbackHandler and creates a USER data object. A manual OR mapping is implemented. In addition, we can also call the stored procedure through the JDBCTemplate.call method. Query, the UPDATE method has many other different parameter versions, please refer to SpringJavadoc. JDBCTemplate and JDBCTemplate operation in the above example use JDBC default autocommit mode, that is, we can not guarantee atomicity of data operation (either all of them, either all invalid), such as jdbctemplate jdbctemplate = new JDBCTemplate (Datasource) JDBCTemplate.Update ("Update User Set Age = 10 Where ID = 'Erica'"); JDBCTemplate.Update ("Update User Set Age = Age 1 WHERE ID = 'Erica'); due to AutoCommit mode, After a UPDATE operation is complete, the record "Erica" ​​in the database has been updated. If the second operation fails, we cannot make the entire transaction back to the initial state. This example may be irrelevant, but for a financial account system, such problems will result in fatal errors. In order to achieve data operation atomicity, we need to introduce transaction logic in the program, introduce transaction mechanisms in JDBCTemplate, there are two ways in Spring: 1. Transaction Management of Code Control 2. Transaction Management of Parameterized Configuration The following two ways.

U-Code Control Services First, make the following configuration, assuming the configuration file as (Application-Context.xml): jdbc: jtds: sqlserver: //127.0.0.1: 1433 / sample test Changeit configuration included in configuration Three nodes: Ø DataSource We use apache dhc The DataSource provided by the P component is implemented and parameters such as JDBC drivers, database URLs, usernames, and passwords. Ø TransactionManager For the JDBC DataSource type data source, we selected DataSourceTransactionManager as the transaction management component.

If you need to use a container-based data source (JNDI), we can use the following configuration: Springframework developer's Guide Version 0.6OCTOBER 8, 2004 SO MANY OPEN SOURCE Projects. Why not open your documents? jdbc / sample Ø Userdao has declated a USERDAO BEAN and specifies DataSource and TransactionManger resources. UserDAO corresponding code is as follows: public class UserDAO {private DataSource dataSource; SpringFrameWork Developer's Guide Version 0.6October 8, 2004 So many open source projects Why not Open your Documents private PlatformTransactionManager transactionManager; public PlatformTransactionManager getTransactionManager () {return transactionManager;} public.? void setTransactionManager (PlatformTransactionManagertransactionManager) {this.transactionManager = transactionManager;} public DataSource executeTestSource () {return dataSource;} public void setDataSource (DataSource dataSource) {this.dataSource = dataSource;} public void insertUser () {TransactionTemplate tt = new TransactionTemplate ( getTransactionManager ()); tt.execute (new TransactionCallback () {public Object doInTransaction (TransactionStatus status) {JdbcTemplate jt = new JdbcTemplate (executeTestSource ()); jt.update ( "insert into users (username) values ​​( 'xiaxin') ""); "" INSERT INTO USERS (ID, Username) Values ​​(2, 'Erica'); "); return null;}});}} can be seen, in Insertuser In the method, we introduced a new template class: org.springframework.transaction.support.transactionTemplate.

TransactionTemplate encapsulates the functions of transaction management, including transaction rollbacks, and transactions submitted after successful operation. Like JDBCTemplate, it makes us no need to be in trivial TRY / CATCH / FINALLY code. The operation performed in the DoIintrance, if throwing unfailed exceptions will be automatically rolled back, if successful is executed, will be submitted automatically. Here we deliberately create some exceptions to observe whether the database operation rollback (deliberately triggered an exception by updating the ID field in the second statement): Write a simple TestCase to observe the actual effect: InputStream is = new fileInputStream (" Application-context.xml "); xmlbeanfactory factory = new xmlbeanfactory (IS); userdao userdao = (userdao) Factory.getBean (" Userdao "); UserDao.Insertuser (); I believe how much I think the code is a bit messy, Callback class Writing seems to have been contrary to daily programming habits (although the author thinks this method is more interesting, because it is smartly solved the problem that the author has encountered in the early self-developing data access template). How to further avoid these problems? Spring's container transaction management mechanism reflects its powerful energy.

u Parameterized Configuration Transaction Management Adds a transaction-context.xml to add a transaction agent (UserDaoproxy) configuration, and because the transaction is managed by the container, Userdao no longer needs TransactionManager settings, removes it: PROPAGATION_REQUIRED PROPAGATION_REQUIRED, readOnly Springframework Developer's Guide Version 0.6october 8, 2004 SO MANY OPEN SOURCE Projects. Why Not Open Your Documents? The UserDaOProxy node configures a transaction agent for Userdao Bean (specified by the target property). Through TransactionAttributes properties, we specify the management policy of the transaction, that is, transaction management of all the INSERT, if the abnormality is thrown, the transaction in the automatic rollback method, if successfully, then after the method is completed Transaction is submitted. On the other hand, for other methods (represented by wildcard *), read-only transaction management is performed to achieve better performance.

UserDAO.insertUser corresponding code changes as follows: public void insertUser (RegisterInfo regInfo) {JdbcTemplate jt = new JdbcTemplate (executeTestSource ()); jt.update ( "insert into users (username) values ​​( 'xiaxin');") JT.Update ("INSERT INTO Users (ID, Username) Values ​​(2, 'Erica');");} The test code is modified as follows: InputStream is = new fileInputStream ("Application-Context.xml"); XMLBeanFactory Factory = NEW XMLBeanFactory (IS); // Note that this must be referenced by proxy Bean "UserDaoproxy", not directly getBean ("Userdao") //, there is still a potential problem related to mandatory transformation, see Hibernate in Spring section After / / a supplementary description of the mandatory transformation. Userdao Userdao = (userDao) Factory.getBean ("UserDaoproxy"); UserDao.insertuser (); can be seen, INSERTUSER becomes very simple. Data logic is clearly visible, comparing transaction management controlled by previous code, as well as traditional JDBC operations, I believe that everyone will have some Hawran cheerful feelings. The careful reader will say that this only shifts the code to the configuration file and does not reduce too much workload. This difference may not be important. From the perspective of application maintenance, the configuration of transaction management is clearly more advantageous. What's more, in actual development, if the previous design is meticulous, the transaction characteristics of the method will generally do not change much, after the maintenance process, we only need to face the data logic in the code. Above we introduce the template operations and the transparency mechanism in Spring in JDBCTemplate. Spring as an open application development platform. It also provides good support for other components. In the persistence layer, Spring provides templates for Hibernate, IBATIS, and JDO, and these implementations have also provided strong support for our development. Below we will introduce the use of the two mainstream persistence frames of Hibernate, IBATIS in Spring. As for JDO, due to the actual development is not wide (actually thinking that JDO prospects is worrying), it will not focus on the introduction, interested readers can see the relevant chapters in Spring-Reference. SpringFrameWork Developer's Guide Version 0.6October 8, 2004 So many open source projects. Why not Open your Documents? Hibernate in SpringHibernate in open source persistence framework is undoubtedly the most vivid recent role, its author has even been invited to join the new EJB Design Work In the middle, see the wonderful advice of Hibernate design. About Hibernate, discussed in another document of the author: "Hibernate Development Guide" http://www.xiaxin.net/Hibernate_Dev_guide.rar

. The following mainly introduces the application of Hibernate in Spring, and there is not much to describe Hibernate itself. Also taking into account Spring's good support for container transactions, the author recommends to use the container management transaction in the development of Spring Framework, to obtain the best readability of data logic code. In the following introduction, the transaction management part of the code control will be subtocated, and the parameterized container transaction management application will be focused. The principle of code-level transaction management implementation is basically consistent with JDBCTemplate above, and interested readers can see related content in Spring-Reference. For the sake of concise, we still use the example above.

First, for Hibernate, we need to configure the following: hibernate-context.xml: net.sourceforge.jtds.jdbc.driver jdbc: jtds: SQLServer: //127.0.0.1: 1433 / Sample Test changeit net / xiaxin / dao / entity / user.hbm.xml Springframework Developer's Guide Version 0.6october 8, 2004 So Many Open Source Projects. why not open your Documents? net.sf.hibernate.dialect.SQLServerDialect True

Class = "Net.xiaxin.dao.userdao> PROPAGATION_REQUIRED PROPAGATION_REQUIRED, readOnly SpringFrameWork Developer's Guide Version 0.6 October 8, 2004 SO Many Open Source Projects? Why not open your documents? The difference between the configuration in the JDBC above is mainly: 1. The introduction of SessionFactory creates and maintains session in Hibernate through SessionFactory. Spring also integrates the configuration of sessionFactory without having to set the sessionFactory via hibernate.cfg.xml. The MappingResources property of the SessionFactory node contains the path to the mapping file. Multiple mapping files can be configured under the List node. The HibernateProperties node accommodates all property configurations. The SESSIONFACTORY configuration here can be interpreted corresponding to the traditional hibernate.cfg.xml file structure. 2. Using Hibernate-oriented TransactionManager: org.springframework.orm.hibernate.hibernateTransActionManager can be seen that for transaction management configuration, it is basically the same as the previous chapter.

Corresponding to the UserS table, establish the following mapping class: user.java: / *** @ hibernate.class table = "users" * / public class user {public string username; public string password; / *** @ hibernate.id * column = "id" * type = "java.lang.Integer" * generator-class = "native" * / public Integer getId () {return id; SpringFrameWork Developer's Guide Version 0.6October 8, 2004 So many Open source projects? why not open your documents?} public void setid (integer ID) {this.id = id;} / *** @ hibernate.property column = "password" length = "50" * / public string getpassword ) {return password;} public void setPassword (String password) {this.password = password;} / *** @ hibernate.property column = "username" length = "50" * / public String getUsername () {return username; } Public void setusername (String UserName) {this.username = Username;}} The above code, specify the class / table with the xDoclet; the mapping relationship of the attribute / field, we can generate the corresponding user.hbm based on the code through xdoclet audask .xml file. For details, please refer to the article "Hibernate Development Guide".

Here is the generated user.hbm.xml: < / generator> < PropertyName = "Username" type = "java.lang.string" update = "true" insert = "true" access = "prot" column = "username" length = "50" /> UserDAO.java:public class UserDAO extends HibernateDaoSupport implements IUserDAO {public void insertUser (User user) {getHibernateTemplate () saveOrUpdate (user);.}} to see this code would have been a little surprised, it seems a little too easy ......, But this is enough. In short one line of code we have implemented the same features as the examples in the previous chapter, which also reflects the power of Spring Hibernate. The above USERDAO implements a custom iUserdao interface (here the iUserdao interface only contains the definition of the INSERTUser method, but there is another layer of meaning, see the code test portion below, and extend the abstract class: HibernatedAosupporthibernateSupport implements the association of the HibernateTemplate and SessionFactory instances. Similar to JDBCTemplate, HibernateTemplate encapsulates Hibernate Session operations, while hibernateTemplate.execute method is the core of a package mechanism, and interested readers can study their implementation mechanism. With HibernateTemplate we can get out of each data operation, you must first get the session instance, start the transaction, submit / rollback transaction, and the cumbersome operations of Urgent Try / Catch / Finally. Thus, the logical presentation effect of the descent in the above code is obtained.

Below this comparison achieve the same function Hibernate native code, presumably more experience: Session sessiontry {Configuration config = new Configuration () configure (); SessionFactory sessionFactory = config.buildSessionFactory (); session = sessionFactory.openSession ();. Transaction tx = session.begintransAction (); user user = new user (); user.setname ("erica"); user.setpassword ("mypass"); session.save (user); tx.commit ();} catch (HibernateException e) {e.printStackTrace (); tx.rollback ();} finally {session.close ();} test code: InputStream is = new FileInputStream ( "Hibernate-Context.xml"); XmlBeanFactory factory = new XmlBeanFactory (is); IUserDAO userDAO = (IUserDAO) factory.getBean ( "userDAOProxy"); SpringFrameWork Developer's Guide Version 0.6October 8, 2004 So many open source projects Why not Open your Documents User user = new User ();.? user. SetUserName ("Erica"); User.SetPassword ("mypass"); UserDao.Insertuser (user); this code does not seem to be special, but there is a subtle point: iuserdao userdao = (iuserdao) Factory.getBean (" Userdaoproxy "); This is not directly transformed with UserDao. This is different from the test code above JDBCTemplate. Not completely from design considerations, here are some special, we can try to force the bean instance to enhance the bean instance with the USERDAO class, but will get a ClassCastException, and the program exception is aborted. Why do you have such problems? Is it only such a problem with using hibernate? This is not the case, if it is transformed on the UserDao based on JDBCTEMPATE, the same problem will also appear. The iUserdao interface itself is very simple (only a definition of an insertuser method), apparently not the reason for exceptions. The reason is that Spring's AOP implementation mechanism, the previous mention, the transaction management in Spring is actually implemented based on dynamic AOP mechanism, in order to implement dynamic AOP, Spring uses Java DynamicProxy by default, but Dynamic Proxy requires its agent Objects must implement an interface that defines how to prepare for proxy. For Java Class, which does not implement any interfaces, Spring is required to implement this function via CGLIB10.

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

New Post(0)