spring第四天笔记

spring第四天笔记

一、内容介绍

1、jdbcTemplate的使用

2、spring的事务控制

二、jdbcTemplate的使用

1、jdbcTemplate的介绍

Spring对数据库的操作在jdbc上面做了深层次的封装,使用spring的注入功能,可以把DataSource注册到JdbcTemplate之中。

jdbc — dbutils – jdbcTemplate(spring 提供) – mybatis(主流) – spring data jpa(趋势)

2、数据源配置
a. c3p0数据源
		<!--c3p0数据源-->
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
        </dependency>
    <!--配置c3p0数据源-->
    <bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driver}"></property>
        <property name="jdbcUrl" value="${jdbc.url}"></property>
        <property name="user" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>
b. dbcp 数据源
	<!--dbcp数据源-->
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>
		
    <bean id="dbcpDataSource"  class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="${jdbc.driver}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>
c. spring jdbc 自带数据源,包含了JdbcTemplate对象
	<!--spring自带数据源-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>

    <bean id="springDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driver}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>
3、jdbcTemplate的CRUD
/**
 * 查询使用:query
 * 增删改:update
 *
 * queryForList :查询返回一个List集合,Map集合
 * query(sql ,属性与列的映射对象,参数):返回值:List<pojo>
 * queryForObject :针对于返回一个对象
 * update(sql ,参数):执行增删改操作
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TestJdbcTemplate {

    @Autowired
    JdbcTemplate jdbcTemplate;

    @Test
    public void testFindAll(){
        String sql = "select * from account";
//        方法返回值是List集合,list中是map集合
        List<Map<String, Object>> accountList = jdbcTemplate.queryForList(sql);
//        for (Map<String, Object> map : accountList) {
//            System.out.println(map);
//        }

        List<Account> accountList = jdbcTemplate.query(sql, new AccountRowMapper());
//        for (Account account : accountList) {
//            System.out.println(account);
//        }

    }

    @Test
    public void testFindById(){
        String sql = "select * from account where id = ?";
        List<Account> accountList = jdbcTemplate.query(sql, new AccountRowMapper(), 5);
//        System.out.println(accountList.size() == 1 ?accountList.get(0):"结果为null");
//        queryForObject(SQL语句,列与属性的映射,参数):掌握
        Account account = jdbcTemplate.queryForObject(sql, new AccountRowMapper(), 5);
//        System.out.println(account);

    }

    @Test
    public void testSave(){
        String sql = "insert into account values(null , ? ,?)";
        jdbcTemplate.update(sql ,"zhangsan", 10000);
    }

    @Test
    public void testUpdate(){
        String sql = "update account set money = ?, name = ? where id = ?";
        jdbcTemplate.update(sql ,1000,"lisi",4);
    }

    @Test
    public void testDel(){
        String sql = "delete from account where id = ?";
        jdbcTemplate.update(sql , 4);
    }

    @Test
    public void testGetTotalCount(){
        String sql = "select count(*) from account";
//        queryForObject(sql语句, 返回值类型)
        Integer count = jdbcTemplate.queryForObject(sql, Integer.class);
        System.out.println(count);
    }
}

映射关系(实现列名属性名不一致的映射类)

public class AccountRowMapper implements RowMapper<Account> {
    /**
     * @param rs  结果集对象,只包含一行数据
     * @param rowNum
     * @return
     * @throws SQLException
     */
    @Override
    public Account mapRow(ResultSet rs, int rowNum) throws SQLException {
        Account account = new Account();
        int id = rs.getInt("id");
        account.setId(id);
        account.setName(rs.getString("name"));
        account.setMoney(rs.getFloat("money"));
        return account;
    }
}
4、在dao中使用jdbcTemplate方法一
a. applicationContext.xml
		<!--创建jdbcTemplate模板对象-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="springDataSource"></property>
    </bean>
    
b.在dao层中使用模板对象
@Repository
public class AccountDaoImpl implements AccountDao {

	  //自动注入模板对象
    @Autowired
    JdbcTemplate  jdbcTemplate;
    
}
5、在dao中使用jdbcTemplate方法二(了解)
a. 在dao实现类中继承接口JdbcDaoSupport类
	public class AccountDaoImpl2 extends JdbcDaoSupport implements AccountDao 
	
b.所有的dao对象需要在xml中创建,需要通过set方法注入数据源对象
		<!--创建dao层对象-->
    <bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl2">
        <!--通过set方法注入数据源-->
        <property name="dataSource" ref="springDataSource"></property>
    </bean>

三、spring的事务控制

1、spring事务控制的api介绍–事务管理类

org.springframework.orm.hibernate5.HibernateTransactionManager: 在hibernate环境下使用
rg.springframework.jdbc.datasource.DataSourceTransactionManager: 在jdbcTemplate,mybatis(ibatis)环境下使用

2、事务的特性

a、事务的四个特性

原子性: 是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
隔离性: 多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离。
一致性: 事务前后数据的完整性必须保持一致。要么全部完成,要么全部不完成。
持久性: 一旦提交持久化到数据中

b、隔离级别
读未提交:read uncommited

	产生的问题:脏读,幻读,不可重复读
	
	脏读:读到了未提交的数据
	不可重复读:一个事务读到了另一个事务已经提交(update)的数据。引发另一个事务,在事务中的多次查询结果不一致。
	幻读(虚读):一个事务读到了另一个事务已经提交(insert)的数据。导致另一个事务,在事务中多次查询的结果不一致。

读已提交:read commited

	产生的问题:幻读,不可重复读
	解决的问题:脏读

重复读: repeatable read

	产生的问题:幻读
	解决的问题:脏读,不可重复读

串行化(序列化): serializable

	产生的问题:null
	解决的问题: 所有的问题
	隔离级别最高,效率最低

c、数据库的支持的隔离级别 – 一般情况下选择都是默认的隔离级别
mysql支持:

read uncommited
read commited
repeatable read
serializable
默认的隔离级别:repeatable read

Oracle支持:

read commited
serializable
read only(只读)
默认的隔离级别:read commited

3、事务的传播

a. 掌握

REQUIRED: 必要的: 如果没有事务,则新建一个事务,如果有事务,加入这个事务当中, spring指定为默认值
	增删改
SUPPORTS: 支持的: 如果没有事务,非事务执行,如果有事务,加入这个事务当中
	查询

b. 了解

MANDATORY: 可以使用当前的事务,如果没有事务,抛出异常
REQUERS_NEW: 新建一个事务,如果存在事务,则挂起事务
NOT_SUPPORTED: 必须非事务执行,如果有事务,则挂起事务
NEVER: 非事务执行,如果存在事务,抛出异常
NESTED: 有事务,嵌套执行,没有事务,执行REQUIRED
4、是否为只读的事务
a.如果是查询,则为只读的事务  readOnly = true
b.如果是增删改,则为非只读的事务,readOnly = false
5、基于xml声明式事务管理(配置文件)(重点)(推荐)

a. 编程式事务管理:在业务层写了事务技术代码
b. 声明式事务管理:在配置文件声明事务对象,管理事务,业务层中没有任何事务代码

  1. 引入依赖:
	<!--aop的切面配置需要的jar包-->
      <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.9</version>
      </dependency>
      <!--spring 的事务管理jar包-->
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>5.0.2.RELEASE</version>
      </dependency>
      <!--spring 的基础包-->
			<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
      <!--spring自带数据源, 包含了事务管理类 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>

2.编写配置文件

 <!--1、创建事务管理器对象-->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--注入数据源属性:事务存在连接中- 连接存在连接池(数据源)中-->
        <property name="dataSource" ref="springDataSource"></property>
    </bean>

    <!--2、事务的增强: 过滤方法是否需要拦截
        id:唯一的标识
        transaction-manager:指定事务管理器
    -->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <!--增强:方法的过滤-->
        <tx:attributes>
            <!--指定需要拦截的方法
            isolation:隔离级别, 一般选择默认的
            propagation:传播的行为,
            read-only: 是否为只读的事务,增删改:非只读事务 read-only=false
                                        查询:只读的事务:read-only=true

            find* :通配符配置,只要以 find开头即可
            -->
         <!--配置方式一:全部配置-->
            <!--增删改(取的都是默认值可以全部省略不写)-->
            <tx:method name="insert*" />
            <tx:method name="add*" />
            <tx:method name="update*" />
            <tx:method name="del*" />
            <tx:method name="delete*" />
            <tx:method name="save*" isolation="DEFAULT" propagation="REQUIRED" read-only="false" timeout="-1"/>
            <!--查询(不取默认值的写出来)-->
            <tx:method name="find*"  propagation="SUPPORTS" read-only="true" ></tx:method>
            <tx:method name="select*" propagation="SUPPORTS" read-only="true" ></tx:method>
            <tx:method name="query*" propagation="SUPPORTS" read-only="true"></tx:method>
            <tx:method name="get*" isolation="DEFAULT" propagation="SUPPORTS" read-only="true" timeout="-1"></tx:method>
            
       <!--配置方式二:one和theOrther-->
            <tx:method name="find*" propagation="SUPPORTS" read-only="true"></tx:method>
            <tx:method name="select*" propagation="SUPPORTS" read-only="true"></tx:method>
            <tx:method name="query*" propagation="SUPPORTS" read-only="true"></tx:method>
            <tx:method name="get*" propagation="SUPPORTS" read-only="true"></tx:method>
            <!--其他方法的配置方法-->
            <tx:method name="*" propagation="REQUIRED" read-only="false"></tx:method>
        </tx:attributes>
    </tx:advice>
    <!--3、aop的配置:
        切面= 切入点 +通知(增强)
        -->
    <aop:config>
        <!--切面配置
            advice-ref: 通知关联对象
            pointcut: 切入点:
          -->
        <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.itheima.service.impl.*.*(..))"></aop:advisor>
    </aop:config>
  1. 业务层
    业务层不需要任何事务管理,只需要提供业务代码即可
6、基于注解的配置(重点)

a. 引入依赖
与xml完全一致
b. 配置文件

1)配置事务管理类
	 <!--创建事务管理器对象-->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--注入数据源属性:事务存在连接中- 连接存在连接池(数据源)中-->
        <property name="dataSource" ref="springDataSource"></property>
    </bean>
2) 开启事务的注解管理
  	<!--transaction-manager: 关联事务管理器对象-->
    <tx:annotation-driven transaction-manager="txManager"></tx:annotation-driven>

    <!--开启aop的注解:自动代理-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

c. 业务层

出现接口上,表示该接口的所有实现类都有事务支持。
在类上标记注解:@Transactional,类中所有的方法都会使用事务管理
在方法上标记注解:@Transactional:只有该方法按照事务执行
以上三个位置的优先级:方法>类>接口

d.属性介绍

 @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, readOnly = false,timeout = -1)
发布了33 篇原创文章 · 获赞 2 · 访问量 976

猜你喜欢

转载自blog.csdn.net/Rhin0cer0s/article/details/100024064
今日推荐