Spring 配置數據源之一三兄弟

前期的準備工做,咱們是使用的是maven,咱們下載節點便可。。。java

節點以下:mysql

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

 <!--spring-jdbcjar 包-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>4.3.3.RELEASE</version>
</dependency>

<!--commons-dncpjar 包-->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-dbcp2</artifactId>
    <version>2.1.1</version>
</dependency>

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

<!--mysql數據庫驅動-->
<dependency>
     <groupId>org.wisdom-framework</groupId>
     <artifactId>mysql-connector-java</artifactId>
     <version>5.1.34_1</version>
</dependency>

導入節點完畢,咱們的準備工做就完成了,接下來進入代碼世界。。。。。。web

(1)建立分層  beans層(實體類)   dao(表示層)  biz(業務邏輯層) web(數據展現) util(工具類層)spring

 今天講解的只涉及到beans,dao,biz,web先不做討論了。sql

beans:數據庫

package cn.books.beans;

/**
 * Created by accp on 2017/3/30.
 */
public class Book {
    private Integer id;
    private String name;
    private String price;

    public Book() {
    }

    public Book(String name, String price) {
        this.name = name;
        this.price = price;
    }

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }
}

dao:apache

package cn.books.dao;

import cn.books.beans.Book;
import org.springframework.jdbc.core.support.JdbcDaoSupport;

import java.util.List;

/**
 * Created by accp on 2017/3/30.
 */
public interface BookDao {
    int add(Book book);

    List<Book> selectAll();
}

對方法的實現層impl:app

咱們分兩種方式講解:dom

第一種:使用註解的方式實現maven

package cn.books.dao.impl;

import cn.books.beans.Book;
import cn.books.dao.BookDao;
import cn.books.util.MyRowMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.util.List;

/**
 * Created by accp on 2017/3/30.
 */
@Repository
public class BookDaoImpl extends  JdbcDaoSupport implements BookDao {

    public int add(Book book) {
        int count = this.getJdbcTemplate().update("insert into book(name,price) values(?,?)",book.getName(),book.getPrice());
        return count;
    }

    public List<Book> selectAll() {
        return this.getJdbcTemplate().query("select * from book",new MyRowMapper());
    }
    @Autowired
    public void setJdbcTemplate2(JdbcTemplate jbdcTemplate){
        super.setJdbcTemplate(jbdcTemplate);
    }
}

看到這裏應該有不少童鞋有疑惑,爲甚要定義setJdbcTemplate2()方法呢?

緣由就在於下面的代碼:

    /**
     * Set the JdbcTemplate for this DAO explicitly,
     * as an alternative to specifying a DataSource.
     */
    public final void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
        initTemplateConfig();
    }



    @Override
    protected void checkDaoConfig() {
        if (this.jdbcTemplate == null) {
            throw new IllegalArgumentException("'dataSource' or 'jdbcTemplate' is required");
        }
    }

該方法源自父類的方法,而且是通過final修飾,咱們都知道被final修飾的方法是不能被修改的,當咱們本身不從新定義方法,而是使用

相同的方法名時,會出現以下錯誤:

  

當註解錯誤時,出現以下錯誤:

biz層:

package cn.books.biz;

import cn.books.beans.Book;

import java.util.List;

/** * Created by accp on 2017/3/30. */ public interface BookBiz { int add(Book book); List<Book> selestAll(); }

biz層方法的實現層impl:

package cn.books.biz.impl;

import cn.books.beans.Book;
import cn.books.biz.BookBiz;
import cn.books.dao.BookDao;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * Created by accp on 2017/3/30.
 */
@Service("bookBiz")
public class BookBizImpl implements BookBiz {
    @Resource
    private BookDao dao;
    public int add(Book book) {
        return dao.add(book);
    }

    public List<Book> selestAll() {
        return dao.selectAll();
    }
}

準備一個測試類:

package cn.books.test;


import cn.books.beans.Book;
import cn.books.biz.BookBiz;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.List;

/**
 * Created by accp on 2017/3/29.
 */
public class FirstTest {
    @Test
    public void findTwo(){
        ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContexttemp.xml");
        BookBiz proxy=(BookBiz) ctx.getBean("bookBiz");
        int count = proxy.add(new Book("你好嗎?第二次", "45"));
        System.out.println(count);
    }

    @Test
    public void findOne(){
        ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContexttemp.xml");
        BookBiz proxy=(BookBiz) ctx.getBean("bookBiz");
        List<Book> list = proxy.selestAll();
        for (Book item  : list) {
            System.out.println(item.getName());
        }
    }
}

寫到這裏,是否是都完成了呢?NO,NO

千萬不要忘記配置xml文件---------重中之重

xml編寫:

建立applicationContexttemp.xml

更改命名空間:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       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.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
  

編寫xml文件的第一步:

<!--配置數據源-->

 <!--spring 內置-->
    <bean id="dataSource" 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.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>
    <!--c3p0數據源-->
    <!--<bean id="dataSource" 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.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>-->
    <!--定義dbcp數據源-->
    <!--<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
        <property name="driverClassName" value="${jdbc.driver}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>-->

共三種配置方案,使用最多的是後面兩種,今天是用的是第一種。

<!--註冊jdbc-->

 <!--註冊jdbc-->
    <context:property-placeholder location="classpath:jdbcmysql.properties"></context:property-placeholder>

<!jdbcmysql.properties文件>

建立一個名稱爲jdbcmysql.properties的文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///y2163
jdbc.username=root
jdbc.password=123456

要想使用註解必需要配置包掃描器:

 <context:component-scan base-package="cn.books"></context:component-scan>

咱們制定總體包,無論哪一個層使用註解均可以掃描到。。。。。

<!--jdbcTemplate-->

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>


代碼編寫到這裏,咱們就能夠運行測試類的代碼了。。。。

有童鞋細心地看代碼沒,咱們上面定義的查詢所有信息的方法,有個知識點並無說到,若是你注意到了,就說明你認真看了。。。。

接下來咱們講解一下怎麼實現從數據庫讀取數據

使用的是query()方法,翻看源碼能夠很清晰的看到,它有不少重載

示例使用的是:

@Override
    public <T> List<T> query(String sql, RowMapper<T> rowMapper) throws DataAccessException {
        return query(sql, new RowMapperResultSetExtractor<T>(rowMapper));
    }

繼續點擊query查看:

@Override
    public <T> T query(final String sql, final ResultSetExtractor<T> rse) throws DataAccessException {
        Assert.notNull(sql, "SQL must not be null");
        Assert.notNull(rse, "ResultSetExtractor must not be null");
        if (logger.isDebugEnabled()) {
            logger.debug("Executing SQL query [" + sql + "]");
        }
        class QueryStatementCallback implements StatementCallback<T>, SqlProvider {
            @Override
            public T doInStatement(Statement stmt) throws SQLException {
                ResultSet rs = null;
                try {
                    rs = stmt.executeQuery(sql);
                    ResultSet rsToUse = rs;
                    if (nativeJdbcExtractor != null) {
                        rsToUse = nativeJdbcExtractor.getNativeResultSet(rs);
                    }
                    return rse.extractData(rsToUse);
                }
                finally {
                    JdbcUtils.closeResultSet(rs);
                }
            }
            @Override
            public String getSql() {
                return sql;
            }
        }
        return execute(new QueryStatementCallback());
    }

繼續點擊executeQuery()方法

 ResultSet executeQuery(String sql) throws SQLException;

到了這裏就跟咱們熟悉的查詢方法碰到了一塊兒,咱們很清晰地看到它返回的是ResultSet

點擊RowMapper<T>就能夠看到他只有一個方法

   /**
     * Implementations must implement this method to map each row of data
     * in the ResultSet. This method should not call {@code next()} on
     * the ResultSet; it is only supposed to map values of the current row.
     * @param rs the ResultSet to map (pre-initialized for the current row)
     * @param rowNum the number of the current row
     * @return the result object for the current row
     * @throws SQLException if a SQLException is encountered getting
     * column values (that is, there's no need to catch SQLException)
     */
    T mapRow(ResultSet rs, int rowNum) throws SQLException;

這個方法會根據你傳入的rs獲得T類型,就是咱們示例中的Book

因此咱們定義了MyRowMapper類

package cn.books.util;

import cn.books.beans.Book;
import org.springframework.jdbc.core.RowMapper;

import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * Created by accp on 2017/3/30.
 */
public class MyRowMapper implements RowMapper<Book> {
    public Book mapRow(ResultSet rs, int rowNum) throws SQLException {
        Book book=new Book();
        book.setName(rs.getString("name"));
        book.setPrice(rs.getString("price"));

        return book;
    }
}

在查詢語句中咱們就能夠經過建立new MyRowMapper()來獲取數據。

運行測試類的代碼,獲得咱們從數據庫拿到的數據。。。。。。。。。。

去實踐吧,騷年。。。。。。。。。。

相關文章
相關標籤/搜索