• 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!!

  • 相关阅读:
    OpenCV:Python3使用OpenCV
    CNN结构:MXNet设计和实现简介
    环的寻找:寻找无向图中所有存在的环-删除点法
    JAVA 构建使用 Native 库
    Android:JAVA使用HDF5存储
    Java:数值-字符串转换(String转Double)
    Qt无法用UTF-8编辑问题
    Boost-QT兼容问题:#define FUSION_HASH #
    JAVA;使用java.awt.Image的不稳定性
    图方法:寻找无向图联通子集的JAVA版本
  • 原文地址:https://www.cnblogs.com/dyh004/p/10672006.html
Copyright © 2020-2023  润新知