Spring框架进阶3

Posted XDZY

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring框架进阶3相关的知识,希望对你有一定的参考价值。

Spring框架进阶3

测试spring_jdbc和spring对事务的管理

 

先配置相应的pom

<?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>com.spring</groupId>
    <artifactId>spring_3</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!-- 属性 -->
    <properties>
        <!-- 设置编译版本为1.7 -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
        <!-- 可以绑定版本号 -->
        <spring.version>4.3.5.RELEASE</spring.version>
    </properties>

    <!-- 锁定版本,struts2-2.3.24、spring4.2.4、hibernate5.0.7 -->
    <dependencyManagement>
        <dependencies>
            <!-- 核心包 -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>${spring.version}</version>
            </dependency>

            <!-- pring IOC的基础实现,包含访问配置文件、创建和管理bean等 -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
                <version>${spring.version}</version>
            </dependency>

            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring.version}</version>
            </dependency>

            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context-support</artifactId>
                <version>${spring.version}</version>
            </dependency>

            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
                <version>${spring.version}</version>
            </dependency>

            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>${spring.version}</version>
            </dependency>

            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-tx</artifactId>
                <version>${spring.version}</version>
            </dependency>

            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aop</artifactId>
                <version>${spring.version}</version>
            </dependency>


            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aspects</artifactId>
                <version>${spring.version}</version>
            </dependency>

            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>${spring.version}</version>
            </dependency>

            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>${spring.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <!-- 依赖管理 -->
    <dependencies>
        <!-- spring相关包 -->
        <!-- 核心包 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
        </dependency>

        <!-- pring IOC的基础实现,包含访问配置文件、创建和管理bean等 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
        </dependency>

        <!-- 数据库驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
            <scope>runtime</scope>
        </dependency>

        <!-- c3p0 -->
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
        </dependency>

        <!-- junit,4.12支持注解测试 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <!-- aop联盟 -->
        <dependency>
            <groupId>org.aopalliance</groupId>
            <artifactId>com.springsource.org.aopalliance</artifactId>
            <version>1.0.0</version>
        </dependency>

        <!-- weaver织入包 -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>com.springsource.org.aspectj.weaver</artifactId>
            <version>1.6.4.RELEASE</version>
        </dependency>

    </dependencies>
</project>

 

相应的连接池和配置文件

#加jdbc前缀的目的是为了避免后面的名字与其他地方名字冲突
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf-8
jdbc.username=root
jdbc.password=admins
<?xml version="1.0" encoding="UTF-8"?>
<!-- 头部约束的作用:beans:最基本;context:读取资源文件;aop:配置aop;tx:配置事务通知 -->
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.2.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx-4.2.xsd ">

    <!-- 读取连接池配置文件 -->
    <context:property-placeholder location="jdbc.properties"/>

    <!-- 1.将连接池放入spring容器 -->
    <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <!-- set注入 -->
        <!--<property name="driverClass" value="com.mysql.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mysql:///test"/>
        <property name="user" value="root"/>
        <property name="password" value="admins"/>-->

        <!-- 资源文件配置 -->
        <property name="driverClass" value="${jdbc.driver}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!-- 2.将JdbcTemplate放入spring容器 -->
    <bean name="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 3.将UserDao放入spring容器 -->
    <bean name="userDao" class="com.dao.UserDaoImpl">
        <property name="jt" ref="jdbcTemplate"/>
    </bean>

    <!-- 无需依赖JdbcTemplate -->
    <!-- 2.AccountDao放入spring容器 -->
    <bean name="accountDao" class="com.dao.AccountDaoImpl">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 3.AccountService放入spring容器 -->
    <bean name="accountService" class="com.service.AccountServiceImpl">
        <property name="dao" ref="accountDao"/>
        <property name="template" ref="transactionTemplate"/>
    </bean>

    <!-- 3种事务管理方式 -->
    <!-- 事务核心管理器,封装了事务的所有操作,依赖连接池 -->
    <bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 依赖注入 -->
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 1:编码方式;事务模板对象 -->
    <bean name="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
        <property name="transactionManager" ref="transactionManager"/>
    </bean>

    <!-- 2:xml配置;配置事务通知 -->
    <tx:advice transaction-manager="transactionManager" id="txAdvice">
        <tx:attributes>
            <!-- isolation:隔离级别;propagation:传播行为 ;read-only:只读-->
            <!-- 以方法名为单位进行配置 -->
            <tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
            <!-- 通常都会加通配符进行配置 -->
            <tx:method name="save*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
            <tx:method name="persist*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
            <tx:method name="update*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
            <tx:method name="modify*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
            <tx:method name="delete*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
            <tx:method name="remove*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
            <tx:method name="get*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true"/>
            <tx:method name="find*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true"/>
        </tx:attributes>
    </tx:advice>

    <!-- 配置织入 -->
    <aop:config>
        <!-- 目标对象 -->
        <aop:pointcut id="txPc" expression="execution(* com.service.*ServiceImpl.*(..))"/>
        <!-- 配置切面:advice-ref:通知;pointcut-ref:切入点 -->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPc"/>
    </aop:config>

    <!-- 开启使用注解管理aop事务 -->
    <tx:annotation-driven/>
</beans>

 

数据库不提供了,先来个bean

package com.bean;

/**
 * @author: XDZY
 * @date: 2018/9/9 14:55
 * @description: 实体bean
 */
public class User {
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name=\'" + name + \'\\\'\' +
                \'}\';
    }
}

 

测试jdbc模板

package com.dao;

import com.bean.User;

import java.util.List;

/**
 * @author: XDZY
 * @date: 2018/9/9 14:56
 * @description: 操作user接口
 */
public interface UserDao {
    /**
     * 增
     *
     * @param user
     */
    void save(User user);

    /**
     * 根据用户ID删除
     *
     * @param id
     */
    void delUserById(Integer id);

    /**
     * 改
     *
     * @param user
     */
    void update(User user);

    /**
     * 根据用户ID查询
     *
     * @param id
     * @return
     */
    User findUserById(Integer id);

    /**
     * 查询用户数量
     *
     * @return
     */
    int findCount();

    /**
     * 查询所有用户
     *
     * @return
     */
    List<User> findUserList();
}
package com.dao;

import com.bean.User;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

/**
 * @author: XDZY
 * @date: 2018/9/9 15:02
 * @description: 使用jdbc模板实现增删改查
 */
public class UserDaoImpl implements UserDao {
    private JdbcTemplate jt;

    public void setJt(JdbcTemplate jt) {
        this.jt = jt;
    }

    @Override
    public void save(User user) {
        String sql = "insert into user_info values(0,?)";
        jt.update(sql, user.getName());
    }

    @Override
    public void delUserById(Integer id) {
        String sql = "delete from user_info where id=?";
        jt.update(sql, id);
    }

    @Override
    public void update(User user) {
        String sql = "update user_info set name=? where id=?";
        jt.update(sql, user.getName(), user.getId());
    }

    @Override
    public User findUserById(Integer id) {
        String sql = "select * from user_info where id=?";
        return jt.queryForObject(sql, new RowMapper<User>() {//匿名内部类
            //ResultSet:结果集;int i:第几行,即第几个数据
            @Override
            public User mapRow(ResultSet rs, int i) throws SQLException {
                User user = new User();
                user.setId(rs.getInt("id"));
                user.setName(rs.getString("name"));
                return user;
            }
        }, id);
    }

    @Override
    public int findCount() {
        String sql = "select count(*) from user_info";
        Integer count = jt.queryForObject(sql, Integer.class);
        return count;
    }

    @Override
    public List<User> findUserList() {
        String sql = "select * from user_info";
        List<User> list = jt.query(sql, new RowMapper<User>() {
            @Override
            public User mapRow(ResultSet rs, int i) throws SQLException {
                User user = new User();
                user.setId(rs.getInt("id"));
                user.setName(rs.getString("name"));
                return user;
            }
        });
        return list;
    }
}
package com.jabcDemo;

import com.bean.User;
import com.dao.UserDao;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;

/**
 * @author: XDZY
 * @date: 2018/9/9 13:50
 * @description: 演示jdbc模板
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Demo {
    @Resource(name = "userDao")
    private UserDao userDao;

    @Test
    public void test() throws Exception {
        //准备连接池
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass("com.mysql.jdbc.Driver");
        dataSource.setJdbcUrl("jdbc:mysql:///test");
        dataSource.setUser("root");
        dataSource.setPassword("admins");

        //创建jdbc模板对象
        JdbcTemplate jt = new JdbcTemplate();
        jt.setDataSource(dataSource);

        //书写sql,并执行
        String sql = "insert into user_info values(0,\'day\')";
        jt.update(sql);
    }

    @Test
    public void test1() throws Exception {
        User user = new User();
        user.setName("tom");
        userDao.save(user);
    }

    @Test
    public void test2() throws Exception {
        User u = new User();
        u.setId(2);
        u.setName("jack");
        userDao.update(u);

    }

    @Test
    public void fun4() throws Exception {
        userDao.delUserById(2);
    }

    @Test
    public void fun5() throws Exception {
        System.out.println(userDao.findCount());
    }

    @Test
    public void fun6() throws Exception {
        System.out.println(userDao.findUserById(1));
    }

    @Test
    public void fun7() throws Exception {
        System.out.println(userDao.findUserList());
    }
}

 

测试事务管理方式

package com.dao;

/**
 * @author: XDZY
 * @date: 2018/9/9 16:54
 * @description: 事务的操作
 */
public interface AccountDao {
    /**
     * 加钱
     *
     * @param id
     * @param money
     */
    void increaseMoney(Integer id, double money);

    /**
     * 减钱
     *
     * @param id
     * @param money
     */
    void decreaseMoney(Integer id, double money);
}
package com.dao;

import org.springframework.jdbc.core.support.JdbcDaoSupport;

/**
 * @author: XDZY
 * @date: 2018/9/9 16:57
 * @description: 不用jdbc模板,扩展知识(继承JdbcDaoSupport直接依赖连接池就行)
 */
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
    @Override
    public void increaseMoney(Integer id, double money) {
        getJdbcTemplate().update("update t_acount set money=money+? where id=?", money, id);
    }

    @Override
    public void decreaseMoney(Integer id, double money) {
        getJdbcTemplate().update("update t_acount set money=money-? where id=?", money, id);
    }
}
package com.service;

/**
 * @author: XDZY
 * @date: 2018/9/9 17:03
 * @description: 逻辑运算
 */
public interface AccountService {
    /**
     * 转账方法
     *
     * @param from
     * @param to
     * @param money
     */
    void transfer(Integer from, Integer to, double money);
}
package com.service;

import com.dao.AccountDao;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;

/**
 * @author: XDZY
 * @date: 2018/9/9 17:06
 * @description: 逻辑运算
 * 注解也可以加在类上;个别情况个别写
 */
@Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED, readOnly = true)
public class AccountServiceImpl implements AccountService {
    private AccountDao dao;
    /**
     * 事务模板
     */
    private TransactionTemplate template;

    public void setDao(AccountDao dao) {
        this.dao = dao;
    }

    public void setTemplate(TransactionTemplate template) {
        this.template = template;
    }

    //转账操作;匿名内部类要访问外部数据要加final
    //事务模板已经封装好,只需提供操作
    //模板过程(1.打开事务 2.调用doInTransactionWithoutResult方法 3.提交事务)
    /*@Override
    public void transfer(final Integer from,final Integer to,final double money) {
        //根据不同的模板调用相应的接口
        //不同的框架对事务的操作是不同的,但是事务的操作流程是一样的;所以spring提供接口来管理事务
        template.execute(new TransactionCallbackWithoutResult() {
            //实现对事务的管理
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                //减钱
                dao.decreaseMoney(from,money);
                //制造异常,测试事务是否有效;就是出现异常还会不会转钱
                //int i=1/0;
                //加钱
                dao.increaseMoney(to,money);
            }
        });
    }*/

    //xml方式管理事务
    //注解方式管理事务
    @Override
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED, readOnly = false)
    public void transfer(Integer from, Integer to, double money) {
        //减钱
        dao.decreaseMoney(from, money);
        //制造异常,测试事务是否有效;就是出现异常还会不会转钱
        //int i=1/0;
        //加钱
        dao.increaseMoney(to, money);
    }
}
package com.jabcDemo;

import com.service.AccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;

/**
 * @author: XDZY
 * @date: 2018/9/9 13:50
 * @description: 事务的操作
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Demo2 {
    @Resource(name = "accountService")
    private AccountService as;

    @Test
    public void test() {
        //1给2转账500元
        as.transfer(1, 2, 500d);
    }
}

 

以上是关于Spring框架进阶3的主要内容,如果未能解决你的问题,请参考以下文章

从 0 开始手写一个 Spring MVC 框架,向高手进阶!

Spring框架进阶Spring V1.0

Spring框架进阶Spring V1.0

Spring框架进阶Spring V3.0 DI源码分析流程

Spring框架进阶常见组件

Spring框架进阶Spring V3.0 IOC源码分析流程