Spring学习之JdbcTemplate

本文介绍了Spring的JdbcTemplate,它是对jdbc操作的一种简化封装,提供了execute、update、query等方法,以及各种回调接口,如PreparedStatementCreator、RowMapper等,方便进行数据库操作。使用JdbcTemplate的一般步骤包括设置数据源、导入依赖、创建DAO并注入DataSource,以及利用JdbcTemplate执行增删改查等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、什么是JDBCTemplate

Spring使用模板方式封装jdbc数据库操作固定流程,并提供丰富callback回调接口功能,方便用户自定义加工细节,更好模块化jdbc操作,简化传统的JDBC操作的复杂和繁琐过程。 

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

(1) execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;

jdbcTemplate.execute("CREATE TABLE t_user (user_id integer, name varchar(64))"); 

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

jdbcTemplate.update("update t_user set username=? where id=?",user.getUsername(), user.getId());

(3) query方法及queryForXXX方法:用于执行查询相关语句;

int count = jdbcTemplate.queryForInt("select count(*) from t_user");
List<String> nicknameList = jdbcTemplate.queryForList("select nickname from t_user", String.class);

(4) call方法:用于执行存储过程、函数相关语句。


JdbcTemplate类支持的回调类:

(1) 预编译语句及存储过程创建回调

PreparedStatementCreator:通过回调获取JdbcTemplate提供的Connection,由用户使用该Conncetion创建相关的PreparedStatement;

CallableStatementCreator:通过回调获取JdbcTemplate提供的Connection,由用户使用该Conncetion创建相关的CallableStatement;


(2) 预编译语句设值回调

PreparedStatementSetter:通过回调获取JdbcTemplate提供的PreparedStatement,由用户来对相应的预编译语句相应参数设值;
BatchPreparedStatementSetter:;类似于PreparedStatementSetter,但用于批处理,需要指定批处理大小;


(3)自定义功能回调

ConnectionCallback:通过回调获取JdbcTemplate提供的Connection,用户可在该Connection执行任何数量的操作;
StatementCallback:通过回调获取JdbcTemplate提供的Statement,用户可以在该Statement执行任何数量的操作;
PreparedStatementCallback:通过回调获取JdbcTemplate提供的PreparedStatement,用户可以在该PreparedStatement执行任何数量的操作;
CallableStatementCallback:通过回调获取JdbcTemplate提供的CallableStatement,用户可以在该CallableStatement执行任何数量的操作;


(4)结果集处理回调

RowMapper:用于将结果集每行数据转换为需要的类型,用户需实现方法mapRow(ResultSet rs, int rowNum)来完成将每行数据转换为相应的类型。
RowCallbackHandler:用于处理ResultSet的每一行结果,用户需实现方法processRow(ResultSet rs)来完成处理,在该回调方法中无需执行rs.next(),该操作由JdbcTemplate来执行,用户只需按行获取数据然后处理即可。
ResultSetExtractor:用于结果集数据提取,用户需实现方法extractData(ResultSet rs)来处理结果集,用户必须处理整个结果集;


二、使用JDBCTemplate

这里先给出使用JDBCTemplate的一般步骤:

1.导入Spring的包和数据库驱动包
2.选择一个数据源(DBCP, C3P0)
3.导入数据源的包:DBCP
4.在beans.xml中创建datasource数据源
5.创建jdbc.propertier来设置数据库连接信息
6.在beans.xml中导入相应的properties文件
<context:property-placeholder location="jdbc.properties"/>
7.写一个DAO,并且为这个DAO创建一个JdbcTemplate,通过JdbcTemplate对象可以方便的完成对数据的操作
8.为Dao注入相应的DataSource并且创建JdbcTemplate
@Resource
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
9.完成数据对象的添加


首先需要把DataSource注册到JdbcTemplate之中。同时,为了支持对properties文件的支持,spring提供了类似于EL表达式的方式,把properties的文件参数引入到参数配置之中。

<?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:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	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/aop
   http://www.springframework.org/schema/aop/spring-aop.xsd">

	<!-- 打开spring的Annotation支持 -->
	<context:annotation-config />
	<!-- 设定spring去哪些包中找Annotation -->
	<context:component-scan base-package="com.spring" />

	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName" value="${jdbc.driverClassName}" />
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
	</bean>
	<!-- 导入src目录下的jdbc.properties文件 -->
	<context:property-placeholder location="jdbc.properties" />

</beans>


配置文件jdbc.properties位于src目录下:

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring_teach
jdbc.username=root
jdbc.password=123

a. 将DataSource注入到JDBCTemplate中:

@Resource
public void setDataSource(DataSource dataSource) {
	this.jdbcTemplate = new JdbcTemplate(dataSource);
}

b. 添加数据

public void add(User user, int gid) {
		jdbcTemplate.update("insert into t_user(username, password, nickname, gid) value(?, ?, ?, ?)",user.getUsername(), user.getPassword(),user.getNickname(), gid);
	}

c.修改数据

public void update(User user) {
		jdbcTemplate.update("update t_user set username=?, password=?,nickname=? where id=?", user.getUsername(), user.getPassword(), user.getNickname(), user.getId());
	}

d. 删除数据

public void delete(int id) {
		jdbcTemplate.update("delete from t_user where id=?", id);
	}


在查询对象的时候,需要用到RowMappe类:

public class UserMapper implements RowMapper<User> {
		@Override
		public User mapRow(ResultSet rs, int rowNum) throws SQLException {
			Group g = new Group();
			g.setId(rs.getInt("gid"));
			g.setName(rs.getString("name"));
			User u = new User();
			u.setGroup(g);
			u.setId(rs.getInt("uid"));
			u.setNickname(rs.getString("nickname"));
			u.setPassword(rs.getString("password"));
			u.setUsername(rs.getString("username"));
			return u;
		}

	}


e. 查询一条数据

public User load(int id) {
		String sql = "select t1.id uid, t1.*, t2.* from t_user t1 left join t_group t2 on (t1.gid=t2.id) where t1.id=?";
		/**
		 * 第一个参数是SQL语句 第二个参数是SQL语句中的参数值,需要传入一个对象数组
		 * 第三个参数是RowMapper,这个RowMapper可以完成一个对象和数据库字段的对应,实现这个RowMapper需要
		 * 实现mapRow方法,在mapRow方法中有rs这个参数,通过rs可以有效的获取数据库的字段
		 */
		User u = (User) jdbcTemplate.queryForObject(sql, new Object[] { id }, new UserMapper());
		return u;
	}

f. 查询一组数据

public List<User> list(String sql, Object[] args) {
		//获取整数值
		String sqlCount = "select count(*) from t_user";
		int count = jdbcTemplate.queryForInt(sqlCount);
		System.out.println("count = "+count);
		//获取String类型的列表
		String sqlNickname = "select nickname from t_user";
		List<String> nicknameList = jdbcTemplate.queryForList(sqlNickname, String.class);
		for(String str : nicknameList){
			System.out.println(str);
		}
		//以下写法无法查询数据
		/*String sqlStrs = "select username, nickname from t_user";
		List<User> users = jdbcTemplate.queryForList(sqlStrs, User.class);
		for(User user : users){
			System.out.println(user);
		}*/
		//以下写法也无法查询数据
		/*String sqlStrs = "select username, nickname from t_user";
		List<Object []> users = jdbcTemplate.queryForObject(sqlStrs, Object[].class);*/
		
		//只能通过RowMapper来实现
	/*	String sqlStrs = "select username, nickname from t_user";
		List<User> users = jdbcTemplate.query(sqlStrs, new RowMapper<User>(){
			@Override
			public User mapRow(ResultSet rs, int rowNum) throws SQLException {
				User u = new User();
				u.setUsername(rs.getString("username"));
				u.setNickname(rs.getString("nickname"));
				return u;
			}
			
		});
		for(User user:users){
			System.out.println(user);
		}*/
		
		return jdbcTemplate.query(sql, args, new UserMapper());

	}


package com.org.dao.impl; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.PreparedStatementCreator; import org.springframework.jdbc.core.RowCallbackHandler; import org.springframework.jdbc.support.GeneratedKeyHolder; import org.springframework.stereotype.Repository; import com.org.JdbcTempBaseDao; import com.org.dao.IUserDao; import com.org.model.User; @Repository @SuppressWarnings("all") public class UserDaoImpl extends JdbcTempBaseDao implements IUserDao { @Override public List<User> getUserList() { String sql="select * from user "; final List<User> list= new ArrayList<User>(); jdbcTemplate.query(sql, new RowCallbackHandler(){ @Override public void processRow(ResultSet rs) throws SQLException { User u=new User(); u.setId(rs.getInt("id")); u.setUsername(rs.getString("username")); u.setPassword(rs.getString("password")); u.setCreateDate(rs.getString("createDate")); u.setModifyDate(rs.getString("modifyDate")); u.setType(rs.getString("type")); list.add(u); } }); return list; } @Override public List<User> getUserLists(Map<String, Object> map) { return null; } @Override public Integer getUserCount(Map<String, Object> map) { String sql = "select count(1) from User where id=? "; return getJdbcTemplate().queryForObject(sql, Integer.class,map); } @Override public User getUserById(Integer primaryKeyId) { String sql = "select id,username, password, createDate, modifyDate,type from User where id=?"; List<User> userList = getJdbcTemplate().query(sql, new BeanPropertyRowMapper(User.class), primaryKeyId); if(userList.size() == 0) { return null; } return userList.get(0); } @Override public void delUserById(Integer primaryKeyId) { String sql = "delete from user where id=?"; getJdbcTemplate().update(sql, primaryKeyId); } @Override public User addUser(final User entity) { final String sql = "insert into User(username, password, createDate, modifyDate,type) values(?,?,?,?,?)"; GeneratedKeyHolder keyHolder = new GeneratedKeyHolder(); getJdbcTemplate().update(new PreparedStatementCreator() { @Override public PreparedStatement createPreparedStatement(Connection connection) throws SQLException { PreparedStatement psst = connection.prepareStatement(sql, new String[]{"id"}); psst.setString(1, entity.getUsername()); psst.setString(2, entity.getPassword()); psst.setString(3, entity.getCreateDate()); psst.setString(4, entity.getModifyDate()); psst.setString(5, entity.getType()); return psst; } }, keyHolder); entity.setId(keyHolder.getKey().intValue()); return entity; } @Override public void editUser(User entity) { String sql="update user set username=?,password=?"; jdbcTemplate.update(sql, User.class,entity); } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值