笔记49 在Spittr应用中整合Hibernate
在前边构建的Spittr应用中整合Hibernate
由于最近所学的hibernate都是使用xml方式进行配置的,所以在与以Java方式配置的Spittr应用结合时就会出现一些小问题,在此进行总结。
一、读取上下文
因为原来的Spittr应用采用的是Java方式配置,没有用到xml。
DispatcherServlet是Spring MVC的核心。按照传统的方式,像DispatcherServlet这样的Servlet会配置在 web.xml文件中。但是在Spittr应用中,使用Java将DispatcherServlet配置在Servlet容器中,而没有使用web.xml文件。代码如下所示:
SpittrWebAppInitializer.java
package myspittr.config; import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletRegistration.Dynamic; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; public class SpittrWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
// TODO Auto-generated method stub
return new Class<?>[] { RootConfig.class };
} @Override
protected Class<?>[] getServletConfigClasses() {
// TODO Auto-generated method stub
return new Class<?>[] { WebConfig.class };
} @Override
protected String[] getServletMappings() {
// TODO Auto-generated method stub
return new String[] { "/" };
} @Override
protected void customizeRegistration(Dynamic registration) {
// TODO Auto-generated method stub
registration.setMultipartConfig(new MultipartConfigElement("/tmp/spittr/uploads", 2097152, 4194304, 0));
} }
WebConfig.java
package myspittr.config; import java.io.IOException; import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver; @Configuration("WebConfig")
@EnableWebMvc
@ComponentScan({ "myspittr.web", "myspittr.data" })
public class WebConfig extends WebMvcConfigurerAdapter {
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setViewClass(org.springframework.web.servlet.view.JstlView.class);
resolver.setExposeContextBeansAsAttributes(true);
return resolver;
} @Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
// TODO Auto-generated method stub
configurer.enable();
} @Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("message");
return messageSource;
} @Bean
public MultipartResolver multipartResolver() throws IOException {
return new StandardServletMultipartResolver();
} // @Bean
// public MultipartResolver multipartResolver() throws IOException {
// return new CommonsMultipartResolver();
// }
}
RootConfig.java
package myspittr.config; import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.web.servlet.config.annotation.EnableWebMvc; @Configuration("RootConfig")
@ComponentScan(basePackages = { "myspittr" }, excludeFilters = {
@Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class) })
public class RootConfig { }
AbstractAnnotationConfigDispatcherServletInitializer的任意类都会自动地配置Dispatcher-Servlet和Spring应用上下文,Spring的应用上下文会位于应用程序的Servlet上下文之中。
插入语:
在Servlet 3.0环境 中,容器会在类路径中查找实现 javax.servlet.ServletContainerInitializer接口的类, 如果能发现的话,就会用它来配置Servlet容器。 Spring提供了这个接口的实现,名 为SpringServletContainerInitializer,这个类反过来又会查找实现WebApplicationInitializer的类并将配置的任务交给 它们来完成。Spring 3.2引入了一个便利的 WebApplicationInitializer基础实现,也就是AbstractAnnotationConfigDispatcherServletInitializer 因为我们的Spittr-WebAppInitializer扩展了 AbstractAnnotationConfig DispatcherServletInitializer(同时也就实现了 WebApplicationInitializer),因此当部署到Servlet 3.0容器中的时候,容器会自动发现它,并用它来配置Servlet上下文。
尽管它的名字很长,但 是AbstractAnnotationConfigDispatcherServletInitializer使用起来很简便。在上述代码中,SpittrWebAppInitializer重写了三个方法。 第一个方法是getServletMappings(),它会将一个或多个路径映 射到DispatcherServlet上。在本例中,它映射的是“/”,这表示 它会是应用的默认Servlet。它会处理进入应用的所有请求。 为了理解其他的两个方法,我们首先要理解DispatcherServlet 和一个Servlet监听器(也就是ContextLoaderListener)的关系。
两个应用(Spring和SpringMVC)上下文之间的关系:
当DispatcherServlet启动的时候,它会创建Spring应用上下文,并加载配置文件或配置类中所声明的bean。在上述代码中的 getServletConfigClasses()方法中,我们要求DispatcherServlet加载应用上下文时,使用定义在WebConfig配置类(使用Java配置)中的bean。 但是在Spring Web应用中,通常还会有另外一个应用上下文。另外的这个应用上下文是由ContextLoaderListener创建的。 我们希望DispatcherServlet加载包含Web组件的bean,如控制器、视图解析器以及处理器映射,而ContextLoaderListener要加载应用中的其他bean。这些bean通常是驱动应用后端的中间层和数据层组件。
实际上,AbstractAnnotationConfigDispatcherServletInitializer 会同时创建DispatcherServlet和 ContextLoaderListener。GetServlet-ConfigClasses() 方法返回的带有@Configuration注解的类将会用来定 义DispatcherServlet应用上下文中的 bean。getRootConfigClasses()方法返回的带 有@Configuration注解的类将会用来配 置ContextLoaderListener创建的应用上下文中的bean。 在本例中,根配置定义在RootConfig中,DispatcherServlet 的配置声明在WebConfig中。需要注意的是,通过 AbstractAnnotationConfigDispatcherServletInitializer来配置DispatcherServlet是传统web.xml方式的替代方案。如果你愿意的话,可以同时包含web.xml和 AbstractAnnotationConfigDispatcherServletInitializer,但这其实并没有必要。
但是,问题是现在还不会使用Java方式对hibernate进行配置,所以没有办法只能采用xml方式配置。如果使用Java方式整合hibernate,那么将hibernate相关的bean放入WebConfig.java中即可。
需要注意的是,以xml方式整合hibernate时,需要在web.xml中进行如下配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" id="WebApp_1529217958650">
<!-- 配置Spring IOC 容器 -->
<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> <!-- 配置Springmvc的核心控制器 -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<!-- 配置编码方式过滤器,且必须配置在所有的过滤器最前面 -->
<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>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 为了使用SpringMVC框架实现REST,需配置HiddenHttpMethodFilter -->
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> </web-app>
但是其中DispatcherServlet和 ContextLoaderListener已经在SpittrWebAppInitializer.java中配置过了,所以要去掉。那么如何加载hibernate相关的bean呢?新建applicationContext.xml文件,在这里面存放有关hibernate的配置,具体代码如下所示:
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd"> <!-- 配置数据源 -->
<context:property-placeholder location="classpath:/config/db.properties" /> <!-- 配置DataSource -->
<bean class="com.mchange.v2.c3p0.ComboPooledDataSource" id="dataSource">
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
</bean> <!-- 配置SeeionFactory -->
<bean class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"
id="sessionFactory">
<!-- 配置数据源 -->
<property name="dataSource" ref="dataSource"></property>
<!-- 配置实体包(pojo) -->
<property name="PhysicalNamingStrategy">
<bean
class="org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl"></bean>
</property>
<property name="packagesToScan" value="com.Spittr.entity"></property> <!-- 配置Hibernate的常用属性 -->
<property name="hibernateProperties">
<props>
<!-- 数据库的方言 -->
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean> <!-- 配置hibernate的事务管理器 -->
<bean class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
</beans>
如何加载这里面的bean呢?使用ClassPathXmlApplicationContext获取配置文件,然后使用getBean方法获取相应bean,即SessionFactory。
代码如下:
ApplicationContext ctx= new ClassPathXmlApplicationContext("/config/applicationContext.xml");
SessionFactory sessionFactory=ctx.getBean(SessionFactory.class);
classpath请参考:笔记48
二、Spittr应用中数据的处理
1.应用中只涉及到两个实体类,一个是spiitle,另一个是spitter。它俩之间的关系是:一个spitter可以对应多个spittle,多个spittle对应一个spitter。
所以在spittle中增加下面代码:
private Spitters spitters;
@ManyToOne
@JoinColumn(name = "author")
public Spitters getSpitters() {
return spitters;
} public void setSpitters(Spitters spitters) {
this.spitters = spitters;
}
在spitter中增加下面代码:
Set<Spittles> spittles;
@OneToMany(fetch = FetchType.EAGER)
@JoinColumn(name = "author")
public Set<Spittles> getSpittles() {
return spittles;
} public void setSpittles(Set<Spittles> spittles) {
this.spittles = spittles;
}
2.Spittr中注册界面和发布页面分别对应实体类spitter和spittle,但是如果这两个实体类直接使用hibernate映射为数据库中的表时,会出现一些问题,因为有一些字段是不用存储在数据库当中的,比如说确认密码。所以需要新建两个实体类,用作与数据库的交互,而原来的spitter和spittle用来与应用交互。下面给出两个新的实体类:
Spitters.java
package com.Spittr.entity; import java.io.Serializable;
import java.util.Set; import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table; @Entity
@Table(name = "spitters")
public class Spitters implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L; int id;
String username;
String password;
String email;
Set<Spittles> spittles; public Spitters() {
// TODO Auto-generated constructor stub
} public Spitters(String username, String password, String email) {
super();
this.username = username;
this.password = password;
this.email = email;
} @Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public int getId() {
return id;
} public void setId(int 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 getEmail() {
return email;
} public void setEmail(String email) {
this.email = email;
} @OneToMany(fetch = FetchType.EAGER)
@JoinColumn(name = "author")
public Set<Spittles> getSpittles() {
return spittles;
} public void setSpittles(Set<Spittles> spittles) {
this.spittles = spittles;
} }
Spittles.java
package com.Spittr.entity; import java.io.Serializable; import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table; @Entity
@Table(name = "spittles")
public class Spittles implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private int id;
private Long spittleId;
private String message;
private String title;
private String time;
private String username;
private String spittlePicture; private Spitters spitters; public Spittles() {
// TODO Auto-generated constructor stub
} public Spittles(Long spittleId, String message, String title, String time, String username, String spittlePicture) {
this.spittleId = spittleId;
this.message = message;
this.title = title;
this.time = time;
this.username = username;
this.spittlePicture = spittlePicture;
} @Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public Long getSpittleId() {
return spittleId;
} public void setSpittleId(Long spittleId) {
this.spittleId = spittleId;
} public String getMessage() {
return message;
} public void setMessage(String message) {
this.message = message;
} public String getTitle() {
return title;
} public void setTitle(String title) {
this.title = title;
} public String getTime() {
return time;
} public void setTime(String time) {
this.time = time;
} public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public String getSpittlePicture() {
return spittlePicture;
} public void setSpittlePicture(String spittlePicture) {
this.spittlePicture = spittlePicture;
} @ManyToOne
@JoinColumn(name = "author")
public Spitters getSpitters() {
return spitters;
} public void setSpitters(Spitters spitters) {
this.spitters = spitters;
} }
三、总结
笔记49 在Spittr应用中整合Hibernate的更多相关文章
- 【Hibernate学习笔记-3】在Spring下整合Hibernate时, 关于sessionFactory的类型的说明
摘要 在Spring下整合Hibernate时,关于sessionFactory的配置方式主要有两种,分别为注解配置方式,和xml配置方式,下面将对这两种配置方式进行介绍. 1. sessionFac ...
- Spring4.* 中整合 Hibernate
1. Spring 整合 Hibernate 整合什么 ? 1). 有 IOC 容器来管理 Hibernate 的 SessionFactory2). 让 Hibernate 使用上 Spring 的 ...
- SSH整合,applicationContext.xml中配置hibernate映射文件问题
今天在applicationContext.xml中配置sessionFactory时遇到了各种头疼的问题,现在总结一下: 1.<property name="mappingDirec ...
- Spring整合Hibernate笔记
1. Spring 指定datasource a) 参考文档,找dbcp.BasicDataSource i. c3p0 ii. dbcp <bean id="dataSource&q ...
- Spring学习笔记六:Spring整合Hibernate
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6785323.html 前言:整合概述 Spring整合Hibernate主要是把Hibernate中常用的S ...
- Spring笔记⑤--整合hibernate代码测试
String整合hibernate代码测试 在上节生成的表中插入数据: 注意:使用myeclipse2014生成的整合项目可能存在问题需要我们自己导入. 第一步 我们写dao接口 packag ...
- Spring笔记④--spring整合hibernate链接数据库
整合hibernate 整合什么? 有ioc容器来管理hibernate的SessionFactory 让hibernate使用上spring的声明式事务 先加入hibernate 驱动包 新建hib ...
- javaEE中的hibernate配置笔记
0 从web.xml出发 项目中用Spring整合Hibernate,Spring贯穿整个项目,所以先看看Spring在哪一步整合了Hibernate.先看部分web.xml. 在context-pa ...
- 吴裕雄--天生自然JAVA SPRING框架开发学习笔记:SSH框架(Struts2+Spring+Hibernate)搭建整合详细步骤
在实际项目的开发中,为了充分利用各个框架的优点,通常都会把 Spring 与其他框架整合在一起使用. 整合就是将不同的框架放在一个项目中,共同使用它们的技术,发挥它们的优点,并形成互补.一般而言,在进 ...
随机推荐
- strcoll - 用当前的区域选项来比较两个字符串
总览 (SYNOPSIS) #include <string.h> int strcoll(const char *s1, const char *s2); 描述 (DESCRIPTION ...
- 使用Gradle发布项目到JCenter仓库 (转载)
原文:使用Gradle发布项目到JCenter仓库 这篇文章介绍通过Gradle把开源项目发布到公共仓库JCenter中,方便你我他的事情,我们都是很懒的嘛.JCenter现在是Android Stu ...
- codeforces round 433 C. Planning 贪心
题目大意: 输入n,k,代表n列航班,初始始发实践为1,2,3分钟以此类推,然后输入n个整数分别代表延迟1分钟第i个航班损失多少钱,然后调整后的始发时间表是这样的,任何一辆航班的始发时间不能在他的初始 ...
- 命令行窗口编译执行java
1:首先配置java环境变量 新建系统环境变量 名称:JAVA_HOME 内容:D:\Program Files\Java\jdk1.7.0_13 为你jdk所在的文件夹位置 修改path路径 ...
- javaWEB 之文件的上传
1.1 文件上传三要素 提供form表单,method必须是post form表单的enctype必须是multipart/form-data 提供 input type=“file” 类型输入 1. ...
- 微信小程序截取字符串
我这里用的 str.substring(star,end)第一个参数代表开始位置,第二个参数代表结束位置的下一个位置;若参数值为负数,则将该值转为0;两个参数中,取较小值作为开始位置,截取出来的字符串 ...
- linq中如何合并多个predicate条件
最近在做一个webAPI 的时候遇到一个需要合并多个predicate条件的问题,下面就是对题的情况.为了方便交流我对case进行了简化,请先看如下代码: using System.Collectio ...
- cgroup & oom-killer 简介
cgroup内存限制 memory.failcnt memory.limit_in_bytes memory.usage_in_bytes memory.max_usage_in_bytes memo ...
- Lambda表达式底层分析
一.我们先看下C#代码下Lamdba表达式的写法 // <summary> /// 写入日志委托 /// </summary> /// <param name=" ...
- 设置非阻塞的套接字Socket
当使用socket()函数和WSASocket()函数创建套接字时,默认都是阻塞的.在创建套接字之后,通过调用ioctlsocket()函数,将该套接字设置为非阻塞模式.函数的第一个参数是套接字,第二 ...