Spring+JDBC 数据库实例


这里写图片描述


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

项目结构:

这里写图片描述

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

这里写图片描述

源码下载: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<Customer> findAll();//查找所有客户信息
    public void bathupdate(List<Customer> 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<Customer> findAll() {
        String sql = "SELECT * FROM tb_customer";
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        List<Customer> listCus = new ArrayList<>();
        listCus = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Customer>(Customer.class));
        return listCus;
    }
    /**
     * 使用JdbcTemplate 测试批处理
     */
    @Override
    public void bathupdate(List<Customer> 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<Customer> findAll() {
        String sql = "SELECT * FROM tb_customer";
        List<Customer> listCus = new ArrayList<>();
        /**
         * 方式一 /*List<Map<String,Object>> 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>(Customer.class));
        return listCus;
    }

    @Override
    public void bathupdate(List<Customer> 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

<?xml version="1.0" encoding="UTF-8"?>
<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"
    >
    <!-- default-autowire="byName" 在头文件上配置,说明整个bean都是按name值装配属性-->

    <bean id="customerDAO" class="com.jxust.dao.impl.JdbcCustomerDaoImpl"  autowire="byType">
        <!-- 在类中让这个属性自动装配,这里不需要配置 -->
        <!-- <property name="dataSource" ref="dataSource"></property> -->
    </bean>
    <bean id="customerDAObyDaoSupport" class="com.jxust.dao.impl.JdbcJdbcDaoSupport">
        <property name="dataSource" ref="dataSourceBean"></property>
    </bean>

</beans>

配置数据源

Spring-Datesource.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"
    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

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

    <!--这种方式只能用@Autowried  -->
<!-- <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" /> -->

<!--<context:annotation-config></context:annotation-config> -->

    <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<Customer> listc= dao.findAll();
        for(int i=0;i<listc.size();i++){
            Customer c = listc.get(i);
            System.out.println(c.toString());
        }*/

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

        List<Customer>lists = new ArrayList<Customer>();
        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<Customer> listc= dao.findAll();
        Iterator<Customer> 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<Customer> 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;i<lists.size();i++){
                customer = lists.get(i);
                ps.setLong(1, 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;i<n.length;i++){
                System.out.println(n[i]);
            }
        } catch (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<Customer> lists = new ArrayList<Customer>();
        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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值