人的一生要遇见太多人,没必要活在他们的眼神里。只要内心澄明,就永远不用讨好一个不懂你的人-----------jgp
1 JDBCTemplate简介
什么是JdbcTemplate?
Spring提供用于操作数据库的模版,类似Dbutils,通俗点讲,我们操作数据库,Spring也会帮我们提供一个操作数据库的工具供我们使用,而不用我们自己手动编写连接数据库,获取结果集等等操作,这个工具就是JdbcTemplate。跟Dbutils一样,想要使用JdbcTemplate,就必须给他配置数据源(依赖)。
我们知道,常用的数据源有DBCP数据源和C3P0数据源。除此之外呢,spring-jdbc-3.2.2.RELEASE.jar对JDBC也提供了支持,
需要设置org.springframework.jdbc.datasource.DriverManagerDataSource的4个参数。
这三种获得数据源对象的方式大同小异,注意导包和四大参数的名称即可。
2 手动方式创建JDBCTemplate
2.1 创建表
建表语句
create database jdbc_template; use jdbc_template; create table t_user( id int(10) primary key auto_increment, username varchar(50), password varchar(32) ); insert into t_user(username,password) values('jack','1234'); insert into t_user(username,password) values('rose','5678');
表中记录
2.2 导入jar包
这里我们当然采用最原始的方法,创建DBCP数据源对象,再手动设置给JdbcTemplate对象,
所以需要导入commons.dbcp和commons.pool,此外spring-jdbc和spring-tx也不可或缺。
2.3 域模型(javabean)
public class User { private int uid; private String username; private String password; public int getUid() { return uid; } public void setUid(int uid) { this.uid = uid; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "User [uid=" + uid + ", username=" + username + ", password=" + password + "]"; } }
2.4 测试程序
import org.apache.commons.dbcp.BasicDataSource; import org.springframework.jdbc.core.JdbcTemplate; public class TestJdbcTemplate { public static void main(String[] args) { //1 创建数据源(连接池) dbcp BasicDataSource dataSource = new BasicDataSource(); // * 基本4项 dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/jdbc_template"); dataSource.setUsername("root"); dataSource.setPassword("1122"); //2 创建模板 JdbcTemplate jdbcTemplate = new JdbcTemplate(); jdbcTemplate.setDataSource(dataSource); //3 通过api操作 String sql = "insert into t_user(username,password) values(?,?)"; Object[] params = {"tom","9999"}; jdbcTemplate.update(sql, params); } }
测试结果:
3 注入JdbcTemplate
3.1 概述
上面的的项目中,需要我们手动地去创建数据源对象,然后手动创建JDBCTemplate对象,
而现在我们的需求是要让Spring容器向userDao对象中注入一个JDBCTemplate,这样userDao对象拿着这个"模板"就可以对数据库进行操作了,
也就是说,我们的测试程序需要从Spring容器中获取UserDao实例对象,这个UserDao实例对象依赖于JDBCTemplate实例对象,JDBCTemplate实例对象又依赖于数据源对象。
如果我们还有个service层呢?
那我们的测试程序需要从Spring容器中获取UserService实例对象,这个UserService实例对象依赖于UserDao实例对象,UserDao实例对象依赖于JDBCTemplate实例对象,
JDBCTemplate实例对象又依赖于数据源对象,依次类推。
3.2 项目搭建与测试
3.2.1 创建表
将上例中的表drop掉,然后重新创建一个空的数据表
CREATE DATABASE jdbc_template; USE jdbc_template; CREATE TABLE t_user( uid INT(10) PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50), PASSWORD VARCHAR(32) );
3.2.2 域模型
public class User { private Integer uid; //用户id private String username; //用户名 private String password; //密码 public Integer getUid() { return uid; } public void setUid(Integer uid) { this.uid = uid; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "UserDao [uid=" + uid + ", username=" + username + ", password=" + password + "]"; } }
3.2.3 导入jar包
下面的项目中我们都利用spring-jdbc-3.2.2.RELEASE.jar对JDBC的支持获得DataSource对象,
这样我们就不需要导入DBCP数据源的实现包和依赖包了。
所以比上面的项目少了两个jar包。
3.2.4 DAO接口和实现类
public interface UserDao { public int addUser(User user); public int updateUser(User user); public int deleteUserById( int id); public User findUserById( int id); public List<User> findAllUser(); }
public class UserDaoImpl implements UserDao{ private JdbcTemplate jdbcTemplate; public JdbcTemplate getJdbcTemplate() { return jdbcTemplate; } public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } // 添加用户 public int addUser(User user) { String sql = "insert into t_user(username,password) values(?,?)"; Object[] params =new Object[]{ user.getUsername(), user.getPassword() }; int flag = this.jdbcTemplate.update(sql, params); return flag; } //更新用户数据 public int updateUser(User user) { String sql = "update t_user set username = ? " + ",password = ? where uid = ?"; Object[] params =new Object[]{ user.getUsername(), user.getPassword(), user.getUid() }; int flag = this.jdbcTemplate.update(sql, params); return flag; } //删除用户 public int deleteUserById(int id) { String sql = "delete from t_user where uid = ?"; int flag = this.jdbcTemplate.update(sql, id); return flag; } //根据id查询用户 public User findUserById(int id) { String sql = "select * from t_user where uid = ?"; /* * 提供默认实现类 ParameterizedBeanPropertyRowMapper,使用此类要求数据表的列必须和java对象的属性对应 * ParameterizedBeanPropertyRowMapper将结果集通过java的反射机制映射到java对象中 */ RowMapper<User> rowMapper = ParameterizedBeanPropertyRowMapper .newInstance(User.class); //使用queryForObject方法查询,返回单行记录 return this.jdbcTemplate.queryForObject(sql, rowMapper, id); } //查询所有用户 public List<User> findAllUser() { String sql = "select * from t_user"; /* * 提供默认实现类 ParameterizedBeanPropertyRowMapper , javabean属性和表的字段必须一致 ParameterizedBeanPropertyRowMapper将结果集通过java的反射机制映射到java对象中 */ RowMapper<User> rowMapper = ParameterizedBeanPropertyRowMapper .newInstance(User.class); //使用query方法执行查询,并返回一个集合 return this.jdbcTemplate.query(sql, rowMapper); }
3.2.5 Spring配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 1配置数据源 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <!--数据库驱动 --> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <!--连接数据库的url --> <property name="url" value="jdbc:mysql://localhost/jdbc_template"/> <!--连接数据库的用户名 --> <property name="username" value="root"/> <!--连接数据库的密码 --> <property name="password" value="1122"/> </bean> <!-- 2配置Jdbc模板 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean> <!--将jdbcTemplate对象注入到userDao实现类中 --> <bean id="userDao" class="com.tcxpz.spring_pro8.jdbc_template.UserDaoImpl"> <property name="jdbcTemplate" ref="jdbcTemplate"/> </bean> </beans>
3.2.6 测试
3.6.2.1 execute()方法
execute(String sql)方法能够完成执行SQL语句的功能。
我们可以直接从Spring容器中获得JdbcTemplate实例对象,用这个对象的execute()方法对数据库进行操作。
public class TestJdbcTemplate { @Test public void executeTest(){ String xmlPath = "applicationContext.xml"; ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath); JdbcTemplate jdbcTemplate = (JdbcTemplate) applicationContext.getBean("jdbcTemplate"); jdbcTemplate.execute("insert into t_user(username,password) values('rose','6789')"); } }
测试结果:
3.6.2.2 update()方法
update()方法可以完成插入、更新和删除的操作。
public class TestJdbcTemplate { @Test public void addUserTest(){ String xmlPath = "applicationContext.xml"; ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath); UserDao userDao = (UserDao) applicationContext.getBean("userDao"); User user = new User(); user.setUsername("jack"); user.setPassword("1234"); int flag = userDao.addUser(user); if(flag == 1){ System.out.println("添加用户成功"); }else{ System.out.println("添加用户失败"); } } }
测试结果:
public class TestJdbcTemplate { @Test public void updateUserTest(){ String xmlPath = "applicationContext.xml"; ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath); UserDao userDao = (UserDao) applicationContext.getBean("userDao"); //User user = userDao.findUserById(1); User user = new User(); user.setUid(1); user.setUsername("tom"); user.setPassword("1111"); //调用userDao中的updateUser()方法执行更新 int flag = userDao.updateUser(user); if(flag == 1){ System.out.println("修改用户成功"); }else{ System.out.println("修改用户失败"); } } }
测试结果:
public class TestJdbcTemplate { @Test public void deleteUserTest(){ String xmlPath = "applicationContext.xml"; ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath); UserDao userDao = (UserDao) applicationContext.getBean("userDao"); int flag = userDao.deleteUserById(1); if(flag == 1){ System.out.println("删除用户成功"); }else{ System.out.println("删除用户失败"); } } }
测试结果:
public class TestJdbcTemplate { @Test public void findUserByIdTest(){ String xmlPath = "applicationContext.xml"; ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath); UserDao userDao = (UserDao) applicationContext.getBean("userDao"); User user = userDao.findUserById(2); System.out.println(user); } }
测试结果:
public class TestJdbcTemplate { @Test public void findAllUserTest(){ String xmlPath = "applicationContext.xml"; ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath); UserDao userDao = (UserDao) applicationContext.getBean("userDao"); List<User> user = userDao.findAllUser(); for(User u : user){ System.out.println(u); } } }
在做这个测试之前先添加几条记录,如下
测试结果:
4 使用JdbcDaoSupport
4.1 概述
在上面的项目中,我们往userDao中注入jdbcTemplate,在jdbcTemplate中注入数据源
那我们能不能在userDao中直接注入数据源,然后得到一个带有jdbcTemplate模板的userDao呢?
答案是肯定的。JdbcDaoSupport这个类中有一个方法,你给他注入一个数据源,他就能给你返回一个JdbcTemplate实例对象,
只要我们的UserDaoImpl继承了JdbcDaoSupport,那我们的UserDaoImpl中理所当然也会有这个方法。
所以,我们只需要往UserDaoImpl中注入一个数据源对象,就能通过this.getJdbcTemplate()方法得到一个JdbcTemplate实例对象,
并且在父类中已经提供了setter方法,UserDaoImpl中连setter方法都不用写了。
如果不理解的话,再看一下源码吧
4.2 项目搭建及测试
在以上的项目中,都可以通过properties文件对数据源四大参数进行配置,所以这里我准备通过properties文件对数据源进行配置。
4.2.1 创建表
懒得重新创建表了,这里就用上一个项目的表吧。
4.2.2 域模型
与上一个项目相同
public class User { private Integer uid; //用户id private String username; //用户名 private String password; //密码 public Integer getUid() { return uid; } public void setUid(Integer uid) { this.uid = uid; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "UserDao [uid=" + uid + ", username=" + username + ", password=" + password + "]"; } }
4.2.3 导入jar包
与上一个项目导入的jar包相同
4.2.4 DAO接口和实现类
区别主要在实现类UserDaoImpl.java(这里删除了上一个项目的几个方法,偷个懒,哈哈)
public interface UserDao { public User findUserById( int id); public List<User> findAllUser(); }
public class UserDaoImpl extends JdbcDaoSupport implements UserDao{ @Override public User findUserById(int id) { String sql = "select * from t_user where uid = ?"; RowMapper<User> rowMapper = ParameterizedBeanPropertyRowMapper.newInstance(User.class); return this.getJdbcTemplate().queryForObject(sql, rowMapper, id); } @Override public List<User> findAllUser() { String sql = "select * from t_user"; RowMapper<User> rowMapper = ParameterizedBeanPropertyRowMapper.newInstance(User.class); return this.getJdbcTemplate().query(sql, rowMapper); } }
4.2.5 properties配置文件
4.2.6 Spring配置文件
(1)导入命名空间
(2)加载配置文件
<?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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 加载配置文件 "classpath:"前缀表示 src下 --> <context:property-placeholder location="classpath:jdbcInfo.properties"/> <!-- 创建数据源 c3p0--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}"></property> <property name="url" value="${jdbc.url}"></property> <property name="username" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> </bean> <!--将dataSource对象注入到userDao实现类中 --> <bean id="userDao" class="com.tcxpz.spring_pro9.c3p0.UserDaoImpl"> <property name="dataSource" ref="dataSource"/> </bean> </beans>
4.2.7 测试
public class TestJdbcTemplate { @Test public void findUserByIdTest(){ String xmlPath = "applicationContext.xml"; ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath); UserDao userDao = (UserDao) applicationContext.getBean("userDao"); User user = userDao.findUserById(3); System.out.println(user); } }
测试结果:
public class TestJdbcTemplate { @Test public void findAllUserTest(){ String xmlPath = "applicationContext.xml"; ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath); UserDao userDao = (UserDao) applicationContext.getBean("userDao"); List<User> user = userDao.findAllUser(); for(User u : user){ System.out.println(u); } } }
测试结果:
5 使用DBCP或者C3P0
上面的几个项目中我们都是利用spring-jdbc-3.2.2.RELEASE.jar对JDBC的支持获得DriverManageDataSource对象
如果我们要使用DBCP或者C3P0数据源获得连接对象呢,就要注意以下几点了
(1)导包 DBCP需要再导入两个jar包:实现+依赖,C3P0也需要导入一个jar包。
(2)四大参数名 要注意不同数据源的四个参数名分别是什么。
使用DBCP方式
使用C3P0方式