Spring+SpringMVC+Hibernate小案例(實現Spring對Hibernate的事務管理)


 

原文地址:https://blog.csdn.net/jiegegeaa1/article/details/81975286

一、工作環境

編輯器用的是MyEclipse,用Mysql數據庫,maven管理jar包。

二、搭建環境

(1)完整工程圖:

(2)pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>ssh</groupId>
  <artifactId>ssh</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <name>ssh</name>
  <description/>
  <properties>
      <!-- Version -->
    <webVersion>3.0</webVersion>
    <springVersion>4.3.7.RELEASE</springVersion>
    <hibernateVersion>4.3.5.Final</hibernateVersion>
    <jsonVersion>1.9.13</jsonVersion>
    <jacksonVersion>2.5.0</jacksonVersion>
    <mysqlVersion>5.1.38</mysqlVersion>
    <c3p0Version>0.9.1.2</c3p0Version>
    <log4jVersion>1.2.17</log4jVersion>
    <fileuploadVersion>1.3.1</fileuploadVersion>
    <lombokVersion>1.16.10</lombokVersion> 
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.glassfish</groupId>
      <artifactId>bean-validator</artifactId>
      <version>3.0-JBoss-4.0.2</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.glassfish</groupId>
      <artifactId>javax.enterprise.deploy</artifactId>
      <version>3.0.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.glassfish</groupId>
      <artifactId>javax.jms</artifactId>
      <version>3.0.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.glassfish</groupId>
      <artifactId>javax.management.j2ee</artifactId>
      <version>3.0.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.eclipse.persistence</groupId>
      <artifactId>javax.persistence</artifactId>
      <version>2.0.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.glassfish</groupId>
      <artifactId>javax.resource</artifactId>
      <version>3.0.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.glassfish</groupId>
      <artifactId>javax.security.auth.message</artifactId>
      <version>3.0.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.glassfish</groupId>
      <artifactId>javax.security.jacc</artifactId>
      <version>3.0.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.glassfish</groupId>
      <artifactId>javax.servlet</artifactId>
      <version>3.0.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.glassfish</groupId>
      <artifactId>javax.servlet.jsp</artifactId>
      <version>3.0.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.glassfish</groupId>
      <artifactId>javax.servlet.jsp.jstl</artifactId>
      <version>3.0.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax.xml.bind</groupId>
      <artifactId>jaxb-api-osgi</artifactId>
      <version>2.2.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax.ws.rs</groupId>
      <artifactId>jsr311-api</artifactId>
      <version>1.1.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.glassfish.web</groupId>
      <artifactId>jstl-impl</artifactId>
      <version>1.2</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax.mail</groupId>
      <artifactId>mail</artifactId>
      <version>1.4.3</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax.xml</groupId>
      <artifactId>webservices-api-osgi</artifactId>
      <version>2.0.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.jboss.weld</groupId>
      <artifactId>weld-osgi-bundle</artifactId>
      <version>1.0.1-SP3</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.glassfish.web</groupId>
      <artifactId>javax.servlet.jsp.jstl</artifactId>
      <version>1.2.1</version>
    </dependency>
    <!-- spring -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>${springVersion}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${springVersion}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${springVersion}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-orm</artifactId>
      <version>${springVersion}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>${springVersion}</version>
    </dependency>
    <!-- spring web + spring mvc -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${springVersion}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${springVersion}</version>
    </dependency>
    <!-- hibernate -->
     <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-core</artifactId>
      <version>${hibernateVersion}</version>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-ehcache</artifactId>
      <version>${hibernateVersion}</version>
    </dependency>
    <!-- Database -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>${mysqlVersion}</version>
    </dependency>
    <dependency>
      <groupId>c3p0</groupId>
      <artifactId>c3p0</artifactId>
      <version>${c3p0Version}</version>
    </dependency>
    <!-- json數據 使springMVC可以返回json值 -->
    <dependency>
      <groupId>org.codehaus.jackson</groupId>
      <artifactId>jackson-mapper-asl</artifactId>
      <version>${jsonVersion}</version>
    </dependency>
    <!-- Jackson可以輕松的將Java對象轉換成json對象和xml文檔,同樣也可以將json、xml轉換成Java對象 -->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>${jacksonVersion}</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>${jacksonVersion}</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>${jacksonVersion}</version>
    </dependency>
    <!-- log4j -->
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>${log4jVersion}</version>
    </dependency>
    <!-- 文件上傳 -->
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>${fileuploadVersion}</version>
    </dependency>
    <!-- lombok插件導包 @Data的使用:自動生成實體的getter/setter/toString -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>${lombokVersion}</version>
        <scope>provided</scope>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.3.2</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.6</version>
        <configuration>
          <failOnMissingWebXml>false</failOnMissingWebXml>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

(3)先配置Springmvc:spring-mvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xmlns:task="http://www.springframework.org/schema/task"
    xmlns:cache="http://www.springframework.org/schema/cache"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
    http://www.springframework.org/schema/data/jpa
    http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
    http://www.springframework.org/schema/task
    http://www.springframework.org/schema/task/spring-task-4.1.xsd
    http://www.springframework.org/schema/cache
    http://www.springframework.org/schema/cache/spring-cache.xsd">
        
        <!-- mvc注解 -->
        <mvc:annotation-driven/>
        
        <!-- 掃描 -->
        <context:component-scan base-package="cn.austin" use-default-filters="false">
            <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
        </context:component-scan>
        
        <!-- 視圖解析 -->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/"></property>
            <property name="suffix" value=".jsp"></property>
        </bean>
        
        <!-- 解析靜態資源 -->
        <mvc:default-servlet-handler/>
        
</beans>

然后在web.xml中加載springmvc配置:

<!-- spring mvc start -->
    <servlet>
          <servlet-name>spring-mvc</servlet-name>
          <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
          <init-param>
              <param-name>contextConfigLocation</param-name>
              <param-value>classpath:spring-mvc.xml</param-value>
          </init-param>
          <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
          <servlet-name>spring-mvc</servlet-name>
          <url-pattern>/</url-pattern>
    </servlet-mapping>
    <!-- spring mvc end -->

然后寫Controller:UserController.java

package cn.austin.controller;
 
import java.util.List;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;
 
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 
import cn.austin.entity.User;
import cn.austin.service.UserService;
 
@Controller
public class UserController {
    
    @RequestMapping("/index")
    public String index() {
        return "index";
    }
}

這里返回了index,再結合spring-mvc.xml中的視圖解析器,加上前綴后綴之后就變成了/WEB-INF/index.jsp

到這里,Springmvc配置完畢,來驗證一下:

 

 

 

Springmvc配置成功!

(4)將Spring和Springmvc整合起來:

下面是Spring的配置文件applicationContext.xml:

 

<?xml version="1.0" encoding="UTF-8"?>
 
<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context-4.3.xsd
         http://www.springframework.org/schema/tx
          http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
         http://www.springframework.org/schema/aop 
         http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
         http://www.springframework.org/schema/mvc 
         http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">
 
    <!-- 掃描注解,注冊bean -->
    <context:component-scan base-package="cn.austin">
        <!-- 跳過@Controller -->
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
</beans>

細心的可以發現Spring和Springmvc的配置文件都會有<context:component-scan base-package="">這么一項。兩個配置文件都掃描注解,會不會發生沖突呢?答案是會的。但我這里的配置可以很好地避免沖突。因為Spring的配置文件會跳過@Controller注解;而Springmvc的配置文件只會掃描@Controller。值得注意的是:Springmvc配置中的use-default-filters="false"是必須要有的!如果不寫上,它的默認值是true,而這個default-filters會默認掃描@Service、@Repository等注解,這樣就會和Spring的配置發生沖突!

在web.xml中加載Spring配置和相關過濾器:

<!-- 亂碼的處理 -->
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>  
  
    <!-- spring start -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!-- spring end -->

到這里,Spring和Springmvc整合完畢,現在新建Service層來測試:

UserService.java:

import java.util.List;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import cn.austin.dao.impl.UserRepositoryImpl;
import cn.austin.entity.User;
 
 
@Service
public class UserService {
    public void show() {
        System.out.println("show service");
    }
    
}

UserController.java:

import java.util.List;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;
 
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 
import cn.austin.entity.User;
 
@Controller
public class UserController {
    
    @Autowired
    private UserService userService;
    
    @RequestMapping("/index")
    public String index() {
        this.userService.show();
        return "index";
    }
}

再次訪問http://127.0.0.1:8080/ssh/index,不僅可以成功訪問主頁,還可以在控制台上看到輸出:show service。這說明了Spring和Springmvc整合成功!

(5)下面是最后,也是最困難的一步,將Hibernate也整合進去(困難是因為還會涉及到事務,將Hibernate事務交給Spring來管理):

先配置好數據庫設置:config.properties

#database connection config
jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://127.0.0.1:3306/struts?useUnicode=true&characterEncoding=utf-8
jdbc.username = root
jdbc.password = 123
 
#hibernate config
hibernate.dialect = org.hibernate.dialect.MySQLDialect
hibernate.show_sql = true
hibernate.format_sql = true
hibernate.hbm2ddl.auto =update

使用時改成自己的數據庫就可以。

來看Hibernate的相關配置。因為Hibernate的工廠以及事務都是交給Spring來管理的,因此將它們配置在一塊,都配置在applicationContext.xml中,下面是完整的配置:

<?xml version="1.0" encoding="UTF-8"?>
 
<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context-4.3.xsd
         http://www.springframework.org/schema/tx
          http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
         http://www.springframework.org/schema/aop 
         http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
         http://www.springframework.org/schema/mvc 
         http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">
 
    <!-- 掃描注解,注冊bean -->
    <context:component-scan base-package="cn.austin">
        <!-- 跳過@Controller -->
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
    
    <!-- hibernate -->
    <!-- 掃描properties配置文件 -->
    <context:property-placeholder location="classpath:config.properties"/>
    
    <!-- 配置c3p0數據源 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <property name="driverClass" value="${jdbc.driver}"></property>
        <property name="jdbcUrl" value="${jdbc.url}"></property>
        <property name="user" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="maxPoolSize" value="40"></property>     <!-- 最大連接數 -->
        <property name="minPoolSize" value="1"></property>      <!-- 最小連接數 -->
        <property name="initialPoolSize" value="10"></property> <!-- 初始化連接池內的數據庫連接 -->
        <property name="maxIdleTime" value="20"></property>     <!-- 最大空閑時間 -->
    </bean>
    
    <!-- session工廠 -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="packagesToScan" value="cn.austin.entity"></property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
            </props>
        </property>
    </bean>
    
    <!-- 事務管理器 -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>
    
    <!-- 開啟事務注解 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>
    
</beans>

下面來看數據庫訪問層(Dao)的寫法:

這里先定義了一個最通用的接口DomainRepository,可供任意的實體Dao使用:

DomainRepository.java:

package cn.austin.dao;
 
import java.io.Serializable;
import java.util.List;
 
/*
 * 通用數據訪問接口
 */
public interface DomainRepository<T,PK extends Serializable> {
    
    T load(PK id);
    
    T get(PK id);
    
    List<T> findAll();
    
    void persist(T entity);
    
    void add(T entity);
    
    void update(T entity);
    
    void delete(PK id);
    
    void flush();
}

UserRepository.java繼承於這個接口,它是專門操作User數據庫的:

package cn.austin.dao;
 
import org.springframework.stereotype.Repository;
 
import cn.austin.entity.User;
 
public interface UserRepository extends DomainRepository<User, Integer> {
 
}

該接口的具體實現類如下:UserRepositoryImpl.java

package cn.austin.dao.impl;
 
import java.util.List;
 
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
 
import cn.austin.dao.UserRepository;
import cn.austin.entity.User;
 
@Repository
public class UserRepositoryImpl implements UserRepository {
    
    @Autowired
    private SessionFactory sessionFactory;
    
    private Session getSession() {
        return this.sessionFactory.getCurrentSession();
    }
    
    @Override
    public User load(Integer id) {
        return (User) this.getSession().load(User.class, id);
    }
 
    @Override
    public User get(Integer id) { // get by Id
        return (User) this.getSession().get(User.class, id);
    }
 
    @Override
    public List<User> findAll() {
        return this.getSession().createQuery("from User").list();
    }
 
    @Override
    public void persist(User entity) {
        this.getSession().persist(entity);
    }
 
    @Override
    public void add(User entity) {
        this.getSession().save(entity);
    }
 
    @Override
    public void update(User entity) {
        this.getSession().update(entity);
    }
 
    @Override
    public void delete(Integer id)  {
        User user = this.get(id);
        try{
            this.getSession().delete(user);
        }catch(Exception e){
            e.printStackTrace();
        }
    }
 
    @Override
    public void flush() {
        this.getSession().flush();
    }
 
}

注意:這里十分重要的一點是,獲取Session一定是要通過getCurrentSession()方法來獲得!如果你用的是openSession()來獲得,那么會造成的問題是事務的連接和操作數據庫的連接(session)是不相干的,從而導致事務無法提交等等,導致update和save操作無法完成!

下面來看看Entity:

User.java:

 

package cn.austin.entity;
 
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
 
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 
 
@Entity
@Table(name="ssh_user")
public class User {
    @Id
    @Column(name="id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Integer id;
    
    @Column(name="username")
    private String username;
    
    @Column(name="password")
    private String password;
    
    @Column(name="description")
    private String description;
 
    public Integer getId() {
        return id;
    }
 
    public void setId(Integer id) {
        this.id = id;
    }
 
    public String getUsername() {
        return username;
    }
 
    public void setUsername(String username) {
        this.username = username;
    }
 
    public String getPassword() {
        return password;
    }
 
    public void setPassword(String password) {
        this.password = password;
    }
    
    public String getDesc() {
        return description;
    }
 
    public void setDesc(String description) {
        this.description = description;
    }
 
    @Override
    public String toString() {
        return "User [id=" + id + ", username=" + username + ", password=" + password + ", description=" + description + "]";
    }
    
}

記得一定要建好數據表!

我也在實體這里被坑了一把。。。剛開始我的description寫的是desc,結果執行增加操作的時候莫名地報錯了:

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'desc, password, username) values ('c', 'b', 'a')' at line 1

后來排錯的時候才發現,原來desc是Mysql的關鍵字,不能這么用,改成description就成功了。

下面來看完整的UserService.java:

package cn.austin.service;
 
import java.util.List;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import cn.austin.dao.impl.UserRepositoryImpl;
import cn.austin.entity.User;
 
@Transactional
@Service
public class UserService {
    @Autowired
    private UserRepositoryImpl userRepositoryImpl;
    
    public User getById(Integer id) {
        return this.userRepositoryImpl.get(id);
    }
    
    public List<User> findAll() {
        return this.userRepositoryImpl.findAll();
    }
    
    public void add(User user) {
        this.userRepositoryImpl.add(user);
    }
    
    public void update(User user) {
        this.userRepositoryImpl.update(user);
    }
    public void delete(Integer id) {
        this.userRepositoryImpl.delete(id);
    }
    
}

UserService.java類上面一定要加一個@Transactional注解,否則會報錯。

那么問題來了,什么是事務管理呢?

事務管理是為了避免程序在執行過程中出現了異常,從而導致數據庫的數據與實際的不一樣。因此,如果某段程序中出現了異常,整個事務就會回滾,而不會提交,這樣一來安全上得到了保證。

下面會對事務進行簡單地驗證。

(6)配置好數據訪問層后,現在先來測試基本的增刪查改功能:

我的數據庫是這樣的:

UserController.java:

package cn.austin.controller;
 
import java.util.List;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;
 
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 
import cn.austin.entity.User;
import cn.austin.service.UserService;
 
@SessionAttributes(value="username")
@Controller
public class UserController {
    
    @Autowired
    private UserService userService;
    
    @RequestMapping("/index")
    public String index() {
        /*
         * 新增
         */
        User user = new User();
        user.setUsername("abc");
        user.setPassword("abc");
        user.setDesc("abc");
        this.userService.add(user);
        
        /*
         * 刪除
         */
        this.userService.delete(8);
        
        /*
         *修改 
         */
        User user1 = new User();
        user1.setId(9);
        user1.setUsername("999");
        user1.setPassword("999");
        user1.setDesc("999");
        this.userService.update(user1);
        
        /*
         * 查詢
         */
        List<User> users = this.userService.findAll();
        for(User us : users)
            System.out.println(us);
        
        return "index";
    }
}

再來訪問http://127.0.0.1:8080/ssh/index:

數據庫變成了這樣:

看看MyEclipse的控制台:

 

這是查詢出來的結果。都是我想要的結果,說明了Sping + Springmvc +Hibernate整合成功,事務配置成功!

(7)最后來簡單地測試一下事務:

這里用修改功能來測試:

UserController.java:

 

package cn.austin.controller;
 
import java.util.List;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;
 
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 
import cn.austin.entity.User;
import cn.austin.service.UserService;
 
@SessionAttributes(value="username")
@Controller
public class UserController {
    
    @Autowired
    private UserService userService;
    
    @RequestMapping("/index")
    public String index() {
        /*
         *修改 
         */
        User user1 = new User();
        user1.setId(9);
        user1.setUsername("9988");
        user1.setPassword("9988");
        user1.setDesc("9988");
        this.userService.update(user1);
        
        return "index";
    }
}

UserRepositoryImpl.java中的update方法:

 

@Override
    public void update(User entity) {
            this.getSession().update(entity);
            int a = 1/0;
    }

這里寫了一個異常,再次運行http://127.0.0.1:8080/ssh/index:

馬上就報錯了:java.lang.ArithmeticException: / by zero

而且這時候,數據庫是沒有數據更新的。這就簡單地驗證了事務的回滾功能:只有程序全部能正常執行,事務才會提交;否則,只要有一個錯誤的地方,事務就會回滾。

最后,祝大家整合成功,沒有任何BUG!!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM