1. 程式人生 > >spring知識七------對JDBC的支援

spring知識七------對JDBC的支援

概述

spring框架也是集成了對JDBC資料庫的操作,但是要明白的是spring對JDBC的支援只是一個簡單的封裝,而不是真正意義上的ORM框架,其中最主要的就是Spring對資料庫的操作不支援級聯操作,即對於存在外來鍵關聯的表,查詢資料時,不會連帶查詢。但是spring新增了對資料庫原始檔的配置,這個可以說是簡化了對資料來源的連線。一般情況下我們都會在spring容器管理的基礎上整合Hibernate框架或者ibatis框架。
spring框架對資料庫的封裝分為兩個模板JdbcTemplate 和NamedParameterJdbcTemplate。其中最主要的區別就是NamedParameterJdbcTemplate可以使用具名引數。


具名引數: SQL 按名稱(以冒號開頭)而不是按位置進行指定。 具名引數更易於維護, 也提升了可讀性。具名引數由框架類在執行時用佔位符取代。具名引數只在 NamedParameterJdbcTemplate 中得到了支援 。

JdbcTemplate

首先我們需要在配置檔案中新增我們所需要的配置檔案。
可以看出我們所需要的類是在【org.springframework.jdbc.core】包中

        <!-- 配置jdbc模板 JdbcTemplate -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
>
<property name="dataSource" value="#{datasource}"></property> </bean>

當我們配置好檔案時,我們就可以進行對資料庫的增刪改查了。在這裡一定要注意方法的呼叫
在查詢時,我們要記得新增POJO類,讓其返回為一個物件,而且要注意使用sql語句的別名與POJO類變數發生一一對映
不支援級聯查詢,如果一個類中包含了另外一個類變數,則會返回【null 】值。
RowMapper介面 指定如何去對映結果集的行,常用 的實現類是BeanPropertyRowMapper。
JdbcTemplate 類被設計成為執行緒安全的

, 所以可以再 IOC 容器中宣告它的單個例項, 並將這個例項注入到所有的 DAO 例項中。

    @Test  //單條記錄更新  update(String sql, Object... args) 
    public void testUpdateSingle(){
        String sql = "Update employ set name=? where id=?";
        jdbcTemplate.update(sql, "fafa",5);
    }

    @Test   
    //批量更新 batchUpdate(String sql, List<Object[]> batchArgs)
    /* 注意最後一個引數batchArgs為Object[]的List 型別:
        修改一條記錄需要一個Object的陣列,修改多條記錄需要多個Object的陣列,,批量修改則是存放在List中
    */
    public void testUpdateBatch(){
        String sql = "insert into employ(name,age,sex,departid) values(?,?,?,?)";
        List<Object[]> batchArgs =new ArrayList<Object[]>();
        batchArgs.add(new Object[]{"AA",15,"男",1});
        batchArgs.add(new Object[]{"BB",18,"女",2});
        batchArgs.add(new Object[]{"CC",22,"男",1});

        jdbcTemplate.batchUpdate(sql, batchArgs);
    }


    @Test
    /*
     * 從資料庫中獲取一條記錄就是對應的一個物件
     * RowMapper介面  指定如何去對映結果集的行,常用 的實現類是BeanPropertyRowMapper
     * 在sql語句中使用別名完成列名與類的屬性名的對映。last_name  lastName
     * 不支援級聯屬性的查詢,JdbcTemplate 只是簡單的封裝jdbc,不是ORM 框架
     * 
     * queryForObject(String sql, RowMapper<Employ> rowMapper, Object... args)
     */

    public void testQueryObject(){  
        String sql="select id,last_name lastName,age,sex,departid from employ where id=?";  
        RowMapper<Employ> rowmapper = new BeanPropertyRowMapper(Employ.class);
        Employ emp =  jdbcTemplate.queryForObject(sql, rowmapper,1);
        System.out.println(emp);
    }

    @Test  
    //查詢實體類集合,query(String sql, RowMapper<Employ> rowMapper, Object... args) 
    public void testQueryList(){
        String sql = "select id,last_name lastName,age,sex,departid from employ where id>?";
        RowMapper<Employ> rowMapper = new BeanPropertyRowMapper(Employ.class);
        List<Employ> query = jdbcTemplate.query(sql, rowMapper,5);
        System.out.println(query);
    }

JdbcDaoSupport

一般在專案中我們在持久層對資料庫進行操作,
Spring JDBC 框架還提供了一個 JdbcDaoSupport 類來簡化 DAO 實現. JdbcDaoSupport 類聲明瞭 jdbcTemplate 屬性, 它可以從 IOC 容器中注入, 或者自動從資料來源中建立。但是不建議這樣使用,因為這樣的使用,在我們利用註解的時候,需要我們手工匯入dataSource或者jdbcTemplate
在xml中我們可以通過配置檔案進行注入dataSource和jdbcTemplate。而在註解時,沒有辦法自動注入,因為在這裡JdbcDaoSupport對於Set的方法是Final的,不能夠被重寫,只能利用曲線救國。在我們自定義的方法中進行呼叫,然後設定dataSource或者jdbcTemplate。下面是程式碼演示,建議使用第二種方式。


// 在基於註解的時候,不推薦使用JdbcDaoSupport進行工作,而是在dao層引入JdbcTemplate作為其類成員變數
@Repository
public class DepartDAO extends JdbcDaoSupport {
// 在繼承spring的JdbcDaoSupport 時,
//利用註解時要注意引入一個dateSource或者JdbcTemplate 在此類中,否則會進行報錯 利用setter方法進行引入

/*  @Autowired
    public void SetterDatasource2(DataSource dataSource){
        setDataSource(dataSource);
    }
*/
    @Autowired
    public void SetterJdbcTeplate2(JdbcTemplate jdbcTemplate){
        setJdbcTemplate(jdbcTemplate);
    }

    public Depart get(int id){
        String sql = "select id,name,people_count peopleCount from depart where id=?";
        RowMapper<Depart> rowMapper = new BeanPropertyRowMapper(Depart.class);  

        return depart;
    }
}

// 推薦使用這個模式
@Repository
public class EmployDAO {

    @Autowired
    private JdbcTemplate jdbcTemplate;      
    public Employ  findEmploy(int id){
        String sql="select id,last_name lastName,age,sex,departid from employ where id=?";
        RowMapper<Employ> rowmapper = new BeanPropertyRowMapper(Employ.class);
        Employ emp =  jdbcTemplate.queryForObject(sql, rowmapper,id);

      return emp;
    }
}

NamedParameterJdbcTemplate

首先我們需要在配置檔案中新增我們所需要的配置檔案。
可以看出我們所需要的類是在【org.springframework.jdbc.core】包中
NamedParameterJdbcTemplate沒有無參的構造器,所以利用一個有參的構造器將DataSource傳遞進去

<!-- 配置 jdbc模板NamedParameterJdbcTemplate  該物件可以使用具名引數  -->

        <bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
            <constructor-arg ref="datasource"></constructor-arg>
        </bean>

對於NamedParameterJdbcTemplate的使用有兩種方式
方式一是簡單的起引數名稱
方式二是將引數名稱與我們的pojo類欄位名稱一致


    @Test  
    // 使用namedParameterJdbcTemplate模板進行操作資料庫,可以使用具名引數,對於資料的封裝我們放到map中
    /* 方式一
     *可以為引數取名字,如果有對個引數的話,可以省略對位置的麻煩,直接對應引數名就可以了,便於維護
     *但是就是比較麻煩,需要使用map進行資料封裝 
     *
     *update(String sql, Map<String, ?> paramMap)
     */
    public void testnamedParameterJdbcTemplate(){
        String sql ="insert into depart (name,people_count) values(:ln,:count)";

        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("ln", "ff");
        paramMap.put("count", 7);
        namedParameterJdbcTemplate.update(sql, paramMap);
    }


    @Test  // 使用namedParameterJdbcTemplate模板進行操作資料庫,可以使用具名引數
    /* 方式二
     *可以為引數取名字,如果使引數名字與我們類中的欄位名稱相對應的話,我們可以進行傳遞類物件
     *update(String sql, SqlParameterSource paramSource)
     */
    public void testnamedParameterJdbcTemplate02(){
        String sql ="insert into depart (name,people_count) values(:name,:peopleCount)";

        Depart depart = new Depart();
        depart.setName("太極");
        depart.setPeopleCount(6);

        SqlParameterSource paramSource = new BeanPropertySqlParameterSource(depart);
        namedParameterJdbcTemplate.update(sql, paramSource);
    }