天天看点

【Spring】JdbcTemplate的常用方法

JdbcTemplate是Spring JDBC的核心类,借助该类提供的方法可以很方便的实现数据的增删改查。下面将在一个例子中介绍该类的几个常用的方法。

本博客用例:

1、创建一个Java或web项目,导入spring所需jar包、数据库连接jar包、日志包及Hikari的jar包;

2、在src目录下新建包“cn.jingpengchong.vo”,并创建一个与数据库中user_info表对应的实体类:

【Spring】JdbcTemplate的常用方法
package cn.jingpengchong.vo;

public class UserInfo {
	
	private String id;
	private String userName;
	private String password;
	//节省篇幅、省略get/set。。。
	@Override
	public String toString() {
		return "UserInfo [id=" + id + ", userName=" + userName + ", password=" + password + "]";
	}
}
           

3、编写spring的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"
	xmlns:p="http://www.springframework.org/schema/p"
	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-4.3.xsd">

	<context:component-scan base-package="cn.jingpengchong"></context:component-scan>
	<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close" p:username="root" p:password="1234">
		<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
		<property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/mytest"></property>
	</bean>
	<bean class="org.springframework.jdbc.core.JdbcTemplate" p:dataSource-ref="dataSource"></bean>
</beans>
           

4、在src目录下新建包“cn.jingpengchong.userinfo.dao”,并创建一个接口“IUserInfoDao.java”和一个类“UserInfoDao.java”:

package cn.jingpengchong.userinfo.dao;

import java.util.List;

import cn.jingpengchong.vo.UserInfo;

public interface IUserInfoDao {	
	boolean insert(UserInfo userInfo);
	boolean delete(String id);
	boolean update(String id);
	String login(String userName,String password);
	UserInfo getById(int id);
	List<UserInfo> selectAll();
}
           
package cn.jingpengchong.userinfo.dao;

import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import cn.jingpengchong.vo.UserInfo;

@Repository
public class UserInfoDao implements IUserInfoDao {

	@Autowired
	private JdbcTemplate template;

	//插入数据
	public boolean insert(UserInfo userInfo) {
		return false;
	}
	
	//删除数据
	public boolean delete(String id) {
		return false;
	}

	//修改数据
	public boolean update(String id) {
		return false;
	}
	
	//查询基本数据类型包装类对象
	String boolean login(String userName,String password) {
		return null;
	}
	
	//查询一个UserInfo对象
	public UserInfo getById(String id) {
		return null;	
	}
	
	//查询多个UserInfo对象
	public List<UserInfo> selectAll(){
		return null;
	}
}
           

JdbcTemplate的常用方法:

1、增加:

int update(final String sql):数据修改,也可用于添加数据,返回受影响的行数。

int update(String sql, Object… args) throws DataAccessException:数据修改,也可用于添加数据,返回受影响的行数,该方法可以规避SQL注入,例子如下:

  • 完善UserInfoDao类中的insert方法:
public boolean insert(UserInfo userInfo) {
	String sql = "insert into user_info(id,user_name,password) values(?,?,?)";
	return template.update(sql, userInfo.getId(),userInfo.getUserName(),userInfo.getPassword()) > 0;
}
           
  • 编写测试类:
package cn.jingpengchong.test;

import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.jingpengchong.userinfo.dao.UserInfoDao;
import cn.jingpengchong.vo.UserInfo;

public class Test {
	
	public static void main(String[] args) {
		
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
		UserInfoDao userInfo = applicationContext.getBean(UserInfoDao.class);
		UserInfo user = new UserInfo("cccccccc-cccc-cccc-cccc-cccccccccccc", "jerry", "555");
		boolean b = userInfo.insert(user);
		if (b) {
			System.out.println("添加成功");
		}
		applicationContext.close();	
	}
}
           

运行结果如下:

【Spring】JdbcTemplate的常用方法

添加成功:

【Spring】JdbcTemplate的常用方法

2、删除:

int update(final String sql):数据修改,也可用于删除数据,返回受影响的行数。

int update(String sql, Object… args) throws DataAccessException:数据修改,也可用于删除数据,返回受影响的行数,该方法可以规避SQL注入,例子如下:

  • 完善UserInfoDao类中的delete方法:
public boolean delete(String id) {
	String sql = "delete from user_info where id = ?";
	return template.update(sql, id) > 0;
}
           
  • 编写测试类:
package cn.jingpengchong.test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import cn.jingpengchong.userinfo.dao.UserInfoDao;

public class Test {
	
	public static void main(String[] args) {
		
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
		UserInfoDao userInfo = applicationContext.getBean(UserInfoDao.class);
		boolean b = userInfo.delete("cccccccc-cccc-cccc-cccc-cccccccccccc");
		if (b) {
			System.out.println("删除成功");
		}
		applicationContext.close();	
	}
}
           

运行结果如下:

【Spring】JdbcTemplate的常用方法

删除成功:

【Spring】JdbcTemplate的常用方法

3、修改:

int update(final String sql):数据修改,返回受影响的行数。

int update(String sql, Object… args) throws DataAccessException:数据修改,返回受影响的行数,该方法可以规避SQL注入,例子如下:

  • 完善UserInfoDao类中的update方法:
public boolean update(String id,String password) {
	String sql = "update user_info set password = ? where id = ?";
	return template.update(sql, password, id) > 0;
}
           
  • 编写测试类:
package cn.jingpengchong.test;

import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.jingpengchong.userinfo.dao.UserInfoDao;

public class Test {
	
	public static void main(String[] args) {
		
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
		UserInfoDao userInfo = applicationContext.getBean(UserInfoDao.class);
		boolean b = userInfo.update("bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb", "333");
		if (b) {
			System.out.println("修改成功");
		}
		applicationContext.close();	
	}
}
           

运行结果如下:

【Spring】JdbcTemplate的常用方法

修改成功:

【Spring】JdbcTemplate的常用方法

4、查询:

①查询基本数据类型包装类对象:

<T> T queryForObject(String sql, Class<T> requiredType) throws DataAccessException:根据SQL语句返回某列的值,其中requiredType用于指定该列的数据类型;

<T> T queryForObject(String sql, Class<T> requiredType, Object… args) throws DataAccessException:同上,该方法可以规避SQL注入。

例子如下:

  • 完善UserInfoDao类中的login方法:
public String login(String userName,String password) {
	try {
		String sql = "select id from user_info where user_name = ? and password = ?";
		String id = template.queryForObject(sql, String.class, userName,password);
		return id;
	} catch (DataAccessException e) {
		return "空";
	}		
}
           
  • 编写测试类:
package cn.jingpengchong.test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import cn.jingpengchong.userinfo.dao.UserInfoDao;

public class Test {
	
	public static void main(String[] args) {
		
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
		UserInfoDao userInfo = applicationContext.getBean(UserInfoDao.class);
		String id = userInfo.login("admin","111");
		System.out.println("查询到的结果为:" + id);
		applicationContext.close();	
	}
}
           

运行结果为:

【Spring】JdbcTemplate的常用方法

②查询单个自定义类对象:

<T> T queryForObject(String sql, RowMapper<T> rowMapper) throws DataAccessException:返回SQL语句查出的某条数据,该数据的数据类型由RowMapper接口实现类决定;

<T> T queryForObject(String sql, RowMapper<T> rowMapper, Object… args) throws DataAccessException:同上,该方法可以规避SQL注入。

<T> T query(final String sql, final ResultSetExtractor<T> rse) throws DataAccessException:返回SQL语句查出数据组成的结果,该结果数据类型由ResultSetExtractor接口实现类决定;

<T> T query(String sql, ResultSetExtractor<T> rse, Object… args) throws DataAccessException:同上,该方法可以规避SQL注入。

例子如下:

  • 完善UserInfoDao类中的selectById方法:
public UserInfo getById(String id) {
		String sql = "select * from user_info where id = ?";
		
		//方法一:用RowMapper内部类方法
//		class UserInfoRowMapper implements RowMapper<UserInfo>{
//			@Override
//			public UserInfo mapRow(ResultSet rs, int rowNum) throws SQLException {
//				UserInfo userInfo = new UserInfo();
//				userInfo.setId(rs.getInt("id"));
//				userInfo.setUserName(rs.getString("user_name"));
//				userInfo.setPassword(rs.getString("password"));
//				
//				return userInfo;
//			}
//		}
		
		//方法二:将方法一改为lambda表达式
//		return template.queryForObject(sql, (rs, rowNum)->{
//			UserInfo userInfo = new UserInfo();
//			userInfo.setId(rs.getInt("id"));
//			userInfo.setUserName(rs.getString("user_name"));
//			userInfo.setPassword(rs.getString("password"));
//			return userInfo;
//		}, id);
		
		//方法三:用ResultSetExtractor内部类方法
//		class UserInfoResultSet implements ResultSetExtractor<UserInfo>{
//			@Override
//			public UserInfo extractData(ResultSet resultSet) throws SQLException, DataAccessException {
//				UserInfo userInfo = new UserInfo();
//				if(resultSet.next()) {
//					userInfo.setId(resultSet.getInt("id"));
//					userInfo.setUserName(resultSet.getString("user_name"));
//					userInfo.setPassword(resultSet.getString("password"));
//				}
//				return userInfo;
//			}
//		}
		
		//方法四:将方法三改为lambda表达式
		return template.query(sql, (resultSet)->{
			UserInfo userInfo = new UserInfo();
			if(resultSet.next()) {
				userInfo.setId(resultSet.getString("id"));
				userInfo.setUserName(resultSet.getString("user_name"));
				userInfo.setPassword(resultSet.getString("password"));
			}
			return userInfo;
		},id);
		
	}
           
  • 编写测试类:
package cn.jingpengchong.test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import cn.jingpengchong.userinfo.dao.UserInfoDao;
import cn.jingpengchong.vo.UserInfo;

public class Test {
	
	public static void main(String[] args) {
		
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
		UserInfoDao userInfo = applicationContext.getBean(UserInfoDao.class);
		UserInfo user = userInfo.getById("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa");
		System.out.println("查询到的结果为:" + user);
		applicationContext.close();	
	}
}
           

运行结果如下:

【Spring】JdbcTemplate的常用方法

③查询多个自定义类对象:

<T> List<T> query(String sql, RowMapper<T> rowMapper) throws DataAccessException:返回SQL语句查出的所有数据组成的List集合,集合中元素数据类型由RowMapper接口实现类决定;

<T> List<T> query(String sql, RowMapper<T> rowMapper, Object… args) throws DataAccessException:同上,该方法可以规避SQL注入。

<T> T query(final String sql, final ResultSetExtractor<T> rse) throws DataAccessException:返回SQL语句查出数据组成的结果,该结果数据类型由ResultSetExtractor接口实现类决定;

<T> T query(String sql, ResultSetExtractor<T> rse, Object… args) throws DataAccessException:同上,该方法可以规避SQL注入。

例子如下:

  • 完善UserInfoDao类中的selectAll方法:
//用RowMapper内部类方式的防注入方法
	public List<UserInfo> selectAll(){
		String sql = "select * from user_info";
//		return template.query(sql, (rs, rowNum)->{
//			UserInfo userInfo = new UserInfo();
//			userInfo.setId(rs.getInt("id"));
//			userInfo.setUserName(rs.getString("user_name"));
//			userInfo.setPassword(rs.getString("password"));
//			return userInfo;
//		});
		
		//用ResultSetExtractor内部类方式的防注入方法
		return template.query(sql, (resultSet)->{
			List<UserInfo> list = new ArrayList<>();
			while(resultSet.next()) {
				UserInfo userInfo = new UserInfo();
				userInfo.setId(resultSet.getString("id"));
				userInfo.setUserName(resultSet.getString("user_name"));
				userInfo.setPassword(resultSet.getString("password"));
				list.add(userInfo);
			}
			return list;
		});
	}
           
  • 编写测试类:
package cn.jingpengchong.test;

import java.util.List;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import cn.jingpengchong.userinfo.dao.UserInfoDao;
import cn.jingpengchong.vo.UserInfo;

public class Test {
	
	public static void main(String[] args) {
		
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
		UserInfoDao userInfo = applicationContext.getBean(UserInfoDao.class);
		List<UserInfo> users = userInfo.selectAll();
		for (UserInfo user : users) {
			System.out.println(user);
		}
		applicationContext.close();	
	}
}
           

运行结果如下:

【Spring】JdbcTemplate的常用方法