Spring DAO 学习笔记(一)

Spring DAO

一、简介

DAO (Data Access Object)数据访问对象

Spring DAO 基于IOC,增加了一些组件,主要实现了以下的功能:

  • 提供对JDBC的支持,对JDBC进行封装,简化了DAO的编写,允许JDBC使用Spring资源,
  • 提供了AOP模式的事物管理,统一管理JDBC事物,

        <bean id="tx" class="...DataSourceTransactionManager">
         <!-- 开启@Transactional标记 -->
         <tx:annotation-driven transaction-manager="tx"/>   
    
  • 统一了异常处理层次,它包装的异常类型DataAccessException继承自RuntimeException,无需显示捕获

二、提供的API

Spring DAO为整合Jdbc提供了JdbcTemplate和JdbcDAOSupport类

JdbcTemplate

1.  简介

    JdbcTemplate封装了connection、statement、执行SQL、释放连接资源等操作。只需要提供SQL语句和参数就可以完成对数据库的增、删、改、查。在进行查询方法时还要提供一个rowmapper方法,即记录映射,将记录转换为对象。

2.  构造方法

    (1)  无参构造

    (2)  1参构造  JdbcTemplate(DataSource) //最常用



        这里传入的是DataSource接口的实现类对象BasicDataSource

        **关于BasicDataSource的使用** 

        a.  在java代码中利用BasicDataSource操作jdbc


                1.  创建DataSource

            BasicDataSource dataSource = new BasicDataSource();

            2. 设置驱动类的全名
            dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver");

            3. 设置数据库的链接地址
            dataSource.setUrl("jdbc:oracle:thin:@localhost:1521");

            4. 设置数据库的帐号
            dataSource.setUsername("liweijie");

            5. 设置数据库的密码
            dataSource.setPassword("123456");

            6. 获取数据库的连接对象
            Connection conn = dataSource.getConnection();

            7. 进行数据库的操作
            Statement state = conn.createStatement();

        b.  将BasicDataSource配置到Spring容器中,并给其注入属性值:具体操作步骤如下:


        方法一:直接注入BasicDataSource 的属性

        <bean id="basicDataSource" class="org.apache.tomcat.dbcp.dbcp.BasicDataSource">

        设置驱动类的全名
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>

        设置数据库的链接地址
        <property name="url" value="jdbc:oracle:thin:@localhost:1521"></property>

        设置数据库的帐号
        <property name="username" value="liweijie"></property>

        设置数据库的密码
        <property name="password" value="123456"></property>

    </bean> 

        方法二:将BasicDataSource的属性值存储在properties文件中进行读取

        db.properties文件中的信息如下:

            driverClassName:oracle.jdbc.driver.OracleDriver
            url:jdbc:oracle:thin:@localhost:1521:xe
            username:a2011102394
            password:123456


applicationContext.xml文件中的配置如下:

        <util:properties id = "db" location="classpath:db.properties">
        </util:properties>
        <bean id = "basicDataSource" 
              class = "org.apache.commons.dbcp.BasicDataSource">
              <property name="driverClassName" 
                        value = "#{db.driverClassName}">
              </property>
              <property name="url"
                        value = "#{db.url}">
              </property>
              <property name="username" value = "#{db.username}"></property>
              <property name="password" value = "#{db.password}" ></property>

        </bean>
    (3)  2参构造  JdbcTemplate(DataSource ,boolean )


3.  常用方法 主要对数据库进行增删改查的操作
  • queryForObject()

  • query()函数

    用来执行查询操作
    
    两参
    
        参数1. 要查询的SQL语句 
        参数2. 结果产生时的回调函数
    
    
    操作案例:
    
        template.query("select * from person", new ResultSetExtractor<List<Person>>() {
            /**
             * 当结果产生时 ,自动执行
             */
            @Override
            public List<Person> extractData(ResultSet result) throws SQLException, DataAccessException {
                ArrayList<Person> ps = new ArrayList<>();
                while (result.next()) {
                    String name = result.getString("name");
                    String age = result.getString("age");
                    Person p = new Person(name, age);
                    ps.add(p);
                }
    
                return ps;
            }
    
        });
    

三参

    参数1. 要查询的预编译SQL语句 
    参数2. 预编译语句中参数的填充, 是一个String 数组 
    参数3. 结果产生时的回调函数

操作案例:

    Boolean flag = template.query("select * from person where name=? and age=?", new String[]{"明达","179"}, new ResultSetExtractor<Boolean>(){

        @Override
        public Boolean extractData(ResultSet result) throws SQLException, DataAccessException {

            if(result.next()){
                return true;
            }
            return false;
        }

    });

* 查询语句中常用的回调函数类型: *

        1.  RowMapper<T> 接口

        回调方法为: 

            //参数1. 结果集对象
            //参数2. 查询的行数
            public <T> T mapRow(ResultSet result, int rowCount);

    2.  ResultSetExtractor<T> 接口

        回调方法为:
            //参数1. 结果集对象
            public <T> T extractData(ResultSet result);

    3.  BeanPropertyRowMapper<Boolean>(T.class) 类 (属于RowMapper的实现类)

        用来更快捷的直接获取结果使用

        回调方法由系统实现, 无序添加回调方法, 可直接传入泛型 ,获取结果 

        获取案例: 

        List<Person> ps = template.query("select*from person"
        ,new BeanPropertyRowMapper<Person>(Person.class));
  • update()函数

    一般用来执行对于数据库的更新操作: 
    
    更新数据库的操作 包含了:  insert update delete语句
    
    参数1. 要执行的预编译的SQL语句
    参数2. 是一个可变参数 ,是要执行的预编译的SQL语句中的参数的填充
    返回值 :  返回的是 当前SQL语句 对于数据的影响 行数
    

    操作案例:

    int count = template.update("insert into person values(?,?)", "向阳","3");
    System.out.println("这条SQL 影响了:"+count+"条数据");
    
  • execute()函数

    用来执行所有的SQL语句

    参数1. 要执行SQL语句
    
    没有返回值
    

    案例:

    template.execute("create table user(uname varchar2(20),upass varchar2(20))");
    

    提供了JdbcTemplate的组件,这个组件的作用

    1. 封装了connection、statement、执行SQL、释放连接资源等操作。只需要提供SQL语句和参数就可以完成对数据库的增、删、改、查。在进行查询方法时还要提供一个rowmapper方法,即记录映射,将记录转换为对象。
    2. 事物控制–声明式事物管理。

    3. 异常处理
      jdbcTemplate之中对异常进行了统一捕获处理,封装成了统一的DateAccessException,便于底层数据库技术的切换。


JdbcDaoSupport的使用步骤

  • JdbcDaoSupport的底层实现

    JdbcDaoSupport类中有一个私有属性JdbcTemplate的属性,该属性不能直接访问,但提供了get和set方法供子类进行访问。同时有一个setDateSource()的方法,该方法内部new出了一个JdbcTemplate对象,所以可以直接在z

    1. 在配置文件中, 添加dataSource对象

    2. 编写Class 继承自 JdbcDaoSupport

    3. 将编写的类, 添加到配置文件的bean节点中

    4. 将dataSource对象, 注入这个bean节点


配置文件案例:


    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <!-- 通过set方法 注入数据库的驱动地址 -->
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
    <!--  注入数据库地址  -->
        <property name="url" value="jdbc:oracle:thin:@localhost:1521"></property>
    <!--  注入数据库的帐号  -->
        <property name="username" value="liweijie"></property>
    <!--  注入数据库的密码  -->
        <property name="password" value="123456"></property>
    </bean>

    <bean id="userDBUtil" class="cn.xdl.dao.UserDBUtil">
    <!-- 
        根据传入的name  
            得到了一个Set方法: 
            setDataSource(dataSource)
     -->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

Java代码案例:

    public class UserDBUtil extends JdbcDaoSupport{}

JDBC事务

1.  编程式事务
2.  声明式事务
编程式事务
使用步骤

1.  创建了事务的管理对象 
    DataSourceTransactionManager manager = new DataSourceTransactionManager(getDataSource());
2.  创建一个事务模版对象 , 并传入事务管理对象, 进行事务的托管
    TransactionTemplate tt = new TransactionTemplate(manager);
3.  创建事务的回调方法
    TransactionCallback<String> callback = new TransactionCallback<String>() {
        //此方法自动调用
        /**
         *在这个方法中,默认情况下的所有jdbc操作 ,被视为一个整体, 代表一个事务 
         */
        @Override
        public String doInTransaction(TransactionStatus status) {

    };

    4.  执行事务
    tt.execute(callback);
声明式事务
1.  通过applicationContext.xml向容器中添加事务管理组件 , 并注入dataSource属性

    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="basicDataSource"></property>
    </bean>

2.  applicationContext.xml中开启事务注解扫描

    <tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/>

3.  在代码中, 对于想要使用事务管理的方法/类, 进行注解:

transactionl注解中的属性:

    propagation: 设置事务传播
    isolation : 设置事务隔离级别
    readOnly : 设置为只读,还是可读写
    rollbackFor : 设置遇到哪些异常必须回滚
    noRollbackFor : 设置遇到哪些异常不回滚

声明式事务与编程式事务的区别:

    1.  声明式事务是采用的aop方式 ,可以在不更改原有代码的情况下, 动态的加入事务! 解除了代码与事务的耦合!

    2.  声明式事务的应用范围最小为一个方法,不灵活!
        而编程式事务的应用最小范围可以控制到一行代码!更灵活!**

猜你喜欢

转载自blog.csdn.net/a2011102394/article/details/75578305