zoukankan      html  css  js  c++  java
  • Spring 配置数据源之一三兄弟

    前期的准备工作,我们是使用的是maven,我们下载节点即可。。。

    节点如下:

    <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>

    导入节点完毕,我们的准备工作就完成了,接下来进入代码世界。。。。。。

    (1)创建分层  beans层(实体类)   dao(表示层)  biz(业务逻辑层) web(数据展示) util(工具类层)

     今天讲解的只涉及到beans,dao,biz,web先不作讨论了。

    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:

    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:

    我们分两种方式讲解:

    第一种:使用注解的方式实现

    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()来获取数据。

    运行测试类的代码,得到我们从数据库拿到的数据。。。。。。。。。。

    去实践吧,骚年。。。。。。。。。。

     
     

          

  • 相关阅读:
    中金所期货(future)指数
    Nginx负载均衡算法之四
    WSGI协议
    Flask 响应之定制全局有效的错误页面,之设置cookie,头信息。
    Python数据结构之栈,队列和堆
    三、Oracle 游标、存储过程、存储函数、触发器
    二、Oracle的结构学习
    一、Oracle的SQL语句学习
    oracle中的修改表结构
    eclipse编写xml文件时类名的自动补全(使用sts插件)
  • 原文地址:https://www.cnblogs.com/wl0000-03/p/6646410.html
Copyright © 2011-2022 走看看