spring integration hibernate

The integration of hibernate by spring includes three parts: the configuration of hibernate, the core objects of hibernate are handed over to spring for management, and the transaction is controlled by AOP. Benefits:

  • Configured by java code, getting rid of hard coding, connecting to the database and other information is more flexible
  • The life cycle such as session is better controlled, and session and transaction dependencies are injected into DAO, which is more refreshing
  • Transactions are managed more clearly by AOP, and transactions are managed automatically

hibernate configuration

Spring provides an implementation of sessionfactory, LocalSessionFactoryBean
The configuration effect is achieved by setting the value in the LocalSessionFactoryBean
Note that there are several types of LocalSessionFactoryBean:
  • org.springframework.orm.hibernate5.LocalSessionFactoryBean
  • org.springframework.orm.hibernate4.LocalSessionFactoryBean
  • org.springframework.orm.hibernate3.LocalSessionFactoryBean
The difference between them is that in different versions of the hibernate package, choose according to your own version of hibernate
@Configuration
@PropertySource("classpath:/application.properties")
public class HibernateConf {
 //Enviroment object can get the file data marked by @PropertySource
 // Get rid of hard coding by getting the properties in the properties file
 @Autowired
 public Environment env;

 
 //DataSource object is used to configure the information to connect to the database
 //Configuring the LocalSessionFactoryBean later will use the datasource to connect to the database
 @Bean
 public DataSource dataSource() throws ClassNotFoundException{
  DataSource ds=new DataSource();
  //Get the configuration information from the Properties file through the Environment object
  ds.setUsername(env.getProperty("dataSource.username","root"));
  ds.setPassword(env.getProperty("dataSource.password","null"));
  ds.setAddress(env.getProperty("dataSource.address"));
  ds.setDriver(env.getProperty("dataSource.driver"));
  return ds;
 }
 
 //LocalSessionFactoryBean同SessionBean
 //Used to configure hibernate
 @Bean
 @Autowired
 public LocalSessionFactoryBean sessionFactory(DataSource dataSource){
  LocalSessionFactoryBean sessionFactory=new LocalSessionFactoryBean();
  sessionFactory.setDataSource(dataSource);
  //Set the package that scans the orm object lock cub
  sessionFactory.setPackagesToScan("weibo.po");
  Properties prop=new Properties();
  prop.setProperty("hibernate.dialect",env.getProperty("hibernate.dialect"));//设置hibernate方言
  prop.setProperty("hibernate.show_sql", env.getProperty("hibernate.show_sql"));//设置显示sql
  prop.setProperty("hibernate.format_sql",env.getProperty("hibernate.format_sql"));//格式化sql
  prop.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));//自动建表
  sessionFactory.setHibernateProperties(prop);
  return sessionFactory;
 }
The essence is, get rid of hard coding, connect the database information (username, password, driver, address....) through the Environment object provided by spring to read the external data file (application.properties) to get the connection information , so that the sub-database configuration It can be configured directly in application.properties. It should be noted that LocalSessionFactoryBean and SessionFactory are not polymorphic, but LocalSessionFactoryBean holds a SessionFactory object. Spring will automatically instantiate the SessionFactory object in LocalSessionFactoryBean during runtime, so When we get the LocalSessionFactoryBean object from the spring container, we actually get the SessionFactory in the LocalSessionFactoryBean

Session, etc. are handed over to the spring container

Hand over SessionFactory, Session, and Transcation objects to Spring container management
  • Better management of life cycle to avoid resource waste
  • Using dependency injection, no longer manually open the connection
  • Use AOP to manage transactions, no longer manage transactions manually
SessionFactory has been identified as a Bean when hibernate was just configured, so there is no need to configure it again.
//session
 @Bean
 //request scope + implement proxy through class
 @Scope(scopeName=WebApplicationContext.SCOPE_REQUEST,proxyMode=ScopedProxyMode.TARGET_CLASS)
 //Autowire the already assembled SessionFactory
 @Autowired
 public Session session(SessionFactory sessionFactory){
   return sessionFactory.openSession();
 }
 
 //transaction
 @Bean
 @Scope(scopeName=WebApplicationContext.SCOPE_REQUEST,proxyMode=ScopedProxyMode.TARGET_CLASS)
 //Autowire the already assembled Session
 @Autowired
 public Transaction transction(Session session){
   return session.beginTransaction();
 }
Here are a few things to note
  • Set the scope, the scope is generally request or session, to avoid long-term connection to the database
  • Set up the proxy, because you want to inject Session and Transcation into DAO, DAO is generally a singleton, and Session and transaction are short-scoped. So you need to use the proxy object to first inject it into the DAO, and then call the real object when it is used.
  • Start the Session through the already assembled SessionFactory
  • Open the transaction through the already assembled Session (in order to achieve the one-to-one correspondence between session and transcation objects)

Transactions are controlled through AOP

When AOP is not used, we would write code like this
public void crud() throws SQLException{
  try{
    // code to operate the database
    transaction.submit();//Submit
  }catch(SQLException e){
    transaction.rollback();//Rollback
    throw e;
  }finally{
    session.close();//Close the connection
  }
 }
Generally, crud needs to have these steps: commit the transaction, roll back the transaction when an error occurs, and close the connection 
Why not use aop to complete this repetitive and unrelated business logic code?
 
When managing transactions through AOP only
  • Set curd as pointcut
  • Write a wraparound advice at the pointcut, and implement several steps of the transaction in the wraparound advice
//declare the aspect
@Aspect
public class DAOAspect {
 //Autowire session and transcation
 @Autowired
 private Session session;
 @Autowired
 private Transaction transaction;
 //declare pointcut
 @Pointcut("execution(* *.dao.*.crud(*))")//In this way, all crud methods under the dao package will be marked as pointcuts
 public void crud(){}
 
 // wrap notification around crud
 @Around("crud()")
 public void aroundCrud(ProceedingJoinPoint p) throws Throwable{
   try{
     p.proceed();//Execute crud action
     transaction.commit();//Commit the transaction
   }catch(Throwable e){
     transaction.rollback();//Error rollback
     throw e;
   }finally{
     session.close();//Close the connection
   }
 }
}
Is it much more convenient to look at it this way? From now on, transaction management only needs to be written once, and there are several points that need to be paid attention to.
  • p.proceed() must be written. If you don't write it, the method of the pointcut (crud) will not be called, just like the pointcut (crud) is intercepted and filtered.
  • Throw e must be written, because aop is actually a proxy object, otherwise an error will not be thrown if the database operation is wrong (the error is captured by the proxy object and handled by the catch)
  • Do not submit the transaction and close the connection in the original crud method, otherwise an error will be reported at the aop level (the connection has been closed and the transaction has been committed)
  • Because the minimum scope of session and transcation is at the request level, there is no need to worry about whether the automatically assembled object is the original one.
View the original text: http://zswlib.com/2016/07/14/spring%e6%95%b4%e5%90%88hibernate/

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326752350&siteId=291194637