JDBC框架和Spring JDBCTemplate

目录

一、关于JDBC

1、JDBC简介

2、JDBC接口

3、JDBC原理及工作流程

1、加载JDBC驱动程序

2、提供JDBC连接的URL

3、创建数据库的连接

4、创建一个Statement

5、执行SQL语句

6、处理结果

7、关闭JDBC对象

二、Spring JDBC框架

1、JDBCTemplate介绍

2、使用JDBCTemplate操作数据库

三、存储过程

存储过程的优点

存储过程的缺点

使用建议


一、关于JDBC

1、JDBC简介

JDBC(Java DataBase Connectivity)可以让我们用相同的方式访问不同的数据库,它定义了一套标准的接口,即访问数据库的通用API。它是sun公司开发的一套数据库访问编程接口,由java语言编写完成。不同的数据库厂商根据自己数据库的特性去实现JDBC提供的这套接口。
        JDBC具有很好的跨平台特性,使用JDBC编写的数据库应用程序可以在任何支持java的平台上运行,所以不必在不同的平台上去编写不同的应用程序。

2、JDBC接口

首先,JDBC接口分为四类

        1:DriverManager:驱动管理接口

        2:Connection,DatabaseMetaData:链接接口

        3:Statement,PreparedStatement,CallableStatement:语句对象接口(用于执行SQL语句)

        4:ResultSet,ResultSetMetaData:结果集合接口(执行select语句的结果)

DriverManager:管理一组JDBC驱动程序的基本服务,我们通过DriverManager来获取Connection。

Connection:通过驱动器DriverManager获取,用来获取Statement

Statement:用于执行SQL语句

ResultSet:在执行查询语句时的返回集接口

3、JDBC原理及工作流程

1、加载JDBC驱动程序

在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机),这通过java.lang.Class类的静态方法forName(String className)实现。成功加载之后,会将Driver类的实例注册到DriverManager类中。

2、提供JDBC连接的URL

连接URL定义了连接数据库时的协议、子协议、数据源标识,
其书写格式:协议子协议数据源标识   

String url="jdbc:mysql://localhost:3306/springtemplate

    协议:在JDBC中总是以jdbc开始   
    子协议:是桥连接的驱动程序或是数据库管理系统名称   
    数据源标识:标记找到数据库来源的地址与连接端口 

3、创建数据库的连接

(1)要连接数据库,需要向java.sql.DriverManager请求并获得Connection对象,该对象就代表一个数据库的连接。   
(2)使用DriverManager的getConnectin(String url , String username , String password )方法传入指定的欲连接的数据库的路径、数据库的用户名和密码来获得。

4、创建一个Statement

要执行SQL语句,必须获得java.sql.Statement实例,Statement实例分为以下3种类型:   
(1)执行静态SQL语句。通常通过Statement实例实现
(2)执行动态SQL语句。通常通过PreparedStatement实例实现
(3)执行数据库存储过程。通常通过CallableStatement实例实现  

5、执行SQL语句

Statement接口提供了三种执行SQL语句的方法:executeQuery 、executeUpdate和execute   
(1)ResultSet executeQuery(String sqlString):执行查询数据库的SQL语句,返回一个结果集(ResultSet)对象。   
(2)int executeUpdate(String sqlString):用于执行INSERT、UPDATE或DELETE语句以及SQL DDL语句,如:CREATE TABLE和DROP TABLE等   
(3)execute(sqlString):用于执行返回多个结果集、多个更新计数或二者组合的语句。

6、处理结果

此处分为两种情况:

(1)执行更新返回的是本次操作影响到的记录数

(2)执行查询返回的结果是一个ResultSet对象

        ResultSet包含符合SQL查询语句中条件的所有行,并且它通过一套get方法提供了对这些行中数据的访问。

7、关闭JDBC对象

操作完成以后要把所有使用的JDBC对象全都关闭,以释放JDBC资源,关闭顺序和声明顺序相反:   

(1)关闭记录集   

(2)关闭声明   

(3)关闭连接对象 

完整的JDBC操作数据库代码示例:

public class JDBCDemo {
    public static void main(String[] args) {
        String url="jdbc:mysql://localhost:3306/springtemplate?useUnicode=true&characterEncoding=utf-8";
        String username = "root";
        String password = "root";
        String sql = "select * from Student";
        try {
            // 1、加载JDBC驱动程序
            Class.forName("com.mysql.jdbc.Driver");
            // 2、提供JDBC连接的URL 3、创建数据库的连接(数据库连接、账号、密码)
            Connection connection = DriverManager.getConnection(url, username, password);
            // 4、创建一个Statement(执行SQL平台)
            Statement statement = connection.createStatement();
            // 5、执行SQL语句
            ResultSet rs = statement.executeQuery(sql);
            // 6、处理执行结果
            while(rs.next()){
                System.out.println(rs.getString("name"));
            }
            // 7、关闭连接
            rs.close();
            statement.close();
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

二、Spring JDBC框架

1、JDBCTemplate介绍

JDBC已经能够满足大部分用户最基本的需求,但是在使用JDBC时,必须自己来管理数据库资源如:获取PreparedStatement,设置SQL语句参数,关闭连接等步骤。
JDBCTemplate就是Spring对JDBC的封装,目的是使JDBC更加易于使用。
JDBCTemplate是Spring的一部分。,JDBCTemplate处理了资源的建立和释放。他帮助我们避免一些常见的错误,比如忘了总要关闭连接。

在数据库已经连接和JdbcTemplate对象已经注入的情况下,使用JdbcTemplate编程我们只需两步:

1、提供SQL语句和占位符的值
2、得到封装好的查询结果集

JdbcTemplate主要提供以下五类方法:

  1. execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;
  2. update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;
  3. batchUpdate方法用于执行批处理相关语句;
  4. query方法及queryForXXX方法:用于执行查询相关语句;
  5. call方法:用于执行存储过程、函数相关语句。

2、使用JDBCTemplate操作数据库

(1)建立实体类Student.java

public class Student {
    private Integer age;
    private String name;
    private Integer id;

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public Integer getId() {
        return id;
    }

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

(2)使用XML文件加载数据库配置和注入JDBCTemplate对象

<?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-3.0.xsd ">

    <!-- Initialization for data source -->
    <bean id="dataSource"
          class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/springtemplate"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>

    <!-- Definition for studentJDBCTemplate bean -->
    <bean id="JDBCTemplate"
          class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource"  ref="dataSource" />
    </bean>

</beans>

(3)操作数据库

public class JDBCTemplateDemo {
    public static void main(String[] args) {
        // 解析配置文件
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
        // 获取模板对象
        JdbcTemplate template = (JdbcTemplate) context.getBean("JDBCTemplate");

        /**
         * 执行 INSERT,UPDATE,DELETE
         */
        String sqlUpdate = "update student set name = ? where id = ?";
        template.update(sqlUpdate,"Bob",3);

        /**
         * 测试批量更新操作
         * 最后一个参数是 Object[] 的 List 类型:因为修改一条记录需要一个 Object 数组,
         * 修改多条记录就需要一个 List 来存放多个数组。
         */
        String batchSql = "insert into student(id, name, age) values(?,?,?)";
        List<Object[]> batchArgs = new ArrayList<>();
        batchArgs.add(new Object[]{4, "Lucy", 22});
        batchArgs.add(new Object[]{5, "bb", 25});
        batchArgs.add(new Object[]{6, "com", 30});
        template.batchUpdate(batchSql,batchArgs);

        /**
         * 从数据库中获取一条记录,实际得到对应的一个对象
         * 注意:不是调用 queryForObject(String sql, Class<Employee> requiredType, Object... args) 方法!
         * 而需要调用 queryForObject(String sql, RowMapper<Employee> rowMapper, Object... args)
         * 1、其中的 RowMapper 指定如何去映射结果集的行,常用的实现类为 BeanPropertyRowMapper
         * 2、使用 SQL中的列的别名完成列名和类的属性名的映射,例如 name age
         * 3、不支持级联属性。 JdbcTemplate 只能作为一个 JDBC 的小工具, 而不是 ORM 框架
         */
        String querySql = "select * from student where id = ?";
        // 指定如何去映射结果集的行
        RowMapper<Student> rowMapper = new BeanPropertyRowMapper<>(Student.class);
        List<Student> query = template.query(querySql, rowMapper,5);
        query.stream().forEach(x-> System.out.println(x.getName()));

        /**
         * 获取单个列的值或做统计查询
         * 使用 queryForObject(String sql, Class<Long> requiredType)
         */
        String countSql = "select count(*) from student";
        Long aLong = template.queryForObject(countSql, Long.class);
    }
}

总结:JdbcTemplate是Spring框架自带的对JDBC操作的封装,目的是提供统一的模板方法使对数据库的操作更加方便、友好,效率也不错。但是功能还是不够强大(比如不支持级联属性),在实际应用中还需要和hibernate、mybaties等框架混合使用

三、存储过程

存储过程(Stored Procedure)是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象。

存储过程是为了完成特定功能的SQL语句集,经编译创建并保存在数据库中,用户可通过指定存储过程的名字并给定参数(需要时)来调用执行。

存储过程思想上很简单,就是数据库 SQL 语言层面的代码封装与重用。

存储过程的优点

1. 运行速度:对于很简单的sql,存储过程没有什么优势。对于复杂的业务逻辑,因为在存储过程创建的时候,数据库已经对其进行了一次解析和优化。存储过程一旦执行,在内存中就会保留一份这个存储过程,这样下次再执行同样的存储过程时,可以从内存中直接调用,所以执行速度会比普通sql快。    

2.  减少网络传输:存储过程直接就在数据库服务器上跑,所有的数据访问都在数据库服务器内部进行,不需要传输数据到其它服务器,所以会减少一定的网络传输。但是在存储过程中没有多次数据交互,那么实际上网络传输量和直接sql是一样的。而且我们的应用服务器通常与数据库是在同一内网,大数据的访问的瓶颈会是硬盘的速度,而不是网速。

3. 可维护性:的存储过程有些时候比程序更容易维护,这是因为可以实时更新DB端的存储过程。有些bug,直接改存储过程里的业务逻辑,就搞定了。 

4. 增强安全性:提高代码安全,防止 SQL注入。这一点sql语句也可以做到。

5. 可扩展性:应用程序和数据库操作分开,独立进行,而不是相互在一起。方便以后的扩展和DBA维护优化。

存储过程的缺点

1. SQL本身是一种结构化查询语言,但不是面向对象的的,本质上还是过程化的语言,面对复杂的业务逻辑,过程化的处理会很吃力。同时SQL擅长的是数据查询而非业务逻辑的处理,如果如果把业务逻辑全放在存储过程里面,违背了这一原则。

2. 如果需要对输入存储过程的参数进行更改,或者要更改由其返回的数据,则您仍需要更新程序集中的代码以添加参数、更新调用,等等,这时候估计会比较繁琐了。

3. 开发调试复杂,由于IDE的问题,存储过程的开发调试要比一般程序困难。     

4. 没办法应用缓存。虽然有全局临时表之类的方法可以做缓存,但同样加重了数据库的负担。如果缓存并发严重,经常要加锁,那效率实在堪忧。

5. 不支持群集,数据库服务器无法水平扩展,或者数据库的切割(水平或垂直切割)。数据库切割之后,存储过程并不清楚数据存储在哪个数据库中。

使用建议

1. 适当的使用存储过程,能够提高我们SQL查询的性能,

2. 存储过程不应该大规模使用,滥用。

3. 随着众多ORM 的出现,存储过程很多优势已经不明显。

4. SQL最大的缺点还是SQL语言本身的局限性——SQL本身是一种结构化查询语言,我们不应该用存储过程处理复杂的业务逻辑——让SQL回归它“结构化查询语言”的功用。复杂的业务逻辑,还是交给代码去处理吧。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

swadian2008

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值