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配置
- 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>
classpath*:app*.xml
:这样写不止可以加载你当前项目下的配置文件,也可以加载你导入的其他jar包下的配置文件。- 配置的前端控制器实际上就是一个servlet,配置的servlet的名字必须和SpringMVC配置文件的名字相同如:springmvc对应springmvc-servlet.xml
<url-pattern>/</url-pattern>
:配置为一个"/
"而不配置为"/*
",因为,因为配置为这两个,静态资源的访问也会通过这个servlet,而可以在spring中配置静态资源的访问通过默认的servlet去处理,如果配置为"/*
",配置将不会生效- 支持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>
<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容器中的功能。<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}";
}
}
- @Controller:将表现层 (Controller 层 ) 的类标识为 Spring Bean,在配置文件中要开启注解扫描
- @GetMapping(查询)/@PostMapping(添加)/@PutMapping(修改)/@DeleteMapping(删除):基于REST架构对资源的不同处理请求
- @ResponseBody:该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。
- @ReuqestBody: a.该注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上;
b.再把HttpMessageConverter返回的对象数据绑定到 controller中方法的参数上。- @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>
- data: {'_method':'put','name':'紫霞','salary':5000 }:使用ajax请求的时候,put/delete请求,使用'_method':'put',type:'post'--此时type类型只能使用post(为什么呢,请看HiddenHttpMethodFilter的源码)
- 如果是表单提交put/delete请求呢?
在表单中添加隐藏域:<input type="hidden" name="_method" value="put/delete" />