SSJ集成整合、声明式事务管理

一、三大框架介绍

1、sssj --》springmvc spring springjdbc(第一个项目)

2、早期:ssh (struts2 spring hibernate) 用的比较多 ,现在struts2被springmvc替代

3、中小型项目 :s s sdj(第二个项目)

​ springmvc spring springdatajpa(就是对jpa进行封装) – spring全家桶

4、现在(比较流行):ssm架构(第三个或者第四项目)

​ springmvc+spring+mybatis

二、搭建Spring+jpa环境

步骤:

​ 一般都是Spring和其他框架进行整合 Spring和JPA

所有配置:

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

    <!-- 扫描spring service注解 repostory注解    开启全注解-->
    <context:component-scan base-package="com.cc.ssj"></context:component-scan>

    <!--大的步奏:jdbc.properties dataSource EntityManagerFactory Transaction-->
    <!-- 1、加载配置jdbc.properties-->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!-- 2、配置连接池dataSource 加载jdbc.properties中的信息到程序中来 -->
    <!-- destroy-method="close"  当前bean销毁的时候,会先调用close方法,关闭连接 -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql:///db0731ssj"></property>
        <property name="username" value="root"></property>
        <property name="password" value="cc123456"></property>
    </bean>

    <!--3、配置EntityManagerFactory-->
    <!-- 得到EntityManagerFactory:LocalContainerEntityManagerFactoryBean-->
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <!-- 1.注入DataSource -->
        <property name="dataSource" ref="dataSource"></property>
        <!-- 2.从哪个包去扫描@Entity,domain包 -->
        <property name="packagesToScan" value="com.cc.ssj.domain"></property>

        <!-- 3.配置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>

    <!-- 事务管理器-->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <!--注入:EntityManagerFactory  好让我们的事务去管理他-->
        <property name="entityManagerFactory" ref="entityManagerFactory"></property>
    </bean>
    <!-- 开启事务 扫描@Transaction这种注解-->
    <tx:annotation-driven/>
</beans>

1、applicationContext.xml 中Bean对象注入的顺序

引用jdbc.properties–>dataSource–>EntityManagerFactory–>-->Transaction

2、配置步奏:

0、配置扫描包:扫描Spring的注解(@Service、@Repostory、等等)

1、配置:jdbc.properties

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

2、配置连接池dataSource

​ 2.1、加载jdbc.properties中的信息到程序中来

​ 2.2、destroy-method=“close” 当前bean销毁的时候,会先调用close方法,关闭连接

3、配置EntityManagerFactory

​ 3.1、得到:EntityManagerFactory

​ LocalContainerEntityManagerFactoryBean

​ 3.2、注入 dataSource

​ 3.3、扫描实体类的配置 @Entity—— 扫描domain包

​ 3.4、配置JPA的实现

4、搭建三层结构

1、IProductDao(新增 修改 删除)

2、ProductDaoImpl(新增 修改 删除)

DaoImpl层:使用——>@PersistenceContext 注入EnttiyManager

//开启dao层注解
@Repository
public class ProductDaoImpl implements IProductDao {
    //注入EnttiyManager
    //@Autowired 不能使用这个注入
    //@PersistenceContext通过持久化上下文得到entityManager
    @PersistenceContext
    private EntityManager entityManager;
    ……增伤改查方法……}

3、IProductService

4、 ProductServiceImpl

注入的Dao的接口,以后都是了。

Service层需要处理业务——开启事务注解

/* 处理业务:开启事务
*       Propagation.REQUIRED(常用)
          表示当前方法必须运行在事务中。
        Propagation.SUPPORTS(常用)
*        表示当前方法不需要事务上下文,但是如果存在当前事务的话,那么该方法会在这个事务中运行
*/
@Transactional(propagation = Propagation.SUPPORTS,readOnly = true)
public class ProductServiceImpl implements IProductService {
    //注入Dao的接口
    @Autowired
    private IProductDao productDao;
    /*这里的增、删、改都是需要事务的哦!!所以再给他们单独配置一个*/
    @Transactional(propagation = Propagation.REQUIRED)
    public void save(Product product) {
        productDao.save(product);
    }

三、Spring事务传播机制

3.1、什么是传播机制

多个方法之间,比如A方法 去调用B方法 事务就可以进行相互传播(A有事务,调用B后,B也被加起事务了)

3.2、传播机制总共有七种:

Propagation.REQUIRED(常用)

表示当前方法必须运行在事务中。如果当前事务存在,方法将会在该事务中运行。否则,会启动一个新的事务

Propagation.SUPPORTS(常用)

Propagation.SUPPORTS(常用)
表示当前方法不需要事务上下文,但是如果存在当前事务的话,那么该方法会在这个事务中运行

3.3、配置及使用:

1、注入:JpaTransactionManager

<!-- 1、事务管理器-->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <!--注入:EntityManagerFactory  好让我们的事务去管理他-->
    <property name="entityManagerFactory" ref="entityManagerFactory"></property>
</bean>
<!-- 2、开启事务 扫描@Transaction这种注解-->
<tx:annotation-driven/>

2、使用

如果@Transactional配置到类上面 ,类里面方法都是用这个传播机制 ;

如果自身的方法配置@Transactional传播机制 方法上面就采用自己配置注解

readOnly = true 只读:只允许读取 – 查询方法配置

@Service
@Transactional(propagation = Propagation.SUPPORTS,readOnly = true)
public class ProductServiceImpl implements IProductService {

    //注入Dao的接口
    @Autowired
    private IProductDao productDao;

    /*这里的增、删、改都是需要事务的哦!!所以再给他们单独配置一个*/
    @Transactional(propagation = Propagation.REQUIRED)
    public void save(Product product) {
        productDao.save(product);
    }

四、SpringMVC+spring集成

1、配置步奏

(1)导入jar --spring-web /spring-webmvc

(2)、配置 applicationContext-MVC.xml 配置文件

​ 0、配置mvc命名空间(如果报红-找不到,就把jar包删了)

​ 1、扫描controller

​ 2、静态资源放行

​ 3、 扫描@RequestMapping注解

​ 4、视图解析器:InternalResourceViewResolver

​ 配置前缀 后缀

​ 5、上传解析器

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

    <!-- 1、扫描controller-->
    <context:component-scan base-package="com.cc.ssj.web.controller"></context:component-scan>

    <!-- 2、静态资源放行-->
    <mvc:default-servlet-handler/>

    <!-- 3、扫描RequestMapping-->
    <mvc:annotation-driven/>

    <!-- 4、视图解析器:InternalResourceViewResolver-->
    <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>

    <!--5、上传-->
    <bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize">
            <value>${1024*1024*10}</value>
        </property>
    </bean>
</beans>

(3)、配置web.xml

​ 1、核心控制器配置:DispatcherServlet

​ 初始化:访问 classpath:applicationContext_mvc.xml 这个配置文件

​ 2、字符编码过滤器:CharacterEncodingFilter

​ 3、监听器读取配置

4、处理懒加载关闭问题

4.1、异常1:(JSON的对象数据传不过去)

JsonMappingException: could not initialize proxy - no Session 
LazyInitializationException: could not initialize proxy - no Session

处理方式:

​ 延迟 entityManager 关闭(我们去取dir分类中的name的时候已经关闭了。)。

​ 加一层过滤器(放到最上面)

4.1、异常2:没有找到 “handler” 这个属性

异常2:HttpMessageNotWritableException……中没有找到   "handler"   这个属性
1.jpa在底层延迟加载的时候额外生产了一个属性"handler"
2.SpringMVC返回JSON数据进行数据组装的时候,出现冲突

处理方式:

​ 让SpringMVC忽略"handler" 这个属性

实体类中的List数据(Product中的dir属性)上面打注解:

@JsonIgnoreProperties({"hibernateLazyInitializer","handler"})

5、web.xml 所有配置:


    <!-- 4、处理懒加载关闭问题 -->
    <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>

    <!-- 1、核心控制器配置-->
    <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都要过-->
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!--2、字符编码过滤器-->
    <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>

    <!--3、监听器读取配置-->
    <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>

(4)、配置tomCat服务器

略……

五、前台处理数据 及 Controller层注意事项

1、Controller层注意事项

如果要返回json数据,一定要用:@ResponseBody ——返回json数据

2、处理数据:

注意:jsp返回数据时,如果返回的json数据中有Obejct对象的数据,需要:

1、在需要取值的定义一个:formatter: 函数名(cc) 属性

<th data-options="field:'dir',width:80,align:'right',formatter:cc">类型</th>

2、使用JS代码去取值即可

dir是product中的一个字段,但是是对象,所以需要这样取值

<script type="text/javascript">
    function cc (dir) {
        if (dir != null) {
            return dir.name;
        }
    }
</script>

2、处理数据:

注意:jsp返回数据时,如果返回的json数据中有Obejct对象的数据,需要:

1、在需要取值的定义一个:formatter: 函数名(cc) 属性

<th data-options="field:'dir',width:80,align:'right',formatter:cc">类型</th>

2、使用JS代码去取值即可

dir是product中的一个字段,但是是对象,所以需要这样取值

<script type="text/javascript">
    function cc (dir) {
        if (dir != null) {
            return dir.name;
        }
    }
</script>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值