Spring SpringMVC JPA整合配置

1. 三大框架

ssh

struts spring hibernate
Struts2 Spring Hibernate

ssm(目前最流行的框架)

SpringMVC Spring MyBatis

ssj(Spring springMvc jpa)

Struts2 Spring JPA(过时)
SpringMVC Spring JPA(今天集成的框架)
SpringMVC Spring spring Data JPA(spring的全家桶)

​ 第一个项目:

  • sssj–>springmvc+spring+springjdbc

    第二个项目: ssdj(结构 中小型的项目)

  • springmvc +spring +springdatajpa

    第三个项目: ssm (现在比较流行结构)

    扫描二维码关注公众号,回复: 9791530 查看本文章
  • springmvc+spring+mybatis

    第四个项目:

  • springboot+springcloud + ssm

SSJ(框架整合)

整合流程:

导包(所有需要的jar包) -> domain(配置实体类)->
db.properties(配置连接数据库需要的资源文件) ->
datasource(配置连接数据库) ->
entityManagerFactory(配置实体管理对象工厂) ->
tx(配置事务) ->dao(配置持久层) -> service(配置业务层,Spring的配置) -> controller(springmvc的配置,web.xml) -> easyui(页面展示数据)

spring项目管理专家,所有的bean都可以交给spring管理

(1)先整合 spring和jpa

导入依赖包:

需要的包
spring-web Spring对于web的支持
spring-webmvc 引入SpringMVC的支持
spring-jdbc Spring连接数据库的包
spring-orm Spring集成ORM[对象,关系,映射]框架需要引入这个包
hibernate-core hibernate的核心包
hibernate-entitymanager hiberante对象jpa的支持包
mysql-connector-java 数据库驱动包
commons-dbcp 引入dbcp连接池的包
spring-test spring的测试包
Aspectjweaver 引入aop的织入包(切面)
jackson-databind SpringMVC返回JSON需要的包

配置pom.xml文件导包:

<?xml version="1.0" encoding="UTF-8"?>
<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>cn.itsource</groupId>
    <artifactId>ssj</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!-- spring和springmvc整合包  Spring 对于web的支持 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>4.2.5.RELEASE</version>
        </dependency>


        <!-- 引入SpringMvc的支持 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.2.5.RELEASE</version>
        </dependency>
        <!-- springjdbc的包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>4.2.5.RELEASE</version>
        </dependency>


        <!--
         Spring和ORM(JPA)整合的包
         集成ORM[对象,关系,映射]框架需要引入这个包
         -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>4.2.5.RELEASE</version>
        </dependency>

         <!-- hibernate核心包 -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>4.3.8.Final</version>
        </dependency>

        <!--hiberante对象jpa的支持包-->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.3.8.Final</version>
        </dependency>
        <!-- mysql数据库驱动包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
        <!-- 连接池引入包-->
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.2.2</version>
        </dependency>


        <!-- Spring测试的支持-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.2.5.RELEASE</version>
        </dependency>
        <!-- Springaop  引入Aop的织入包-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.9</version>
        </dependency>
        <!-- 处理json的包  返回json的格式包-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.6.5</version>
        </dependency>
        <!-- junit测试包-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

​jdbc.properties:连接数据库所需要的资源配置文件

 //建议前面都加上jdbc底层就是根据这个前缀去找的(不加上需要多一个配置) 
 // 而且这个 username 和window底层的名字一样会发生冲突
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///ssj
jdbc.username=root
jdbc.password=123456

配置文件applicationContext.xml Spring核心配置文件

dataSource(连接池)–》EntityManagerFactory–》EntityManager -->事务

<?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:tx="http://www.springframework.org/schema/tx"
       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/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 扫描包的注解-->
    <context:component-scan base-package="cn.itsource"></context:component-scan>
    <!-- 指定位置去加载 jdbc.properties文件    classpath*  加上这一句才能找到(血的教训)   -->
<context:property-placeholder location="classpath*:jdbc.properties"></context:property-placeholder>
    <!-- 配置连接池dataSource bean生命周期方法 销毁方法close 用来连接之后 还给链接池-->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
          <!--导入数据库核心包-->
          <!--导入数据库驱动-->
        <property name="driverClassName" value="${jdbc.driverClassName}"></property>
           <!--配置数据库地址-->
        <property name="url" value="${jdbc.url}"></property>
          <!--配置数据库用户名-->
        <property name="username" value="${jdbc.username}"></property>
        <!--配置数据库密码-->
        <property name="password" value="${jdbc.password}"></property>
    </bean>

    <!-- 得到EntityManagerFactory 方言 链接池-->
    <!-- 得到EntityManagerFactory-->

    <bean id="entityManagerFactory"
          class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <!-- 配置属性 setDataSource   数据是从数据库来的,与数据库建立连接-->
        <property name="dataSource" ref="dataSource"></property>
        <!-- 扫描实体类的配置 entity-->
        <property name="packagesToScan" value="cn.itsource.domain"></property>
       <!--
        配置一个JPA的适配器:hibernate  Adapter:适配器
        jpaVendorAdapter:JPA是用哪一个框架来实现的
        配置JPA
     -->
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <!-- 是否显示sql-->
                <property name="showSql" value="true"></property>
                <!-- 是否创建表-->
                <property name="generateDdl" value="true"></property>
                <!--数据库方言-->
                <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect"></property>
            </bean>
        </property>


    </bean>
  <!-- 准备JPA的事务管理器,事务管理器需要工厂对象的支持 -->
<!--id名称固定 transactionManager-->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"></property>
    </bean>

    <!-- 开启事务 扫描@Transaction这种注解  spring支持的注解-->
    <tx:annotation-driven/>
</beans>

整合 spring和springmvc
​ 配置 web.xml和applicationContext-mvc.xml里面配置


applicationContext.xml SprtingMVC 核心配置文件


<?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">

    <!-- 扫描controller  扫包才能使用注解-->
    <context:component-scan base-package="cn.itsource.web.controller"></context:component-scan>
    <!-- 静态资源放行-->
    <mvc:default-servlet-handler/>
    <!-- 扫描RequestMapping-->
    <mvc:annotation-driven/>
    <!-- 视图解析器-->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>
</beans>

配置WEB.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">








    <!-- 找到spring 的核心配置文件-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>

    <!--&lt;!&ndash; 监听器读取配置&ndash;&gt;-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>



    <!-- 配置过滤器 解决懒加载延迟关闭问题-->
    <filter>
        <filter-name>openEntityManagerInViewFilter</filter-name>
        <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>openEntityManagerInViewFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>




    <!-- 字符编码过滤器-->
    <filter>
        <filter-name>characterEncoding</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>characterEncoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>


    <!-- 核心控制器配置-->
    <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:applicationContext-mvc.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>


</web-app>

propagation:事务传播机制

属性:
REQUIRED(默认配置):如果调用我的方法是有事务的,那么我们就使用同一 个事务
REQUIRES_NEW: 不管谁调用我,我都会开一个自己的新事务
NEVER: 绝对不开事务,看到事务就报错给你看
SUPPORTS: 支持(调用我的方法有事务,就有,如果没有事务,就算了)

关于事务的配置Servce层

// 表示交给srping管理
@Service
/*在真实的使用场景里面还是查询居多 所以设计事务比较少
 所以总体设置为 SUPPORTS 支持(调用我的方法有事务,就有,如果没有事务,就算了)
 readOnly = true 在将事务设置成只读后,相当于将数据库设置成只读数据库,
 此时若要进行写的操作,会出现错误
 注意是一次执行多次查询来统计某些信息,这时为了保证数据整体的一致性,要用只读事务  
*/
@Transactional(propagation = Propagation.SUPPORTS,readOnly = true)
public class ProductDirServiceImpl  implements IProductDirService {
      // 注入值
     @Autowired
     private  IProductDirDao dirDao;
// 增删改需要开启事务  REQUIRED(默认配置):如果调用我的方法是有事务的,那么我们就使用同一 个事务
@Transactional(propagation = Propagation.REQUIRED)
    public void save(ProductDir Dir) {
        dirDao.save(Dir);

    }
    @Transactional(propagation = Propagation.REQUIRED)
    public void update(ProductDir Dir) {
             dirDao.updete( Dir);
    }
    @Transactional(propagation = Propagation.REQUIRED)
    public void deleteById(Long id) {
dirDao.delit(id);

    }

    public ProductDir queryOne(Long id) {
        return dirDao.queryOne(id);
    }

    public List<ProductDir> queryAll() {
        return dirDao.queryAll();
    }
}

dao层得到 private EntityManager 的注解不能使用@Autowired

通过持久化上下文得到entityManager
@PersistenceContext
​ private EntityManager entityManager;

domain注意点

 // 多对以  设置懒加载
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="dir_id")
    //忽略延迟加载额外生成的handler这个属性
   @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})

为什么出现懒加载延迟加载报错的情况:

报错译文 无法序列化
HTTP状态500 -无法写入内容:无法初始化代理-没有会话(通过引用链:java.util.ArrayList [0] - > cn.itsource.domain.Product [1 - > cn.itsource.domain“dir”。$ jvst3de嵌套异常是com.fasterxml.jackson.databind。JsonMappingException:无法初始化代理没有会话(通过引用链:java.util.ArrayList[01->cn.itsource.domain. product ’ dir ’ 1->cn.itsource.domain。产品目录$$ ivst3de
报错原因:
当我们使用迫切加载的时候 底层是把所有的关联数据都查询出来所以当我们使用josn格 式返回数据到界面的时候拿到的是所有的数据 所以不会出现问题、
可我们设置为懒加载的时候 底层只会查询你当前请求查询的数据当你拿到数据通过json格式返回数据到界面的时候 他发现你还有一个属性没有值(比如你学生对应的老师类 当你查询学生的时候 所对应的老师在懒加载的时候没有查询出来 但是你返回josn格式的时候也要处理这个属性) 需要再次加载实体对象 但是此时连接池已经关闭了 当你第一次查询结束后且提交事务 此时的实体对象状态处于一个游离状态 连接池已经关闭

过滤器底层 拦截所有的请求当全部结束后 才关闭资源 (此时就不会提前关闭的情况了)

  if (!participate) {
            EntityManagerHolder emHolder = (EntityManagerHolder)TransactionSynchronizationManager.unbindResource(emf);
            if (!this.isAsyncStarted(request)) {
                this.logger.debug("Closing JPA EntityManager in OpenEntityManagerInViewFilter");
                EntityManagerFactoryUtils.closeEntityManager(emHolder.getEntityManager());
            }

报错译文
无法写入内容:没有为类找到序列化器org.hibernate.proxy.pojo.javassist。没有发现用于创建BeanSerializer的属性(为了避免异常,禁用SerializationFeature。(通过参考链:java.util.ArrayList [O] - > cn.itsource.domain.Product [1 - > cn.itsource.domain“dir”。ProductDir_ j v s t 7 b a c o m . f a s t e r x m l . j a c k s o n . d a t a b i n d J s o n M a p p i n g E x c e p t i o n : o r g . h i b e r n a t e . p r o x y . p o j o . j a v a s s i s t B e a n S e r i a l i z e r ( S e r i a l i z a t i o n F e a t u r e ( : j a v a . u t i l . A r r a y L i s t r o 1 > 1 > c n . i t s o u r c e . d o m a i n c n . i t s o u r c e . d o m a i n . P r o d u c t r _jvst7ba嵌套异常是com.fasterxml.jackson.databind。JsonMappingException:没有为org.hibernate.proxy.pojo.javassist类找到序列化器。没有发现用于创建BeanSerializer的属性(为了避免异常,禁用SerializationFeature。(通过参考链:java.util.ArrayListro1 - > 1 - > cn.itsource.domain cn.itsource.domain.Productr迪尔”。产品目录 ivst7ba
为什么加上拦截器的配置后之后还会报错
当我们懒加载的底层是使用代理模式的 底层会给你新建一个子类但是该子类中会新增出来一个属性 “handler” 所以会报错

发布了23 篇原创文章 · 获赞 2 · 访问量 936

猜你喜欢

转载自blog.csdn.net/metjoyful/article/details/101426806