Spring+JDBC 数据库实例


Spring+JDBC 数据库实例_第1张图片


Spring +JDBC实例

JDBC 是和数据库交互最基本的的语言,在 Spring 中提供了 JdbcTemplate封装了JDBC的操作,最主要的还是 Spring IOC控制反转的特点。

参考教材:http://www.yiibai.com/spring/maven-spring-jdbc-example.html

版本信息

Tomcat 8.0
JDK 1.8
Eclipse版本 Neon.1a Release (4.6.1)
Spring 4.3.4
数据库 MySQL5.7.12

项目结构:

Spring+JDBC 数据库实例_第2张图片

lib包中要有MySQL数据库连接的jar包,我导入的Spring的jar如下,其实有些包都没用到,像事务,aop。(ˇˍˇ)

Spring+JDBC 数据库实例_第3张图片

源码下载:http://download.csdn.net/detail/peng_hong_fu/9695130

MySQL表

mysql> create database db_spring;
Query OK, 1 row affected (0.07 sec)

mysql> use db_spring;
Database changed
mysql> create table tb_customer(
    -> CUST_ID int NOT NULL auto_increment,
    -> NAME varchar(100) NOT NULL,
    -> AGE int NOT NULL,
    -> primary key(CUST_ID))
    -> default charset=utf8;
Query OK, 0 rows affected (0.29 sec)

mysql> desc tb_customer;
+---------+--------------+------+-----+---------+----------------+
| Field   | Type         | Null | Key | Default | Extra          |
+---------+--------------+------+-----+---------+----------------+
| CUST_ID | int(11)      | NO   | PRI | NULL    | auto_increment |
| NAME    | varchar(100) | NO   |     | NULL    |                |
| AGE     | int(11)      | NO   |     | NULL    |                |
+---------+--------------+------+-----+---------+----------------+

实体类Customer

Customer.java

package com.jxust.model;
/**
 * 客户实体类 对应表tb_customer
 * @author Peng
 * @Date2016年11月27日下午8:43:03
 */
public class Customer {
    private Integer custId;//id
    private String name;//姓名
    private Integer age;//年龄

    public Customer() {
        super();
    }

    public Customer(String name, Integer age) {
        super();
        this.name = name;
        this.age = age;
    }

    public Customer(Integer custId, String name, Integer age) {
        super();
        this.custId = custId;
        this.name = name;
        this.age = age;
    }
    //省略 setter and getter 
    @Override
    public String toString() {
        return "Customer [custId=" + custId + ", name=" + name + ", age=" + age + "]";
    }   
}

数据访问对象 Dao层

CustomerDAO

package com.jxust.dao;

import java.util.List;

import com.jxust.model.Customer;
/**
 *  客户管理Dao层接口
 * @author Peng
 * @Date2016年11月27日下午8:45:13
 */
public interface CustomerDAO {
    /**
     * 使用普通的JDBC操作数据库
     * @param customer
     */
    public void insertByJDBC(Customer customer);//添加一条客户数据
    public Customer findByCustomerId(int custId);//根据ID查询客户信息
    /**
     * 以下方法使用JdbcTemlate
     * @param customer
     */
    public void insertByJdbcTemlate(Customer customer);//添加一条客户数据
    public Customer findByCustomerIdByJdbcTemlate(int custId);//根据ID查询客户信息
    public List findAll();//查找所有客户信息
    public void bathupdate(List lists);//批处理添加客户数据
}

数据访问对象Dao层实现

JdbcCustomerDaoImpl.java

这是使用了普通的JDBC PreparedStatement,和spring 封装的JdbcTemplate

package com.jxust.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.sql.DataSource;

import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import com.jxust.dao.CustomerDAO;
import com.jxust.model.Customer;
import com.jxust.model.CustomerRowMapper;
/**
 * 客户管理Dao层实现类
 * @author Peng
 * @Date2016年11月27日下午8:45:41
 */
public class JdbcCustomerDaoImpl  implements CustomerDAO {
    /**
     *  这是一种装配方式 @Autowired@Qualifier("")
     */
    //注入数据库连接信息,第二种装配方式
    @Resource(name="dataSourceBean")
    private DataSource dataSource;

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    /**
     * 使用JDBC的PreparedStatement 添加数据
     */
    @Override
    public void insertByJDBC(Customer customer) {
        String sql = "INSERT INTO tb_customer(CUST_ID,NAME,AGE) VALUES(?,?,?)";
        Connection conn = null;

        try {
            conn = dataSource.getConnection();
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setInt(1, customer.getCustId());
            ps.setString(2, customer.getName());
            ps.setInt(3, customer.getAge());
            ps.executeUpdate();
            ps.close();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    /**
     * 使用JDBC的PreparedStatement查找数据
     */
    @Override
    public Customer findByCustomerId(int custId) {
        String sql = "SELECT * FROM tb_customer WHERE CUST_ID = ?";
        Connection conn = null;
        Customer customer = null;
        try {
            conn = dataSource.getConnection();
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setInt(1, custId);

            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                customer = new Customer();//这里要实例化
                customer.setCustId(rs.getInt("CUST_ID"));
                customer.setName(rs.getString("NAME"));
                customer.setAge(rs.getInt("AGE"));
            }
            rs.close();
            ps.close();

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }   
        return customer;
    }
    /**
     * 使用JdbcTemplate 添加数据
     */
    @Override
    public void insertByJdbcTemlate(Customer customer) {
        String sql = "INSERT INTO tb_customer(CUST_ID,NAME,AGE) VALUES(?,?,?)";
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        /**
         * 出现以下异常
         * The type org.springframework.dao.DataAccessException cannot be resolved. It is indirectly referenced from required .class files
         * 导入spring-tx-4.3.4.RELEASE.jar
         */
        jdbcTemplate.update(sql,new Object[]{customer.getCustId(),
                customer.getName(),customer.getAge()});     
    }
    /**
     * 使用JdbcTemplate 查询数据
     */
    @Override
    public Customer findByCustomerIdByJdbcTemlate(int custId) {
        Customer customer = new Customer();
        String sql = "SELECT * FROM tb_customer WHERE CUST_ID = ?";
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        //这里可以定义一个类CustomerRowMapper实现RowMapper,封装获取Customer对象的代码
        customer = (Customer) jdbcTemplate.queryForObject(sql, new Object[]{custId},new CustomerRowMapper());
        //customer = (Customer) jdbcTemplate.queryForObject(sql, new Object[]{custId},new BeanPropertyRowMapper<>(Customer.class));
        return customer;
    }
    /**
     * 使用JdbcTemplate 查询所有数据
     */
    @Override
    public List findAll() {
        String sql = "SELECT * FROM tb_customer";
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        List listCus = new ArrayList<>();
        listCus = jdbcTemplate.query(sql, new BeanPropertyRowMapper(Customer.class));
        return listCus;
    }
    /**
     * 使用JdbcTemplate 测试批处理
     */
    @Override
    public void bathupdate(List lists) {
        String sql ="INSERT INTO tb_customer(CUST_ID,NAME,AGE) VALUES(?,?,?) ";
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        jdbcTemplate.batchUpdate(sql,new BatchPreparedStatementSetter() {

            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                Customer customer = lists.get(i);
                ps.setLong(1, customer.getCustId());
                ps.setString(2, customer.getName());
                ps.setInt(3, customer.getAge() );       
            }       
            @Override
            public int getBatchSize() {
                //批处理的语句个数
                return lists.size();
            }
        });     
    }
}

在上面的类中,通过new JdbcTemplate类的得到实例,写这个类主要是说明继承JdbcDaoSupport,得到JdbcTemplate,在类中,直接通过getJdbcTemplate()就能得到JdbcTemplate实例

JdbcJdbcDaoSupport.java

package com.jxust.dao.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;

import com.jxust.dao.CustomerDAO;
import com.jxust.model.Customer;

/**
 * 测试采用继承JdbcDaoSupport的方式的到jdbcTemplate,在xml文件中注入dataSource
 * http://www.yiibai.com/spring/spring-jdbctemplate-querying-examples.html
 * 
 * @author Peng
 * @Date2016年11月24日下午5:05:49
 */
public class JdbcJdbcDaoSupport extends JdbcDaoSupport implements CustomerDAO {

    @Override
    public void insertByJDBC(Customer customer) {
        // TODO Auto-generated method stub

    }

    @Override
    public Customer findByCustomerId(int custId) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void insertByJdbcTemlate(Customer customer) {
        // TODO Auto-generated method stub

    }

    /**
     * 查找指定列的客户信息
     */
    @Override
    public Customer findByCustomerIdByJdbcTemlate(int custId) {
        String sql = "SELECT NAME FROM tb_customer WHERE CUST_ID = ?";

        String name = (String) getJdbcTemplate().queryForObject(sql, new Object[] { custId }, String.class);
        Customer cu = new Customer();
        cu.setName(name);
        return cu;
    }

    /**
     * 查询所有客户信息
     */
    @Override
    public List findAll() {
        String sql = "SELECT * FROM tb_customer";
        List listCus = new ArrayList<>();
        /**
         * 方式一 /*List> rows =
         * getJdbcTemplate().queryForList(sql); for (Map row : rows) { Customer
         * customer = new Customer(); customer.setCustId((Integer)
         * row.get("CUST_ID")); customer.setName((String)row.get("NAME"));
         * customer.setAge((Integer)row.get("AGE")); listCus.add(customer); }
         */

        // 方式二
        listCus = getJdbcTemplate().query(sql, new BeanPropertyRowMapper(Customer.class));
        return listCus;
    }

    @Override
    public void bathupdate(List lists) {
    }
}

CustomerRowMapper.java

这个类主要是对数据库查询返回的结果集,你也可以不封装出来,直接写在查询方法下。

package com.jxust.model;

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

import org.springframework.jdbc.core.RowMapper;
/**
 * 在数据库查询中,如果返回的类型是用户自定义的类型则需要包装
 * RowMapper可以将数据中的每一行封装成用户定义的类,
 * @author Peng
 * @Date2016年11月27日下午9:51:48
 */
public class CustomerRowMapper implements RowMapper<Object> {

    public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
        Customer customer = new Customer();
        customer.setCustId(rs.getInt("CUST_ID"));
        customer.setName(rs.getString("NAME"));
        customer.setAge(rs.getInt("AGE"));
        return customer;
    }
}

Spring bean配置

配置 customerDAO

Spring-Customer.xml


<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
    >
    

    <bean id="customerDAO" class="com.jxust.dao.impl.JdbcCustomerDaoImpl"  autowire="byType">
        
        
    bean>
    <bean id="customerDAObyDaoSupport" class="com.jxust.dao.impl.JdbcJdbcDaoSupport">
        <property name="dataSource" ref="dataSourceBean">property>
    bean>

beans>

配置数据源

Spring-Datesource.xml


<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="dataSourceBean" 
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/db_spring?useSSL=false" />
        <property name="username" value="root" />
        <property name="password" value="root" />
    bean>
beans>

引入上面两个Bean配置文件,测试的时候,取这个xml的数据,得到Bean。

application.xml


<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"
    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-4.3.xsd">

    




    <import resource="customer/Spring-Customer.xml"/>
    <import resource="database/Spring-Datasource.xml"/>
beans>

Junit测试

TestSpringJDBC.java

package test;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.jxust.dao.CustomerDAO;
import com.jxust.model.Customer;
/**
 *  测试dao层实现类方法的类,即使是同名的方法,getBean获取不同的bean,也是不同的实现内容
 * @author Peng
 * @Date2016年11月24日下午5:24:14
 */
public class TestSpringJDBC {

    /**
     * 普通的jdbc添加、查询客户数据
     */
    @Test
    public void testByJDBC(){
        ApplicationContext context = new 
                ClassPathXmlApplicationContext("application.xml");
        CustomerDAO dao = (CustomerDAO) context.getBean("customerDAO");

        Customer customer = new Customer(7,"李勃",21);
        dao.insertByJDBC(customer); 

        /*根据id查询客户数据
         * Customer customer = dao.findByCustomerId(6);     
            System.out.println(customer.toString());*/
    }

    /**
     * JdbcTemplate
     */
    @Test
    public void testByJdbcTemplate(){
        ApplicationContext context = new 
                ClassPathXmlApplicationContext("application.xml");
        CustomerDAO dao = (CustomerDAO) context.getBean("customerDAO");

        /*JdbcTemplate添加数据
         * Customer customer = new Customer(2,"白居易",24);
        dao.insertByJdbcTemlate(customer);*/

        /*JdbcTemplate查找数据
         * Customer customer1 = dao.findByCustomerIdByJdbcTemlate(2);
        System.out.println(customer1.toString());*/ 

        /*JdbcTemplate查找所有数据
         * List listc= dao.findAll();
        for(int i=0;i

        //测试批处理 添加数据
        Customer customer1 = new Customer(3, "王维",41);
        Customer customer2 = new Customer(4, "岑参",42);
        Customer customer3 = new Customer(6, "陶渊明",63);

        Listlists = new ArrayList();
        lists.add(customer1);
        lists.add(customer2);
        lists.add(customer3);

        dao.bathupdate(lists);
    }
    /**
     * 继承jdbcDaoSupport得到的JdbcTemplate
     */
    @Test
    public void testByjdbcDaoSupport(){
        ApplicationContext context = new 
                ClassPathXmlApplicationContext("application.xml");
        //取得bean有所不同
        CustomerDAO dao = (CustomerDAO) context.getBean("customerDAObyDaoSupport");
        /*-------------------------*/
        List listc= dao.findAll();
        Iterator it = listc.iterator();
        while(it.hasNext()){
            Customer customer = it.next();
            System.out.println(customer.toString());
        }
        /*-------------------------*/
        //Customer cu = dao.findByCustomerIdByJdbcTemlate(5);
        //System.out.println(cu.getName());
    }
}

关于批处理

这是一个JDBC批处理的方法

JdbcCustomerDaoImpl.java

.
.
@Override
public void bathUpdateByJDBC(List lists) {
        String sql = "INSERT INTO tb_customer(CUST_ID,NAME,AGE) VALUES(?,?,?)";
        Connection conn = null;
        Customer customer = null;
        try {
            conn = dataSource.getConnection();
            PreparedStatement ps = conn.prepareStatement(sql);
            for(int i=0;i1, customer.getCustId());
                ps.setString(2, customer.getName());
                ps.setInt(3, customer.getAge() );
                ps.addBatch();
            }
            int [] n = ps.executeBatch();
            /**
             * 数组的长度就是执行成功的语句条数
             * 数组内容是执行的结果,表示这条sql语句,影响了数据表,几行数据
             * 大于等于0,表示执行成功 
             * SUCCESS_NO_INFO 执行成功 受影响的行数是未知
             * EXECUTE_FAILED 执行失败
             */
            System.out.println("数组n的长度"+n.length);
            for(int i=0;icatch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
.
.

执行这个方法

.
.
    @Test
    public void testbathUpdateByJDBC() {
        ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
        CustomerDAO dao = (CustomerDAO) context.getBean("customerDAO");

        // 测试批处理 添加数据
        Customer customer1 = new Customer(8, "王维", 41);
        Customer customer2 = new Customer(9, "岑参", 42);
        Customer customer3 = new Customer(10, "陶渊明", 63);

        List lists = new ArrayList();
        lists.add(customer1);
        lists.add(customer2);
        lists.add(customer3);
        dao.bathUpdateByJDBC(lists);
    }
.
.
数组n的长度3
1
1
1

成功执行了3条添加数据的指令,每条语句影响的行数都是1

源码下载

源码下载:http://download.csdn.net/detail/peng_hong_fu/9695130

你可能感兴趣的:(架构)