SSJ集成学习

一、什么是三大框架

1.ssh

  • Struts2 Spring Hibernate

2.ssm

  • SpringMVC Spring MyBatis

3.ssj

  • Struts2 Spring JPA
  • SpringMVC Spring JPA(今天学习)
  • SpringMVC Spring Data JPA

二、SSJ集成的步骤分析:

  • 1.创建项目&导包
  • 2.搭建spring的运行环境
  • 3.集成springMVC
  • 4.三层架构(表现层、业务层、数据层)
  • 5.数据层集成JPA
  • 6.业务层添加AOP实现事务管理
  • 7.Tomact运行项目,浏览器测试访问

三、集成

一、创建maven的web项目

二、导入jar包

  • 导入jar包
    • Spring的4个核心包
    • SpringMVC的两个包
    • Spring-aop
    • Spring-test
    • Hibernate核心包和JPA支持包
    • mySQL驱动包
    • 连接池DBCP
    • Spring与JPA集成的ORM和JDBC包
    • Spring的事务管理包spring-tx
    • SpringMVC转JSON的jackson
<dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <!-- 导入Spring的核心包 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.7.RELEASE</version>
        </dependency>
        <!-- Spring的单元测试 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.3.7.RELEASE</version>
        </dependency>

        <!-- 导入mySQL的驱动包 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.13</version>
        </dependency>

        <!-- 导入数据库连接池的包 -->
        <dependency>
            <groupId>commons-pool</groupId>
            <artifactId>commons-pool</artifactId>
            <version>1.5.6</version>
        </dependency>
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.2.1</version>
        </dependency>

        <!-- 导入SpringMVC的核心包 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.3.7.RELEASE</version>
        </dependency>

        <!-- orm映射 jdbc-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>4.3.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>4.3.7.RELEASE</version>
        </dependency>

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

        <!-- jackson核心包【SpringMVC返回json数据】 -->
        <dependency>
            <groupId>jackson</groupId>
            <artifactId>jackson-all</artifactId>
            <version>1.7.6</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.8.0</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.8.7</version>
        </dependency>


    </dependencies>

三、搭建spring的运行环境:spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       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/tx http://www.springframework.org/schema/tx/spring-tx.xsd">


    <!-- 扫描包
        @Controller @Service @Repository @Component
    -->
    <context:component-scan base-package="cn.itsource"/>

    <!-- 开启Spring的注解支持 -->
    <context:annotation-config/>


    <!--
        1)配置数据库连接池
            dbcp.properties
        2)配置JPA的EntityManagerFactory,使用FactoryBean的方式配置
        3)支持全注解的事务管理 在Service层的实现类或者方法上面添加@Transactional注解即可
    -->
    <!--引入dbcp.properties文件-->
    <context:property-placeholder location="classpath:dbcp.properties"/>
    <!--配置dbcp连接池-->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <!--通常情况下以下四个key都要加前缀-->
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>


    <!--配置JPA的EntityManagerFactory【FactoryBean方式配置】-->
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <!--引用一个数据库连接池-->
        <property name="dataSource" ref="dataSource"/>
        <!--指定我们的domain实体类【加了@Entity注解的实体类】在哪个包-->
        <property name="packagesToScan" value="cn.itsource.domain"/>
        <!--指定一个适配器-->
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <!--配置方言-->
                <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect"/>
                <!--建表策略-->
                <property name="generateDdl" value="false"/>
                <!--是否显示SQL-->
                <property name="showSql" value="true"/>
            </bean>
        </property>
    </bean>
    
    
    <!-- Service层添加事务管理【全注解添加事务管理】 -->
    <bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>
    <!--
        开启注解直接AOP
        tx:annotation-driven 表示开启注解支持Spring的事务管理【AOP】,会查找默认的bean名称:transactionManager
            transaction-manager属性可以指定事务管理器的bean名称,如果不指定默认找transactionManager
    -->
    <tx:annotation-driven transaction-manager="txManager"  />

</beans>

dbcp.properties

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///jpql
jdbc.username=root
jdbc.password=root

四、DAO层和Service层

  • 1.接口和实现类来一套
  • 2.实现类上添加@Service和@Repository注解
  • 3.建立依赖关系【写一个字段添加@Autowired注解】
 @Autowired
    private IEmployeeDao employeeDao;
  • 4.Dao层实现类中不能使用@Autowired,而是要用@PersistenceContext注解
 /**
     * @PersistenceContext
     *  在持久化上下文范围内查找一个EntityManager对象进行注入,
     *  如果找不到bean,就调用entityManagerFactory的createEntityManager方法帮我们创建一个
     *  如果你在Service层添加了事务管理,此对象不是在这儿创建的,而是在Service层就已经创建好了
     * @Autowired
     *  在spring容器中查找目标对象,找不到就直接抛异常
     */
    @PersistenceContext
    private EntityManager entityManager;

5.Service层:开启事务管理


/**
 * @Transactional 表示开启事务管理的注解
 *  写在类上,表示全局配置,适用于当前类中所有方法
 *  写在方法上,表示局部配置,只对当前方法有效
 *      readOnly  表示是否只读 默认false【可以读写】
 *          false 表示可以读写,增删改查都可以
 *          true  表示只读,只能查询
 *      propagation 事务传播机制【事务管理的范围大小】
 *          Propagation.SUPPORTS    默认值  你怎么写的它就怎么传播
 *          Propagation.NEVER       从不传播【一般不用】
 *          Propagation.REQUIRED    包含
 *          Propagation.REQUIRES_NEW 包含并且新开一个事务
 *
 */
@Service
@Transactional(readOnly = false,propagation = Propagation.SUPPORTS)
public class EmployeeServiceImpl implements IEmployeeService {

    @Autowired
    private IEmployeeDao employeeDao;
    ......

五、集成SpringMVC

  • 1.准备一个SpringMVC.xml
    - 扫描包 @Controller
    - 开启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">

    <!-- 扫描@Controller -->
    <context:component-scan base-package="cn.itsource.controller"/>

    <!--
        开启SpringMVC的注解支持【默认就开启】
        @RequestMapping
        @ResponseBody
        @RequestParam
        @PathVariable
    -->
    <mvc:annotation-driven/>

    <!-- 配置一个视图解析器 -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/view/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!-- 文件上传解析器[暂时先不配置] -->



</beans>
  • 2.修改web.xml
    - DispatcherServlet核心控制器
    - 初始化参数指定配置文件路径和名称
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         id="WebApp_ID" version="3.1">

  <display-name>Archetype Created Web Application</display-name>

  <!--
    集成Spring+SpringMVC
  -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring.xml</param-value>
  </context-param>



  <!-- 解决no session问题 -->
  <filter>
    <filter-name>noSessionFilter</filter-name>
    <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>noSessionFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>



  <!--
    配置SpringMVC的核心控制器
     SpringMVC的配置文件默认必须放在WEB-INF之下,与web.xml同级,而且名称必须叫 SpringMVC-servlet.xml
     如果文件路径或者名称不对,就必须使用初始化参数来指定路径和名称
  -->
  <servlet>
    <servlet-name>SpringMVC</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>
  </servlet>
  <servlet-mapping>
    <servlet-name>SpringMVC</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>



</web-app>

六、配置Tomcat,启动&测试访问

  • 复制easyui

七、三大必然出现的问题

  • 1.no session
    • 原因:因为懒加载,提取关联对象的属性值的时候发现EntityManager已经被关闭,就报no session
    • 解决办法:将关闭EntityManager的动作延后
    • 具体做法
      • 在web.xml中添加一个过滤器OpenEntityManagerInViewFilter

  <!-- 解决no session问题 -->
  <filter>
    <filter-name>noSessionFilter</filter-name>
    <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>noSessionFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  • 2.转JSON的死循环
    • 原因:SpringMVC自动转JSON的时候自动调用对象的属性的get方法,双向关联会形成死循环
    • 解决办法:转JSON的时候让关联对象忽略属性
    • 具体做法:@JsonIgnore
package cn.itsource.domain;


import com.fasterxml.jackson.annotation.JsonIgnore;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name="department")
public class Department {


    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;
    private String provice;
    private String city;
    private String street;

    //多个部门被同一个部门经理管理【单向多对一】
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="manager_id")
    @JsonIgnore//@JsonIgnore 转化为JSON字符串的时候请忽略此属性
    private Employee manager;

    private String sn;

    //当前部门下的员工集合
    @JsonIgnore
    @OneToMany(fetch = FetchType.LAZY,mappedBy = "department")
    private List<Employee> employees = new ArrayList<>();
    ......
  • 3.No Serializer
    • 原因:懒加载原理中生成的子类除了重写属性的get方法之外,还额外添加了三个字段,但是没有提供属性的get方法
    • 解决办法:转JSON时忽略这三个属性
    • @JsonIgnoreProperties(value={“hibernateLazyInitializer”,“handler”, “fieldHandler”})
package cn.itsource.domain;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import javax.persistence.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Entity
@Table(name="employee")
public class Employee {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;

    //多个员工属于同一个部门【单向多对一】
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="department_id")
    //@JsonIgnoreProperties 表示转化为JSON的时候忽略指定的属性
    @JsonIgnoreProperties(value={"hibernateLazyInitializer","handler", "fieldHandler"})
    private Department department;

    private BigDecimal salary;
    private Date hireDate;
  get,set......
  • 补充:
  • 前台表格显示的时间问题:
/**
     * @JsonFormat 表示转化为JSON字符串的时候处理一下日期格式
     *  转化为JSON的时候会自动调用属性的get方法
     * @return
     */
    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")
    public Date getHireDate() {
        return hireDate;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值