美文网首页
6-基于Spring的框架-JDBC——6-1 引入及概述

6-基于Spring的框架-JDBC——6-1 引入及概述

作者: 鹏程1995 | 来源:发表于2020-02-25 16:38 被阅读0次

概要

过度

我们前面基本介绍完了Spring的框架实现思路,现在我们以前面介绍的知识为基础,对常用的一些基于Spring的框架进行分离,目的是从java SE加特殊业务基本框架的角度对我们工作中使用的Spring定制框架进行解读。从而摘掉企业级框架的神秘面纱。

当然,虽然我一直对常用框架有一种读源码、即知其然也知其所以然的态度,但是要明白我们要用的本就是这些工具,我们需要的是这种探究的思想、设计模式的学习以及对疑难杂症的解决思路,而不是从头另搭一套东西出来。所以,我们在接下来的框架学习中力求用Java SE加基本框架的方法进行Spring框架的解读,但是不会再继续深入。

内容简介

本文回顾了jdbc的基本使用方法,并展示了 spring-jdbc工具的使用方法。下文将以本文的代码为切入点,解析spring-jdbc的实现逻辑。

前面对Spring框架的解析我们基本都是依照《Spring源码深度解析》一书,从这里开始,我们的阅读操作仍然以此书为一些指引,但是不在完全跟着他的思路走了。

所属环节

spring-jdbc引入及概览。

上下环节

上文:Spring框架详细解析

下文:无【如果硬要安排一个的话,应该算是数据库相关框架的总结吧】

JDBC

引入

我们在大学针对数据库操作进学习了一种框架:jdbc,这个是Java操作数据库的最基本的框架了。我们在操作数据库都是依靠SQL语句的,JDBC(Java DataBase Connectivity)也是接受SQL入参,并执行链接库、查询操作。

使用示例

我们先看一下基本的jdbc使用方法:

public static void main(String args[]) throws ClassNotFoundException, SQLException {
  // 在 com.mysql.cj.jdbc.Driver 类的静态代码块中进行了DriverManager的注册。
  Class.forName("com.mysql.cj.jdbc.Driver");
  Connection connection = DriverManager.getConnection("jdbc:mysql://","","");
  Statement statement = connection.createStatement();
  ResultSet resultSet = statement.executeQuery("select * from form");
  while (resultSet.next()){
    String x= resultSet.getString(1);
    System.out.println("x="+x);
  }
  //        statement.executeUpdate();
}

基本的jdbc的操作就是这样了,当然还有很多高级操作。比如:使用DataSource数据库连接池,使用PreparedStatement提高执行速度等等。

我们先看使用数据库连接池的操作:

public static void main(String args[]) throws ClassNotFoundException, SQLException, PropertyVetoException {
        // 在 com.mysql.cj.jdbc.Driver 类的静态代码块中进行了DriverManager的注册。
        ComboPooledDataSource ds = new ComboPooledDataSource();
        ds.setUser("");
        ds.setPassword("");
        ds.setDriverClass("com.mysql.cj.jdbc.Driver");
        ds.setJdbcUrl("jdbc:mysql://");
        ds.setInitialPoolSize(3);
        ds.setMaxPoolSize(10);
        ds.setMaxStatements(100);
        ds.setAcquireIncrement(2);

        Statement statement = ds.getConnection().createStatement();
        ResultSet resultSet = statement.executeQuery("select * from form");
        while (resultSet.next()){
            String x= resultSet.getString(1);
            System.out.println("x="+x);
        }
    }

接下来是使用PreparedStatement的操作:

public static void main(String args[]) throws ClassNotFoundException, SQLException {
  // 在 com.mysql.cj.jdbc.Driver 类的静态代码块中进行了DriverManager的注册。
  Class.forName("com.mysql.cj.jdbc.Driver");
  Connection connection = DriverManager.getConnection("jdbc:mysql://","","");
  PreparedStatement statement = connection.prepareStatement("select * from form");
  ResultSet resultSet = statement.executeQuery();
  while (resultSet.next()){
    String x= resultSet.getString(1);
    System.out.println("x="+x);
  }
}

总结

上面的所有操作其实思路都是相似的:

  1. 加载JDBC驱动
  2. 设置数据库相关信息【url、用户名、密码等等】
  3. 获得Connection
  4. 获得Statement
  5. 传入sql,获得执行结果

Spring JDBC

引入

上面进行了一些总结,我们很容易发现整体思路都差不多:

  • 其中1、2是一劳永逸的,这种设置在项目中不会变化
  • 3、4可以根据线程及其他的一些信息(例如事务)进行托管,以高效、合理的完成实现
  • 5和业务逻辑密切相关,涉及查询方式及数据转化,无法简化

所以,我们猜测Spring做的事应该分成两类:

  1. 对 JDBC驱动的加载、数据库的配置进行全局化设置:一次设置,多处复用。
  2. 接管ConnectionStatement的创建工作

我们使用Spring JDBC后只需要关注要执行的sql和结果映射即可。

使用示例

我们用最基本的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">

  <!-- 1、声明数据源对象:C3P0连接池 -->
  <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <!-- 加载jdbc驱动 -->
    <property name="driverClass" value="com.mysql.cj.jdbc.Driver"/>
    <!-- jdbc连接地址 -->
    <property name="jdbcUrl" value="jdbc:mysql://"/>
    <!-- 连接数据库的用户名 -->
    <property name="user" value=""/>
    <!-- 连接数据库的密码 -->
    <property name="password" value=""/>
    <!-- 数据库的初始化连接数 -->
    <property name="initialPoolSize" value="3"/>
    <!-- 数据库的最大连接数 -->
    <property name="maxPoolSize" value="10"/>
    <!-- 数据库最多执行的事务 -->
    <property name="maxStatements" value="100"/>
    <!-- 连接数量不够时每次的增量 -->
    <property name="acquireIncrement" value="2"/>
  </bean>

  <!--  创建jdbcTemplate对象 -->
  <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"/>
  </bean>

  <bean id="userTemplate" class="UserTemplate" >
    <property name="jdbcTemplate" ref="jdbcTemplate"/>
  </bean>
</beans>

以上是所有的xml配置,其中:

  • 创建DataSource相关的配置实现了我们说的第一点——对 JDBC驱动的加载、数据库的配置进行全局化设置:一次设置,多处复用
  • 在我们的数据库增删改查操作和DataSource之间多了一层JdbcTemplate,猜测应该是这里进行了一些ConnectorStatement的封装工作。

我们继续看UserTemplate的Java代码:

public Long saveUser(User user){
  String sql = "INSERT INTO learn.form (creator, is_deleted, modifier, business_id, form_name, template_id, creation_code) VALUES (?,?,?,?,?,?,?)";
  KeyHolder keyHolder = new GeneratedKeyHolder();
  int result =  jdbcTemplate.update(
    new PreparedStatementCreator() {
      public PreparedStatement createPreparedStatement(Connection con) throws SQLException
      {
        PreparedStatement ps = getJdbcTemplate().getDataSource()
          .getConnection().prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
        ps.setString(1,user.getCreator());
        ps.setBoolean(2,user.isDeleted());
        ps.setString(3,user.getModifier());
        ps.setLong(4,user.getBusinessId());
        ps.setString(5,user.getFormName());
        ps.setLong(6,user.getTemplateId());
        ps.setString(7,user.getCreationCode());
        return ps;
      }
    }, keyHolder);
  if (result != 0){
    System.out.println("插入数据成功");
    return keyHolder.getKey().longValue();
  }
  return null;
}

public List<User> getByCreator(String creator){
  return jdbcTemplate.query("select * from form where creator = '"+creator+"'",new UserRowMapper());

我们很容易发现查询、修改(包括插入、删除)操作都依赖于JdbcTemplate的对应函数。我们在自己的代码中主要关注:

  1. SQL语句的构建操作
  2. 修改操作返回结果的带出设置
  3. 查询结果到POJO的映射

其中2、3都是各自的特殊属性,1是共通的属性。

总结

我们上面记录了对JdbcTemplate的使用方法,后面主要关注的是就是其中对ConnectionStatement的管理。

扩展

问题遗留

参考文献

相关文章

网友评论

      本文标题:6-基于Spring的框架-JDBC——6-1 引入及概述

      本文链接:https://www.haomeiwen.com/subject/cyfxchtx.html