Spring声明式事务基础_JdbcTemplate

Spring_JdbcTemplate

关注公众号“小东方不败”,码字不易!

Spring的学习主要分为3大块:IOC(包括DI),AOP,声明式事务。

本篇主要记录声明式事务的基础:【Spring框架本身】连接数据库相关的操作。

JdbcTemplatemybatis很像,但是性能和SQL解耦方面还是有很大区别的。

Spring整合mybatis在技术实现上来说,是必要的。但是对于JdbcTemplate的学习,作为学习Spring框架学习的补充,也是必要的。

0x01_JdbcTemplate介绍

JdbcTemplatespring框架中提供的一个对象,是对原始繁琐的Jdbc API对象的简单封装。spring框架为我们提供了很多的操作模板类。例如:操作关系型数据的JdbcTemplate和操作nosql数据库的RedisTemplate,操作消息队列的JmsTemplate等等。

话不多说,直接上手试试。

0x02_创建项目

创建一个新的模块:

image-20221105000634377

我目前用的IDEA版本是官网最新版。如果是2020.3版本的idea(之前我一直用这个版本,所以比较了解),只需要创建一个标准的maven项目即可,不需要选任何archetype。

创建项目完成之后,请务必确保下面的配置:

【1】maven:(最好是自己本地的maven)

image-20221105121629334

【2】maven的JDK for importer

之前因为这个出现过不可描述的问题,所以每一次我都改成自己的JDK .

image-20221105121753460

【3】在用到lombok的项目中需要勾选:Enable annotation processing

image-20221105121925077

0x03_导入依赖

<dependencies>
<!--        Spring核心容器包-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.3.23</version>
    </dependency>
<!--        Spring切面包-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>5.3.23</version>
    </dependency>
<!--        druid数据源(连接池)-->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.10</version>
    </dependency>
<!--        spring aop联盟包 包含了针对面向切面的接口。 通常Spring等其它具备动态织入功能的框架依赖此包。-->
    <dependency>
        <groupId>aopalliance</groupId>
        <artifactId>aopalliance</artifactId>
        <version>1.0</version>
    </dependency>
<!--        mysql驱动-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.30</version>
    </dependency>
<!--        SpringJDBC包-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.3.23</version>
    </dependency>
<!--        spring映射依赖-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-orm</artifactId>
        <version>5.3.23</version>
    </dependency>
<!--        apache commons日志包-->
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.2</version>
    </dependency>


    <!--        Spring事务控制包tx-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>5.3.23</version>
    </dependency>


    <!--        junit测试的依赖-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.2</version>
        <scope>test</scope>
    </dependency>
<!--        lombok  在实体类中使用注解,可以不用自己写get,set,toString,构造方法等方法-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.24</version>
        <scope>provided</scope>
    </dependency>
    
</dependencies>

注意:如果配置了阿里或者华为的镜像还是下载有问题的话,建议多install几次依赖,这个没办法。

0x04_resources目录下的配置文件

1.jdbc.properties

这个以前写过很多次,我直接拿来用了:

根据你的实际环境更改参数,比如数据库的账户名和密码,你的数据库名。

如果你的mysql版本不是8,那么下面url中的参数可能还需要你google进行更改。

jdbc_username=root
jdbc_password=root
jdbc_driver=com.mysql.cj.jdbc.Driver
jdbc_url=jdbc:mysql://127.0.0.1:3306/mydb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true

这个文件不要留多余的空格和换行。

2.applicationContext.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:c="http://www.springframework.org/schema/c"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/util
       http://www.springframework.org/schema/util/spring-util.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
">
<!--    Spring注解扫描-->
    <context:component-scan base-package="com.bones"/>
<!--    读取properties的配置-->
    <context:property-placeholder location="classpath:jdbc.properties"/>
<!--    配置druid数据源(连接池)-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="url" value="${jdbc_url}"/>
        <property name="username" value="${jdbc_username}"/>
        <property name="password" value="${jdbc_password}"/>
        <property name="driverClassName" value="${jdbc_driver}"/>
    </bean>
<!--    配置JdbcTemplate对象,并向里面注入DataSource对象(druid)-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--        通过set方法注入druid数据源-->
        <property name="dataSource" ref="dataSource"/>
    </bean>
</beans>

注:

上面的最后是注入JdbcTemplate对象,其中需要配置druid数据源(连接池),即配置初始化JdbcTemplate对象时,需要的DataSource对象:

什么意思呢?看一下JdbcTemplate类的一部分源码就可以理解了:

初始化JdbcTemplate,会走构造方法,这点毋庸置疑吧:

	public JdbcTemplate(DataSource dataSource) {
		setDataSource(dataSource);
		afterPropertiesSet();
	}

走构造方法的第一步就是设置数据源setDataSource(dataSource);,所以要将druid数据源设置为JdbcTemplate的数据源,则只需要调用set方法,所以就有了:

<property name="dataSource" ref="dataSource"/>

0x05_搭建项目结构

数据库表的创建

由于sql文件比较大,可以去github下载:https://github.com/kirsten-1/sqlFile/blob/main/mydb.sql

实体类

com.bones.pojo.Emp

package com.bones.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.Date;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Emp implements Serializable {
    private Integer empno;
    private String ename;
    private String job;
    private Integer mgr;//上级的员工编号
    private Date hiredate;
    private Double sal;
    private Double comm;//补助金
    private Integer deptno;//部门编号
}

dao层

com.bones.dao.EmpDaocom.bones.dao.impl.EmpDaoImpl

EmpDao

package com.bones.dao;

import org.springframework.stereoty

EmpDaoImpl

package com.bones.dao.impl;

import com.bones.dao.EmpDao;
import org.springframework.stereotype.Repository;

@Repository
public class EmpDaoImpl implements EmpDao {
}

service层

com.bones.service.EmpServicecom.bones.service.impl.EmpServiceImpl

EmpService

package com.bones.service;

public interface EmpService {
}

EmpServiceImpl

package com.bones.service.impl;

import com.bones.service.EmpService;
import org.springframework.stereotype.Service;

@Service
public class EmpServiceImpl implements EmpService {

}

目前的项目结构是 :

image-20221105140443825

0x06_JdbcTemplate查询操作

实验1:查询返回值类型为int

EmpService接口:

int findEmpcount();

EmpServiceImpl实现类:

@Autowired
private EmpDao empDao;

@Override
public int findEmpcount() {
    return empDao.findEmpcount();
}

EmpDao接口:

 int findEmpcount();

EmpDaoImpl实现类

@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public int findEmpcount() {
    /** jdbcTemplate.queryForObject
     *  查询的返回值类型是int数字类型
     *  传入参数有2个
     *  第一个参数:sql语句
     *  第二个参数:返回值类型的class字节码文件
     */
    String sql = "select count(1) from emp";
    int count = jdbcTemplate.queryForObject(sql, Integer.class);
    return count;
}

测试:

/**
 * 对于JdbcTemplate的各种查询操作进行测试
 */
@Test
public void testJdbcTemplateQuery(){
    //获取容器
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    EmpServiceImpl empService = context.getBean(EmpServiceImpl.class);
    int empcount = empService.findEmpcount();
    System.out.println("empcount = " + empcount);
}

测试结果:

image-20221105141617245

注意JdbcTemplate的 API:

如果是查询结果的返回值类型是普通的基本数据类型:

int count = jdbcTemplate.queryForObject(sql, Integer.class);
  • 第一个参数:查询的sql语句
  • 第二个参数:返回值类型的class字节码文件
  • 还要注意Autowired一个JdbcTemplate对象(已经在applicationContext.xml文件中注入了这个对象)
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--        通过set方法注入druid数据源-->
    <property name="dataSource" ref="dataSource"/>
</bean>

实验2:查询返回值类型是单个的实体类对象:

现在根据员工表的员工编号查询单个的emp:

EmpService接口:

Emp findEmpByEmpno(int empno);

EmpServiceImpl实现类:

@Autowired
private EmpDao empDao;
@Override
public Emp findEmpByEmpno(int empno) {
    return empDao.findEmpByEmpno(empno);
}

EmpDao接口:

Emp findEmpByEmpno(int empno);

EmpDaoImpl实现类:

@Autowired
private JdbcTemplate jdbcTemplate;

@Override
public Emp findEmpByEmpno(int empno) {
    /**
     * 查询结果是单个的实体类对象   jdbcTemplate.queryForObject
     * 第一个参数:SQL语句
     * 第二个参数:RowMapper对象,因为RowMapper是一个接口,这里用Spring提供的RowMapper的实现类BeanPropertyRowMapper
     *          需要定义泛型和实体类的字节码文件
     * 第三个参数:SQL语句中的参数,一般是传进来的
     */
    String sql = "select * from emp where empno = ?";//底层用的是preparedStatement
    BeanPropertyRowMapper<Emp> mapper = new BeanPropertyRowMapper<>(Emp.class);
    Emp emp = jdbcTemplate.queryForObject(sql, mapper, empno);
    return emp;
}

测试:

@Test
public void testJdbcTemplateQuery1(){
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    EmpServiceImpl empService = context.getBean(EmpServiceImpl.class);
    Emp emp = empService.findEmpByEmpno(7369);
    System.out.println(emp);
}

测试结果:

image-20221105143150151

注意:

关键的API

/**
     * 查询结果是单个的实体类对象   jdbcTemplate.queryForObject
     * 第一个参数:SQL语句
     * 第二个参数:RowMapper对象,因为RowMapper是一个接口,这里用Spring提供的RowMapper的实现类BeanPropertyRowMapper
     *          需要定义泛型和实体类的字节码文件
     * 第三个参数:SQL语句中的参数,一般是传进来的
     */
    String sql = "select * from emp where empno = ?";//底层用的是preparedStatement
    BeanPropertyRowMapper<Emp> mapper = new BeanPropertyRowMapper<>(Emp.class);
    Emp emp = jdbcTemplate.queryForObject(sql, mapper, empno);

其中BeanPropertyRowMapperRowMapper接口的一个实现类,是由spring提供的一个类,需要传入参数:查询结果封装的实体类的泛型和字节码文件。

实验3:查询返回值类型是List<T>

现在根据部门编号查询emp的List集合.

EmpService接口:

List<Emp> findEmpsByDeptno(int deptno);

EmpServiceImpl实现类

@Override
public List<Emp> findEmpsByDeptno(int deptno) {
    return empDao.findEmpsByDeptno(deptno);
}

EmpDao接口:

List<Emp> findEmpsByDeptno(int deptno);

EmpDaoImpl实现类

@Override
public List<Emp> findEmpsByDeptno(int deptno) {
    String sql = "select * from emp where deptno = ?";
    BeanPropertyRowMapper<Emp> mapper = new BeanPropertyRowMapper<>(Emp.class);
    List<Emp> emps = jdbcTemplate.query(sql, mapper, deptno);
    return emps;
}

测试方法:

@Test
public void testJdbcTemplateQuery2(){
    List<Emp> emps = empService.findEmpsByDeptno(10);
    emps.forEach(System.out::println);
}

测试结果:

image-20221105150423170

注意:

和查询单个的emp对象类似,也要用RoeMapper的对象:

BeanPropertyRowMapper<Emp> mapper = new BeanPropertyRowMapper<>(Emp.class);

但是用的JdbcTemplate的API是:

List<Emp> emps = jdbcTemplate.query(sql, mapper, deptno);
  • 第一个参数:SQL语句
  • 第二个参数:RowMapper对象,这里用的是Spring提供的RowMapper实现类BeanPropertyRowMapper,需要指定泛型和实体类的字节码文件。
  • 第三个参数SQL语句的需要传入的参数。

0x07_JdbcTemplate增删改操作

JdbcTemplate的增删改操作都是通过update方法完成的。

其实对于JdbcTemplate的学习建议可以CV代码,因为比较简单。

EmpService接口:

int addEmp(Emp emp);

int updateEmp(Emp emp);

int deleteEmp(int empno);

EmpServiceImpl实现类:

@Autowired
private EmpDao empDao;

@Override
public int addEmp(Emp emp) {
    return empDao.addEmp(emp);
}

@Override
public int updateEmp(Emp emp) {
    return empDao.updateEmp(emp);
}

@Override
public int deleteEmp(int empno) {
    return empDao.deleteEmp(empno);
}

EmpDao接口:

int addEmp(Emp emp);

int updateEmp(Emp emp);

int deleteEmp(int empno);

EmpDaoImpl实现类:

@Override
public int addEmp(Emp emp) {
    String sql = "insert into emp values(DEFAULT,?,?,?,?,?,?,?)";
    Object[] args = {emp.getEname(),emp.getJob(),emp.getMgr(),emp.getHiredate(),emp.getSal(),emp.getComm(),emp.getDeptno()};
    return jdbcTemplate.update(sql, args);
}

@Override
public int updateEmp(Emp emp) {
    String sql = "update emp set ename = ?,job = ?,mgr = ?,hiredate = ?,sal = ?,comm = ?,deptno = ? where empno = ?";
    Object[] args = {emp.getEname(),emp.getJob(),emp.getMgr(),emp.getHiredate(),emp.getSal(),emp.getComm(),emp.getDeptno(),emp.getEmpno()};
    return jdbcTemplate.update(sql, args);
}

@Override
public int deleteEmp(int empno) {
    String sql = "delete from emp where empno = ?";
    return jdbcTemplate.update(sql,empno);
}

测试方法:

@Test
public void testAddEmp(){
    int rows = empService.addEmp(new Emp(null, "Amy", "MANAGER", 7369, new Date(), 1900.0, 80.0, 10));
    System.out.println("rows = " + rows);
}

@Test
public void testUpdateEmp(){
    int rows = empService.updateEmp(new Emp(7941, "Jack", "SALSMAN", 7521, new Date(), 2000.0, 70.0, 20));
    System.out.println("rows = " + rows);
}

@Test
public void testDeleteEmp(){
    int rows = empService.deleteEmp(7941);
    System.out.println("rows = " + rows);
}

0x08_JdbcTemplate_批操作

批操作主要是:批量增加,批量修改,批量删除。

下面的实验记录对dept表进行批量的增删改操作。

实验

DeptService接口

package com.bones.service;

import com.bones.pojo.Dept;

import java.util.List;

public interface DeptService {
    int[] batchAdd(List<Dept> depts);

    int[] batchUpdate(List<Dept> depts);

    int[] batchDelete(List<Integer> deptnos);
}

DeptServiceImpl实现类

package com.bones.service.impl;

import com.bones.dao.DeptDao;
import com.bones.pojo.Dept;
import com.bones.service.DeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class DeptServiceImpl implements DeptService {
    @Autowired
    private DeptDao deptDao;
    @Override
    public int[] batchAdd(List<Dept> depts) {
        return deptDao.batchAdd(depts);
    }

    @Override
    public int[] batchUpdate(List<Dept> depts) {
        return deptDao.batchUpdate(depts);
    }

    @Override
    public int[] batchDelete(List<Integer> deptnos) {
        return deptDao.batchDelete(deptnos);
    }
}

DeptDao接口

package com.bones.dao;

import com.bones.pojo.Dept;

import java.util.List;

public interface DeptDao {
    int[] batchAdd(List<Dept> depts);

    int[] batchUpdate(List<Dept> depts);

    int[] batchDelete(List<Integer> deptnos);
}

DeptDaoImpl实现类

package com.bones.dao.impl;

import com.bones.dao.DeptDao;
import com.bones.pojo.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

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

@Repository
public class DeptDaoImpl implements DeptDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Override
    public int[] batchAdd(List<Dept> depts) {
        String sql = "insert into dept values(DEFAULT,?,?)";
        List<Object[]> args = new ArrayList<>();
        for (Dept dept : depts) {
            Object[] arg = {dept.getDname(),dept.getLoc()};
            args.add(arg);
        }
        return jdbcTemplate.batchUpdate(sql,args);
    }

    @Override
    public int[] batchUpdate(List<Dept> depts) {
        String sql = "update dept set dname = ?,loc = ? where deptno = ?";
        List<Object[]> args = new LinkedList<>();
        for (Dept dept : depts) {
            Object[] arg = {dept.getDname(),dept.getLoc(),dept.getDeptno()};
            args.add(arg);
        }
        return jdbcTemplate.batchUpdate(sql, args);
    }

    @Override
    public int[] batchDelete(List<Integer> deptnos) {
        String sql = "delete from dept where deptno = ?";
        List<Object[]> args = new ArrayList<>();
        for (int deptno : deptnos) {
            Object[] arg = {deptno};
            args.add(arg);
        }
        return jdbcTemplate.batchUpdate(sql,args);
    }
}

测试方法

package com.bones.test01;


import com.bones.pojo.Dept;
import com.bones.service.DeptService;
import com.bones.service.impl.DeptServiceImpl;
import com.bones.service.impl.EmpServiceImpl;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

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

public class Test2_TestJdbcTemplateBatch {
   ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
   DeptService deptService = context.getBean(DeptServiceImpl.class);
   @Test
   public void TestBatchAdd(){
      List<Dept> depts = new ArrayList<>();
      for (int i = 0; i < 5; i++) {
         depts.add(new Dept(null,"dname"+i,"loc"+i));
      }
      int[] ints = deptService.batchAdd(depts);
      System.out.println(Arrays.toString(ints));
   }

   @Test
   public void testBatchUpdate(){
      List<Dept> depts = new ArrayList<>();
      for (int i = 44; i < 50; i++) {
         depts.add(new Dept(i,"new_dname","new_loc"));
      }
      int[] ints = deptService.batchUpdate(depts);
      System.out.println(Arrays.toString(ints));
   }

   @Test
   public void testBatchDelete(){
      List<Integer> empnos = new ArrayList<>();
      for (int i = 44; i < 50; i++) {
         empnos.add(i);
      }
      int[] ints = deptService.batchDelete(empnos);
      System.out.println(Arrays.toString(ints));
   }

}

总结

对于JdbcTemplate增删改的操作都是通过API jdbcTemplate.batchUpdate(sql, args);来完成的。

看一下jdbcTemplate.batchUpdate(sql, args);的源码:

	@Override
	public int[] batchUpdate(String sql, List<Object[]> batchArgs) throws DataAccessException {
		return batchUpdate(sql, batchArgs, new int[0]);
	}

需要传入2个参数:

  • 第一个参数:sql语句
  • 第二个参数:List<Object[]>类型的对象,是对每一次操作的SQL语句中的参数封装成一个Object数组,数组中的每一个值都是SQL的?占位的参数。因为是批量操作,所以是List类型的数组。

以上就是对JdbcTemplate对于数据库的基本操作。

0x09_JdbcTemplate总结

JdbcTemplate Spring JDBC核心包(core)中的核心类,它可以通过配置文件、注解、Java 配置类等形式获取数据库的相关信息,实现了对 JDBC 开发过程中的驱动加载、连接的开启和关闭、SQL 语句的创建与执行、异常处理、事务处理、数据类型转换等操作的封装。我们只要对其传入SQL 语句和必要的参数即可轻松进行 JDBC 编程。

  • 1.Spring对数据库的操作在jdbc上面做了深层次的封装,使用spring的注入功能,可以把DataSource注册到JdbcTemplate之中。

这个就是在applicationContext.xml中配置的:

<!--    配置JdbcTemplate对象,并向里面注入DataSource对象(druid)-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--        通过set方法注入druid数据源-->
    <property name="dataSource" ref="dataSource"/>
</bean>

这里对于JdbcTemplate的配置,我用的是Druid数据源(连接池)

  • 2.JdbcTemplate主要提供以下方法:
  • query方法及queryForXXX(上面用的是queryForObject)方法:用于执行查询相关语句;

  • update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语句;

其他API:(作为了解)

方法说明
public int update(String sql)用于执行新增、更新、删除等语句;sql:需要执行的 SQL 语句;args 表示需要传入到 SQL 语句中的参数。
public int update(String sql,Object… args)
public void execute(String sql)可以执行任意 SQL,一般用于执行 DDL 语句; sql:需要执行的 SQL 语句;action 表示执行完 SQL 语句后,要调用的函数。
public T execute(String sql, PreparedStatementCallback action)
public List query(String sql, RowMapper rowMapper, @Nullable Object… args)
用于执行查询语句;sql:需要执行的 SQL 语句;rowMapper:用于确定返回的集合(List)的类型;args:表示需要传入到 SQL 语句的参数。
public T queryForObject(String sql, RowMapper rowMapper, @Nullable Object… args)
public int[] batchUpdate(String sql, List<Object[]> batchArgs, final int[] argTypes)用于批量执行新增、更新、删除等语句; sql:需要执行的 SQL 语句;argTypes:需要注入的 SQL 参数的 JDBC 类型;batchArgs:表示需要传入到 SQL 语句的参数。
  • 其他数据源:
    <!--定义数据源 Bean-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <!--数据库连接地址-->
        <property name="url" value="${jdbc.url}"/>
        <!--数据库的用户名-->
        <property name="username" value="${jdbc.username}"/>
        <!--数据库的密码-->
        <property name="password" value="${jdbc.password}"/>
        <!--数据库驱动-->
        <property name="driverClassName" value="${jdbc.driver}"/>
    </bean>

Spring 默认使用 DriverManagerDataSource 对数据库连接池进行管理,我们可以在 Spring 的 XML 配置文件中定义 DriverManagerDataSource 的 Bean,并注入到 JdbcTempate 的 Bean 中。

建议使用druid 数据源。(就像我的例子)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值