spring 数据库操作之JDBC(05)

Spring JDBC模板

一. 单独使用jdbc

Java Database Connectivity(JDBC) 是Java api标准的一部分.是用来Java开发语言和多数数据库交换.JDBC是编程接口,供Java开发者用来访问数据库.JDBC提供了很多方法用来查询,更新,和删除数据库数据,JDBC库主要提供的接口使用步骤

  1. 创建数据库链接
  2. 创建SQL声明
  3. 执行SQL语句
  4. 查看或者数据结果集
  5. 关闭链接

下面是一个使用JDBC操作数据库的简单例子

创建数据库spring_jdbc和表employee

create table employee(
    id int primary key auto_increment,
    name varchar(32)
);

创建Java工程,导入连接MySQL的jar包:mysql-connector-java-5.1.7-bin.jar

Entity:

Employee.java

package com.it.entity;

public class Employee {
    private int id;
    private String name;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Employee(int id, String name) {
        super();
        this.id = id;
        this.name = name;
    }
    
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return this.id+"==>"+this.name;
    }
}

接口EmployeeDao.java

package com.it.dao;

import java.io.Serializable;
import com.it.entity.Employee;

public interface EmployeeDao {
    Employee getEmployeeById(Serializable id);
    //void createEmployee();
    void insertEmployee(Employee employee);
}

接口EmployeeDao的实现类:EmployeeDaoImpl.java

package com.it.dao.impl;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import com.it.dao.EmployeeDao;
import com.it.entity.Employee;

public class EmployeeDaoImpl implements EmployeeDao{
    private String url = "jdbc:mysql://localhost:3306/spring_jdbc?useUnicode=true&characterEncoding=utf-8";
    private String user = "root";
    private String password = "1l9o9v0e";
    private String className = "com.mysql.jdbc.Driver";
    
    @Override
    public Employee getEmployeeById(Serializable id) {
        // TODO Auto-generated method stub
        Connection connection = null;
        Employee employee = null;
        
        try {
            Class.forName(className);
            connection = DriverManager.getConnection(url, user, password);
            PreparedStatement statement = connection.prepareStatement(""
                    + "select id,name from employee where id=?");
            statement.setInt(1, (int) id);
            ResultSet rs = statement.executeQuery();
            if (rs.next()) {
                employee = new Employee(rs.getInt("id"), rs.getString("name"));
            }
            rs.close();
            statement.close();
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally {
            if (connection!=null) {
                try {
                    connection.close();
                } catch (Exception e2) {
                    // TODO: handle exception
                    throw new RuntimeException(e2);
                }
            }
        }
        
        return employee;
    }

    @Override
    public void insertEmployee(Employee employee) {
        // TODO Auto-generated method stub
        Connection connection = null;
        try {
            
            Class.forName(className);
            connection = DriverManager.getConnection(url, user, password);
            PreparedStatement statement = connection.prepareStatement("insert into employee(name) values(?)");
            
            statement.setString(1, employee.getName());
            statement.execute();
                    
            statement.close();
            
        } catch (Exception e) {
            // TODO: handle exception
            throw new RuntimeException(e);
        }finally {
            if (connection!=null) {
                try {
                    connection.close();
                } catch (Exception e2) {
                    // TODO: handle exception
                    throw new RuntimeException(e2);
                }
            }
        }
    }

}

测试JDBC操作数据库:JdbcDemo.java

package com.it.a_jdbc;

import org.junit.Test;

import com.it.dao.EmployeeDao;
import com.it.dao.impl.EmployeeDaoImpl;
import com.it.entity.Employee;

public class JdbcDemo {

    private EmployeeDao employeeDao = new EmployeeDaoImpl();
    
    @Test
    public void testJdbcInsert() {
        Employee employee = new Employee(2, "大佬");
        employeeDao.insertEmployee(employee);
        System.out.println("insert success!");
    }
    
    @Test
    public void testJdbcGet() {
        Employee emp = employeeDao.getEmployeeById(1);
        System.out.println(emp);
    
    }
    
}

运行测试方法,数据库会增加近name='大佬'的数据,同样可以获取ID为1的数据

二. Spring 对JDBC的支持

在前面的小例子,我们没有引入spring相关的方法,实现了一个Java类进行DAO操作:使用JDBC连接到数据库,进行数据操作.在下面的内容,将会学习spring框架通过去除重复代码,让我们的工作更加简单.

使用 spring JdbcTemplate查找数据库

2.1 引入spring-JDBC相关jar包

c3p0-0.9.1.2.jar
commons-logging-1.1.3.jar
mysql-connector-java-5.1.7-bin.jar
spring-aop-4.1.6.RELEASE.jar
spring-aspects-4.1.6.RELEASE.jar
spring-beans-4.1.6.RELEASE.jar
spring-context-4.1.6.RELEASE.jar
spring-core-4.1.6.RELEASE.jar
spring-expression-4.1.6.RELEASE.jar
spring-jdbc-4.1.6.RELEASE.jar
spring-tx-4.1.6.RELEASE.jar

2.2 src目录下创建bean.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:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    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/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">
        
        
        
        <!-- 数据源对象:c3p0连接池 -->
        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
            <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
            <property name="jdbcUrl" value="jdbc:mysql:///spring_jdbc?useUnicode=true&characterEncoding=utf8"></property>
            <property name="user" value="root"></property>
            <property name="password" value="1l9o9v0e"></property>
            <property name="initialPoolSize" value="3"></property>
            <property name="maxPoolSize" value="10"></property>
            <property name="maxStatements" value="100"></property>
            <property name="acquireIncrement" value="2"></property>
        
        </bean>
        
        
        <!-- jdbcTemplate工具类实例 -->
        <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
        
        <bean id="userDao" class="com.it.dao.impl.UserDaoImpl">
            <property name="jdbcTemplate" ref="jdbcTemplate"></property>
        </bean>
        
        
</beans>

2.3 相关类的主要代码

创建Entity类:User.java

package com.it.entity;

public class User {
    private int id;
    private String name;
    private int age;
    
    public void setAge(int age) {
        this.age = age;
    }
    
    public int getAge() {
        return age;
    }
    
    public User() {
        // TODO Auto-generated constructor stub
        super();
    }
    
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public User(int id, String name,int age) {
        super();
        this.id = id;
        this.name = name;
        this.age = age;
    }
    
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return "id:"+this.id+"==>:name"+this.name+"==>age:"+this.age;
    }
}

接口 UserDao.java

package com.it.dao;

import com.it.entity.User;

public interface UserDao {
    //根据ID获取用户
    User getUserById(int id);
    //插入数据
    int insertUser(User user);
    //删除用户
    int deleteUserById(int id);
    //获取用户数量
    int getUserCount();
    //更新用户
    void updateUser(User user);
    
}

UserDao的实现,UserDaoImpl.java

package com.it.dao.impl;

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

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

import com.it.dao.UserDao;
import com.it.entity.User;

public class UserDaoImpl implements UserDao{

    private JdbcTemplate jdbcTemplate;
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
    //user_t
    @Override
    public User getUserById(int id) {
        // TODO Auto-generated method stub
        String sql = "select id,name,age from user_t where id=?";
        return jdbcTemplate.queryForObject(sql, new MyMapper(),id);
    }

    @Override
    public int insertUser(User user) {
        // TODO Auto-generated method stub
        String sql = "insert into user_t(name,age) values(?,?)";
        int affect = jdbcTemplate.update(sql, user.getName(),user.getAge());
        return affect;
    }

    @Override
    public int deleteUserById(int id) {
        String delQuery = "delete from user_t where id = ?";
        return jdbcTemplate.update(delQuery, new Object[] { id });
    }

    @Override
    public int getUserCount() {
        // TODO Auto-generated method stub
        String sql = "select count(id) from user_t";
        
        return jdbcTemplate.queryForObject(sql, null, Integer.class);
    }

    @Override
    public void updateUser(User user) {
        // TODO Auto-generated method stub
        User user2 = this.getUserById(user.getId());
        if (user2!=null) {
            String sql = "update user_t set name=?,age=? where id=?";
            jdbcTemplate.update(sql, user.getName(),user.getAge(),user.getId());
        }
    }
    
    
    public void insertUsers(final List<User> users) {
        String sql = "insert into user_t(name,age) values(?,?)";
        
        jdbcTemplate.batchUpdate(sql,
                new BatchPreparedStatementSetter() {
                    
                    @Override
                    public void setValues(PreparedStatement statement, int i) throws SQLException {
                        // TODO Auto-generated method stub
                        User user = users.get(i);
                        statement.setString(1, user.getName());
                        statement.setInt(2, user.getAge());
                        
                    }
                    
                    @Override
                    public int getBatchSize() {
                        // TODO Auto-generated method stub
                        return users.size();
                    }
                }
            );
    }
    
    public void batchUpdate() {
        jdbcTemplate.batchUpdate(new String[]{
                "update user_t set age=100 where id=5",
                "update user_t set age=100 where id=6",
                "update user_t set age=100 where id=7"
        });
    }
    
    class MyMapper implements RowMapper<User>{

        @Override
        public User mapRow(ResultSet rs, int index) throws SQLException {
            // TODO Auto-generated method stub
            User user = new User(rs.getInt("id"),rs.getString("name"), rs.getInt("age"));
            return user;
        }
    }
}

测试类:测试spring JDBCTemplate简单的CRUD

JdbcTemplateDemo.java

package com.it.b_jdbc_template;

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

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

import com.it.dao.UserDao;
import com.it.dao.impl.UserDaoImpl;
import com.it.entity.User;

public class JdbcTemplateDemo {
    
    private ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
    
    @Test
    public void getUserById() {
        UserDao userDao = (UserDao) ac.getBean("userDao");
        User user = userDao.getUserById(1);
        System.out.println(user);
    } 
    
    @Test
    public void insertUser(){
        UserDao userDao = (UserDao) ac.getBean("userDao");
        User user = new User(3, "小爱", 12);
        int count = userDao.insertUser(user);
        System.out.println("插入成功!:"+count);
    
    }
    
    @Test
    public void deleteUserById(){
        UserDao userDao = (UserDao) ac.getBean("userDao");
        int index = userDao.deleteUserById(2);
        System.out.println("删除成功!:"+index);
    }
    
    @Test
    public void getUserCount(){
        UserDao userDao = (UserDao) ac.getBean("userDao");
        int userCount = userDao.getUserCount();
        System.out.println("总的用户个数: "+userCount);
    }
    
    @Test
    public void updateUser(){
        UserDao userDao = (UserDao) ac.getBean("userDao");
        User user = new User(1, "大兵", 44);
        userDao.updateUser(user);
        System.out.println("更新成功: "+user.toString());
        
    }
    
    @Test
    public void batchOperation() {
        List<User> list = new ArrayList<>();
        for(int i = 0;i<10;i++){
            User user = new User(i+5, "Rose"+i+1, i+23);
            list.add(user);
        }
        
        UserDaoImpl userDao = (UserDaoImpl) ac.getBean("userDao");
        userDao.insertUsers(list);
        int userCount = userDao.getUserCount();
        System.out.println("总的用户数量: "+userCount);
    }
    
    @Test
    public void batchUpdate() {
        UserDaoImpl userDao = (UserDaoImpl) ac.getBean("userDao");
        userDao.batchUpdate();
        
    }
}

2.4 spring JDBC的批处理操作

批处理:单个可执行的操作单元组成的多步操作.如果需要进行多次同样的操作,JDBC驱动会表现更加流畅.此外,如果多个更新操作处理,可以限制运行的操作数量.

通常来说,运行程序的服务器和数据库服务器不在同一个位置.假设现在需要执行100次执行语句,
通常来说,我们会在程序将查询语句逐条的发送到数据库服务器并执行.这样,我们必须通过网络将查询语句发送到数据库服务器.这样会导致交流成本的消耗降低性能.所以,为了挺高性能和减少交流的消耗,使用JDBC的批处理操作.

批处理操作允许我们一次性提交多个SQL语句到服务器.JDBCTemplate支持JDBC 多个statement
或者多个prepareStatement的操作

jdbcTemplate有两个重载batchUpdate()方法

  • 一个方法是执行多个JDBC statement语句 : public int[] batchUpdate(String[] sql) throws DataAccessException

比如:

jdbcTemplate.batchUpdate (new String [] {
"update emp set salary = salary * 1.5 where empId = 10101",
"update emp set salary = salary * 1.2 where empId = 10231", "update dept set location = 'Bangalore' where deptNo = 304"
});
  • 另外一个方法是执行SQL statement语句多次,可以有不同的参数,使用preparestatement语句

public int[] batchUpdate(String sql, BatchPreparedStatementSetter bPSS) throws DataAccessException

主要例子看 UserDaoImpl.java的两个方法


    public void insertUsers(final List<User> users) {
        String sql = "insert into user_t(name,age) values(?,?)";
        
        jdbcTemplate.batchUpdate(sql,
                new BatchPreparedStatementSetter() {
                    
                    @Override
                    public void setValues(PreparedStatement statement, int i) throws SQLException {
                        // TODO Auto-generated method stub
                        User user = users.get(i);
                        statement.setString(1, user.getName());
                        statement.setInt(2, user.getAge());
                        
                    }
                    
                    @Override
                    public int getBatchSize() {
                        // TODO Auto-generated method stub
                        return users.size();
                    }
                }
            );
    }
    
    public void batchUpdate() {
        jdbcTemplate.batchUpdate(new String[]{
                "update user_t set age=100 where id=5",
                "update user_t set age=100 where id=6",
                "update user_t set age=100 where id=7"
        });
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容

  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,733评论 6 342
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,594评论 18 139
  • 主要内容 定义Spring的数据访问支持 配置数据库资源 使用Spring提供的JDBC模板 写在前面:经过上一篇...
    程序熊大阅读 8,744评论 1 31
  • 《北京折叠》火了一段时间了。赶紧找来看看,说实话有点失望。 同样是获得雨果奖,与“三体”没法比。 当然,它是短篇小...
    德万托阿阅读 1,547评论 0 4
  • 今天一直在想写什么好呢,刚才突然想到周末两天是可以休息不写的,那么我可以写一下休息。 今天没什么特别的安排,老大不...
    by_10阅读 223评论 0 0