【Spring Boot 25】JdbcTemplate配置类 + 事务控制 + API简介

一、JdbcTemplate概述

​ JDBC已经能够满足大部分用户最基本的需求,但是在使用JDBC时,必须自己来管理数据库资源如:获取PreparedStatement,设置SQL语句参数,关闭连接等步骤。

​ JdbcTemplate是Spring对JDBC的封装,目的是使JDBC更加易于使用。JdbcTemplate是Spring的一部分。JdbcTemplate处理了资源的建立和释放。他帮助我们避免一些常见的错误,比如忘了总要关闭连接。他运行核心的JDBC工作流,如Statement的建立和执行,而我们只需要提供SQL语句和提取结果。

在JdbcTemplate中执行SQL语句的方法大致分为3类:

  1. execute:可以执行所有SQL语句,一般用于执行DDL语句;
  2. update:用于执行INSERT、UPDATE、DELETE等DML语句;
  3. queryXxx:用于数据查询语句;

除了JdbcTemplate,spring 框架还为我们提供了很多的操作模板类

  1. 操作关系型数据的:JdbcTemplate和HibernateTemplate。
  2. 操作 nosql 数据库的:RedisTemplate。
  3. 操作消息队列的:JmsTemplate。

二、Spring中实现jdbcTemplate对数据库操作(采用c3p0连接池)

1、src下创建属性配置文件db.properties

spring.datasource.primary.url=jdbc:mysql://localhost:3306/test
spring.datasource.primary.username=root
spring.datasource.primary.password=root
spring.datasource.primary.driver-class-name=com.mysql.jdbc.Driver

其它配置信息

 initialPoolSize:初始化连接数量
 minPoolSize:最小连接数量
 maxPoolSize:最大连接数量
 acquireIncrement: 当连接池用完之后一次性获取的连接数量
 idleConnectionTestPeriod:根据一定的时间间隔检查连接池的连接数量 单位为秒
 maxIdleTime:最大空闲时间 单位为秒
 maxStatements:最大的maxStatements连接数量
 maxStatementsPerConnection:最大语句缓存

2、配置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-4.3.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">

    <!-- 导入资源文件
        读取db.properties文件中的数据 -->
    <context:property-placeholder location="classpath:db.properties"/>

    <!-- 配置C3P0数据源 -->
    <bean id="dataSource"
        class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
        <property name="driverClass" value="${jdbc.driverClass}"></property>

        <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
        <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
    </bean>

    <!-- 配置Spring的jdbcTemplate 
        并注入一个dataSource数据源-->
    <bean id="jdbcTemplate"
        class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>    
    </bean>
</beans>

3、测试是否已经连接数据库

package com.guor.jdbctemplate;

import java.sql.SQLException;
import javax.sql.DataSource;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;

public class testJDBC {
    private JdbcTemplate jdbcTemplate;
    private ApplicationContext context = null;

    //初始化连接池
    {
        context = new ClassPathXmlApplicationContext("applicationContext.xml");
        jdbcTemplate = (JdbcTemplate) context.getBean("jdbcTemplate");
    }

    //测试是否连接数据库
    @Test
    public void testIsConnect() throws SQLException {
        DataSource dataSource = context.getBean(DataSource.class);
        System.out.println("连接成功"+dataSource.getConnection());
    }
}

三、Springboot配置jdbcTemplate的Datasource

SpringBoot配置

1、在配置文件中,写入数据库连接信息

application.properties配置如下

spring.datasource.primary.url=jdbc:mysql://localhost:3306/test
spring.datasource.primary.username=root
spring.datasource.primary.password=root
spring.datasource.primary.driver-class-name=com.mysql.jdbc.Driver

2、创建Spring配置类,定义DataSource用来读取application.properties中的配置

@Configuration
public class DataSourceConfig {
    @Bean(name = "primaryDataSource")//命名这个datasource,用来区分不同的bean,比如多个数据库源
    @Qualifier("primaryDataSource")//@Autowired默认是根据类型进行注入的,因此如果有多个类型一样的Bean候选者,Qualifier则需要限定其中一个候选者,否则将抛出异常,@Qualifier限定描述符除了能根据名字进行注入,更能进行更细粒度的控制如何选择候选者
    @ConfigurationProperties(prefix="spring.datasource.primary")//读取前缀是什么的配置
    public DataSource primaryDataSource() {
        return DataSourceBuilder.create().build();
    }
}

3、在使用的时候注入datasource

@Bean(name = "primaryJdbcTemplate")
public JdbcTemplate primaryJdbcTemplate(
        @Qualifier("primaryDataSource") DataSource dataSource) {
    return new JdbcTemplate(dataSource);
}

4、更详细的配置类

package com.guor.config;
 
import java.sql.SQLException;
 
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
 
import com.alibaba.druid.pool.DruidDataSource;
 
@Configuration
@PropertySource(value = { "classpath:druidConfig.properties",
"classpath:jdbc.properties" }, ignoreResourceNotFound = true)
public class DataSourceConfig {
	@Value("${driverClassName}")
	private String driverClassName;
	@Value("${url}")
	private String url;
	@Value("${duridUserName}")
	private String username;
	@Value("${password}")
	private String password;
	@Value("${filters}")
	private String filters;
	@Value("${initialSize}")
	private int initialSize;
	@Value("${maxActive}")
	private int maxActive;
	@Value("${minIdle}")
	private int minIdle;
	@Value("${maxWait}")
	private int maxWait;
	@Value("${validationQuery}")
	private String validationQuery;
	@Value("${testWhileIdle}")
	private boolean testWhileIdle;
	@Value("${testOnBorrow}")
	private boolean testOnBorrow;
	@Value("${testOnReturn}")
	private boolean testOnReturn;
	@Value("${maxPoolPreparedStatementPerConnectionSize}")
	private int maxPoolPreparedStatementPerConnectionSize;
	@Value("${removeAbandoned}")
	private boolean removeAbandoned;
	@Value("${removeAbandonedTimeout}")
	private int removeAbandonedTimeout;
	@Value("${timeBetweenEvictionRunsMillis}")
	private int timeBetweenEvictionRunsMillis;
	@Value("${minEvictableIdleTimeMillis}")
	private int minEvictableIdleTimeMillis;
	
	@Bean(initMethod="init",destroyMethod="close")
	public DruidDataSource dataSource(){
		DruidDataSource dataSource=new DruidDataSource();
		try {
			dataSource.setUrl(url);
			dataSource.setDriverClassName(driverClassName);
			dataSource.setUsername(username);
			dataSource.setPassword(password);
			dataSource.setFilters(filters);
			dataSource.setInitialSize(initialSize);
			dataSource.setMaxActive(maxActive);
			dataSource.setMinIdle(minIdle);
			dataSource.setMaxWait(maxWait);
			dataSource.setValidationQuery(validationQuery);
			dataSource.setTestWhileIdle(testWhileIdle);
			dataSource.setTestOnBorrow(testOnBorrow);
			dataSource.setTestOnReturn(testOnReturn);
			dataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
			dataSource.setRemoveAbandoned(removeAbandoned);
			dataSource.setRemoveAbandonedTimeout(removeAbandonedTimeout);
			dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
			dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
			System.out.println("连接池启动成功");
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return dataSource;
	}
}

5、事务的使用

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    @Transactional
    public void insertUser(User user) {
        String sql = "insert into user(id, name) values(?,?)";
        jdbcTemplate.update(sql, user.getId(), user.getName());
        //int num = 1/0;  //放开测试事务。预期结果为添加失败,库中无数据。测试结果与预期一致
    }
}

【Spring Boot 23】MyBatis事务管理

 6、dao层代码简介


@Repository("userDao")
public class UserDaoImpl implements UserDao {
	@Autowired
	private JdbcTemplate jdbcTemplate;
	
	//判断用户是否登录成功
	public boolean isLogin(UserEntity paramUser) {
		boolean flag=false;
		String sqlStr="select * from user where userName=? and passWord=?";
		List<UserEntity> userList=jdbcTemplate.query(sqlStr, 
				new Object[]{paramUser.getUserName(),paramUser.getPassWord()}, 
				new BeanPropertyRowMapper(UserEntity.class));
		if(userList!=null && userList.size()>0){
			flag=true;
		}
		return flag;
	}
}

 四、API介绍

1、执行DDL语句

(1)API简介

//一般用于执行DDL语句
public int execute(final String sql)

(2)代码实例

public class Test01 {
	public static void main(String[] args) {
		// 创建表的SQL语句
		String sql = "CREATE TABLE product("
				+ "pid INT PRIMARY KEY AUTO_INCREMENT,"
				+ "pname VARCHAR(20),"
				+ "price DOUBLE"
				+ ");";
				
		JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
		jdbcTemplate.execute(sql);
	}
}

2、JdbcTemplate实现增删改

(1)API简介

扫描二维码关注公众号,回复: 12138000 查看本文章
//用于执行INSERT、UPDATE、DELETE等DML语句
public int update(String sql)

(2)代码实例

public class Test {
	public static void main(String[] args) throws Exception {
		insertTest();
		updateTest();
		deleteTest();
	}
	
	// JDBCTemplate插入
	public static void insertTest() throws Exception {
		JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
		String sql = "INSERT INTO user(id,name,age) VALUES (?, ?, ?)";
		jdbcTemplate.update(sql, 1, "素小暖", 18);
	}
	
	// JDBCTemplate更新
	public static void updateTest() throws Exception {
		JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
		String sql = "UPDATE user SET age= ?, address = ? WHERE name=?";
		int i = jdbcTemplate.update(sql, 19, "大连市高新园区", "素小暖");
		System.out.println("影响的行数: " + i);
	}

	// JDBCTemplate删除
	public static void deleteTest() throws Exception {
		JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
		String sql = "DELETE FROM user WHERE id=?";
		int i = jdbcTemplate.update(sql, 1);
		System.out.println("影响的行数: " + i);
	}
}

3、JdbcTemplate查询-queryForInt返回一个int整数

(1)API简介

//执行查询语句,返回一个int类型的值
public int queryForInt(String sql)

(2)代码实例

// queryForInt返回一个整数
public static void test01() throws Exception {
   // String sql = "SELECT COUNT(*) FROM user";
   String sql = "SELECT name FROM user WHERE id= ?";
   JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
   int forInt = jdbcTemplate.queryForInt(sql, 2);
}

4、JdbcTemplate查询-queryForLong返回一个long整数

(1)API简介

//执行查询语句,返回一个long类型的数据
public long queryForLong(String sql)

(2)代码实例

// queryForLong  返回一个long类型整数
public static void test02() throws Exception {
   String sql = "SELECT COUNT(1) FROM user";
   JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
   long forLong = jdbcTemplate.queryForLong(sql);
}

5、JdbcTemplate查询-queryForObject返回String

(1)API简介

//执行查询语句,返回一个指定类型的数据
public <T> T queryForObject(String sql, Class<T> requiredType)

(2)代码实例

public static void test03() throws Exception {
   String sql = "SELECT name FROM user WHERE id= ?";
   JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
   String str = jdbcTemplate.queryForObject(sql, 1, String.class);
}

6、JdbcTemplate查询-queryForMap返回一个Map集合

(1)API简介

//执行查询语句,将一条记录放到一个Map中
public Map<String, Object> queryForMap(String sql)

(2)代码实例

public static void test04() throws Exception {
   String sql = "SELECT * FROM user WHERE id= ? ";
   JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
   Map<String, Object> map = jdbcTemplate.queryForMap(sql, 1);
}

7、JdbcTemplate查询-queryForList返回一个List集合

(1)API简介

//执行查询语句,返回一个List集合,List中存放的是Map类型的数据
public List<Map<String, Object>> queryForList(String sql)

(2)代码实例

public static void test05() throws Exception {
   String sql = "SELECT * FROM user WHERE id< ?";
   JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
   List<Map<String, Object>> list = jdbcTemplate.queryForList(sql, 10);
   for (Map<String, Object> map : list) {
      System.out.println(map);
   }
}

8、JdbcTemplate查询-RowMapper返回自定义对象

(1)API简介

//执行查询语句,返回一个List集合,List中存放的是RowMapper指定类型的数据
public <T> List<T> query(String sql, RowMapper<T> rowMapper)

(2)使用步骤

  1. 定义Product类
  2. 创建JdbcTemplate对象
  3. 编写查询的SQL语句
  4. 使用JdbcTemplate对象的query方法,并传入RowMapper匿名内部类
  5. 在匿名内部类中将结果集中的一行记录转成一个Product对象

(3)代码实例

// query使用rowMap做映射返回一个对象
public static void test06() throws Exception {
    JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());

   // 查询数据的SQL语句
   String sql = "SELECT * FROM user";
   /**
   * 使用JdbcTemplate对象的query方法,并传入RowMapper匿名内部类
   * 在匿名内部类中将结果集中的一行记录转成一个User对象
   */
   List<User> list = jdbcTemplate.query(sql, new RowMapper<User>() {
      @Override
      public Product mapRow(ResultSet arg0, int arg1) throws SQLException {
         User user = new User();
         user.setId(arg0.getInt("id"));
         user.setName(arg0.getString("name"));
         user.setAge(arg0.getInt("age"));
         return p;
      }
   });

   for (User user : list) {
      System.out.println(user);
   }
}

9、JdbcTemplate查询-BeanPropertyRowMapper返回自定义对象

(1)API简介

//执行查询语句,返回一个List集合,List中存放的是RowMapper指定类型的数据
public <T> List<T> query(String sql, RowMapper<T> rowMapper)
//BeanPropertyRowMapper类实现了RowMapper接口
public class BeanPropertyRowMapper<T> implements RowMapper<T>

(2)使用步骤

  1. 定义Product类
  2. 创建JdbcTemplate对象
  3. 编写查询的SQL语句
  4. 使用JdbcTemplate对象的query方法,并传入BeanPropertyRowMapper对象

(3)代码实例

// query使用BeanPropertyRowMapper做映射返回对象
public static void test07() throws Exception {
	JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());

	// 查询数据的SQL语句
	String sql = "SELECT * FROM user";
	List<Product> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(User.class));

	for (User user : list) {
		System.out.println(user);
	}
}

10、批量插入

(1)API简介

//批量插入
jdbcTemplate.batchUpdate(String sql, List<Object[]> paramList);

(2)代码实例 

String sql = "INSERT INTO login (user_name, pass_word) VALUES (?, ?)";
List<Object[]> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
    String[] arr = new String[3];
    arr[0] = "username" + i;
    arr[1] = "password" + i;
    list.add(arr);
}
jdbcTemplate.batchUpdate(sql, list);

往期精彩内容:

超详细的springBoot学习笔记

Java多线程基础知识总结(绝对经典)

Java面试题总结(附答案)

Vue基础知识总结(绝对经典)

常见数据结构与算法整理总结

猜你喜欢

转载自blog.csdn.net/guorui_java/article/details/111936978