SpringMVC+Spring+Hibernate整合(三层都

2017-08-01  本文已影响0人  原来蜗牛不是牛

创建Maven项目,导入依赖

<dependencies>
   <!-- Servlet / JSP / JSTL -->
        <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.1</version>
            <scope>provided</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <!-- Hibernate / MySQL Driver / Connection Pool -->
        <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.2.10.Final</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.40</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.2</version>
        </dependency>
        <!-- Spring Web MVC / ORM / Test -->
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.3.9.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-orm -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>4.3.9.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.3.9.RELEASE</version>
            <scope>test</scope>
        </dependency>
        <!-- JUnit -->
        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!-- Jackson -->
        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.8.9</version>
        </dependency>
        <!-- File Upload -->
        <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.10</version>
        </dependency>
  </dependencies>

SpringMVC配置

  1. web.xml中的配置
<web-app>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:app*.xml</param-value>
    </context-param>
    <!-- 支持RESTful架构的过滤器 -->
    <filter>
        <filter-name>rest</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>rest</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
   <!-- 配置spring自带的过滤器 -->
  <filter>
    <filter-name>characterEncodingFilter</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>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
   <!-- 启动Spring IoC容器的监听器 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
  <!-- 1.配置前端控制器 -->
  <servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
 </web-app>
  1. classpath*:app*.xml:这样写不止可以加载你当前项目下的配置文件,也可以加载你导入的其他jar包下的配置文件。
  2. 配置的前端控制器实际上就是一个servlet,配置的servlet的名字必须和SpringMVC配置文件的名字相同如:springmvc对应springmvc-servlet.xml
  3. <url-pattern>/</url-pattern>:配置为一个"/"而不配置为"/* ",因为,因为配置为这两个,静态资源的访问也会通过这个servlet,而可以在spring中配置静态资源的访问通过默认的servlet去处理,如果配置为"/*",配置将不会生效
  4. 支持RESTful架构的过滤器:浏览器支持的请求方式为get/post,spring支持get/post/put/delete请求,如果要使用put/delete请求就需要配置这个过滤器,后面代码中有使用例子

配置SpringMVC

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">
        
    <!-- 指定扫描控制器的包 -->
    <context:component-scan base-package="com.chenx.controller" />
    <context:annotation-config />
    
    <!-- 配置静态资源仍然交给应用服务器默认的Servlet进行处理 -->
    <mvc:default-servlet-handler />
    
    <!-- 使用注解驱动Spring MVC配置 -->
    <mvc:annotation-driven />
    
    <!-- 配置JSP页面的视图解析器 -->
    <!-- 只能支持解析可由Servlet API的RequestDispatcher转发的视图资源图,如:内部jsp或者servlet。  --> 
    <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 决定视图类型,如果添加了jstl支持(即有jstl.jar),那么默认就是解析为jstl视图 -->
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <!-- 视图前缀 -->
        <property name="prefix" value="/WEB-INF/jsp/"/>
         <!-- 视图后缀 -->
        <property name="suffix" value=".jsp"/>
    </bean>

</beans>
  1. <context:component-scan base-package="com.chenx.controller" /><context:annotation-config />:<context:annotation-config />仅能够在已经在已经注册过的bean上面起作用。对于没有在spring容器中注册的bean,它并不能执行任何操作。但是不用担心,<context:component-scan>除了具有<context:annotation-config />的功能之外,还具有自动将带有@component,@service,@Repository等注解的对象注册到spring容器中的功能。
  2. <mvc:default-servlet-handler />:配置静态资源的处理,最好的方式是使用资源映射的方式--<mvc:resources mapping="/resources/**" location="/resources/" />

Spring配置

app.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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/context   
        http://www.springframework.org/schema/context/spring-context.xsd   
        http://www.springframework.org/schema/mvc   
        http://www.springframework.org/schema/mvc/spring-mvc.xsd"
        default-autowire="byType">
        
    <!-- 指定扫描哪个包及其子包将注解的类纳入Spring IoC容器的管理 -->
    <!-- @Component / @Controller / @Service / @Repository -->
    <context:component-scan base-package="com.chenx" />
    <context:annotation-config />

    <!-- 配置数据库连接池,阿里巴巴连接池druid -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
        init-method="init" destroy-method="close">
        <!-- 基本属性 url、user、password -->
        <property name="url" value="jdbc:mysql://localhost:3306/hr?useUnicode=true&characterEncoding=utf8" />
        <property name="username" value="root" />
        <property name="password" value="123456" />

        <!-- 配置初始化大小、最小、最大 -->
        <property name="initialSize" value="10" />
        <property name="minIdle" value="10" />
        <property name="maxActive" value="50" />

        <!-- 配置获取连接等待超时的时间 -->
        <property name="maxWait" value="15000" />

        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
        <property name="timeBetweenEvictionRunsMillis" value="60000" />

        <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
        <property name="minEvictableIdleTimeMillis" value="300000" />

        <property name="validationQuery" value="SELECT 'x'" />
        <property name="testWhileIdle" value="true" />
        <property name="testOnBorrow" value="false" />
        <property name="testOnReturn" value="false" />

        <!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
        <property name="poolPreparedStatements" value="true" />
        <property name="maxPoolPreparedStatementPerConnectionSize"
            value="20" />

        <!-- 配置监控统计拦截的filters -->
        <property name="filters" value="stat" />
    </bean>

    <!-- Hibernate的SessionFactory -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="packagesToScan" value="com.chenx.model" />
        <property name="hibernateProperties">
            <value>
                hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
                hibernate.show_sql=true
                hibernate.format_sql=true
            </value>
        </property>
    </bean>

    <!-- 事务管理器和声明式事务 -->
    <bean id="txManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager" />
    
    <tx:annotation-driven transaction-manager="txManager" />
    
</beans>

1.<tx:annotation-driven />:通过注解的方式配置声明式事务,在需要事务环境的业务层类上使用@Transactional声明事务,不在配置文件中再配置切面和增强处理

Dao层的实现类

@Repository
public class DepartmentDaoImpl 
    extends BaseDaoHibernateAdapter<Department, Integer>
    implements DeparmentDao {

}

@Repository:将数据访问层 (DAO 层 ) 的类标识为 Spring Bean,在配置文件中要开启注解扫描

Service层实现类

@Transactional
@Service
public class DepartmentServiceImpl implements DepartmentService {
    @Autowired
    private DeparmentDao deparmentDao;
    @Autowired
    private EmployeeDao employeeDao;
        
    //业务略
}

1.@Transactional: 声明事务环境
2.@Service:将业务层 (Service 层 ) 的类标识为 Spring Bean,在配置文件中要开启注解扫描
3.@Autowired:自动装配,spring调用setter方法注入

表现层

@Controller
public class EmpController {
    @Autowired
    private EmployeeService empService;
    
    @GetMapping(value = "/employee/{no}", produces = "application/json;charset=utf-8")
    @ResponseBody
    public Employee getEmployee(@PathVariable Integer no) {
        return empService.getEmployeeByNo(no);
    }
    
    @PostMapping(value = "/employee", produces = "application/json;charset=utf-8")
    @ResponseBody
    public Employee addEmployee(Employee employee) {
        return empService.addNewEmployee(employee)? employee : null;
    }
    
    @PutMapping(value = "/employee/{no}", produces = "application/json;charset=utf-8")
    @ResponseBody
    public Employee updateEmployee(Employee employee) {
        return empService.editEmployee(employee)? employee : null;
    }
    
    @DeleteMapping(value = "/employee/{no}")
    @ResponseBody
    public String delEmployee(@PathVariable Integer no) {
        Employee employee = new Employee();
        employee.setNo(no);
        return empService.removeEmployee(employee) ?
                "{'flag': true}" : "{'flag': false}";
    }
}
  1. @Controller:将表现层 (Controller 层 ) 的类标识为 Spring Bean,在配置文件中要开启注解扫描
  2. @GetMapping(查询)/@PostMapping(添加)/@PutMapping(修改)/@DeleteMapping(删除):基于REST架构对资源的不同处理请求
  3. @ResponseBody:该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。
  4. @ReuqestBody: a.该注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上;
    b.再把HttpMessageConverter返回的对象数据绑定到 controller中方法的参数上。
  5. @PathVariable:通过 @PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中:URL 中的 {xxx} 占位符可以通过@PathVariable("xxx") 绑定到操作方法的入参中

页面请求url

<html>
    <head>
        <meta charset="utf-8">
    </head>
    <body>
        <button id="getButton">查询</button>
        <button id="delButton">删除</button>
        <button id="addButton">新增</button>
        <button id="updateButton">修改</button>
    
        <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
        <script>
            $(function() {
                $('#getButton').on('click', function() {
                    $.getJSON('employee/7800', function(data) {
                        window.alert(data.name);
                        window.alert(data.department.name);
                    });
                });
                $('#delButton').on('click', function() {
                    $.ajax({
                        url: 'employee/7800',
                        type: 'delete',
                        success: function(data) {
                            window.alert(data);
                        }
                    });
                });
                $('#addButton').on('click', function() {
                    $.ajax({
                        url: 'employee',
                        type: 'post',
                        data: { 'no': 7800,'name':'某该','job':'程序员','manager.no':2056,'salary':3000,'department.no':30 },
                        success: function(data) {
                            window.alert(data);
                        }
                    });
                });
                $('#updateButton').on('click', function() {
                    $.ajax({
                        url: 'employee/5566',
                        type: 'post',
                        data: {'_method':'put','name':'紫霞','salary':5000 },
                        success: function(data) {
                            window.alert(data);
                        }
                    });
                });
            });
        </script>   
    </body>
</html>
  1. data: {'_method':'put','name':'紫霞','salary':5000 }:使用ajax请求的时候,put/delete请求,使用'_method':'put',type:'post'--此时type类型只能使用post(为什么呢,请看HiddenHttpMethodFilter的源码)
  2. 如果是表单提交put/delete请求呢?
    在表单中添加隐藏域:<input type="hidden" name="_method" value="put/delete" />
上一篇下一篇

猜你喜欢

热点阅读