JdbcTemplate是Spring JDBC的核心类,借助该类提供的方法可以很方便的实现数据的增删改查。下面将在一个例子中介绍该类的几个常用的方法。
本博客用例:
1、创建一个Java或web项目,导入spring所需jar包、数据库连接jar包、日志包及Hikari的jar包;
2、在src目录下新建包“cn.jingpengchong.vo”,并创建一个与数据库中user_info表对应的实体类:
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();
}
}
运行结果如下:
添加成功:
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();
}
}
运行结果如下:
删除成功:
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();
}
}
运行结果如下:
修改成功:
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();
}
}
运行结果为:
②查询单个自定义类对象:
<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();
}
}
运行结果如下:
③查询多个自定义类对象:
<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();
}
}
运行结果如下: