1、JdbcTemplate简介
Spring的官方介绍里开头如是说道
This is the central class in the JDBC core package. It simplifies the use of JDBC and helps to avoid common errors.
这是jdbc核心包的核心类,它简化了jdbc的使用并帮助人们避免一些一般的错误
2、怎么配置JdbcTemplate
首先,我们需要配置一个数据源
确定你要使用的数据库连接池
在applicationContext.xml配置文件里配置数据库连接池,即数据源
这里我将使用c3p0连接池
<!-- 配置数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="user"></property>
<property name="password" value="password"></property>
<property name="driverClass" value="driverClass"></property>
<property name="jdbcUrl" value="jdbcUrl"></property>
<property name="initialPoolSize" value="initialPoolSize"></property>
<property name="maxPoolSize" value="maxPoolSize"></property>
</bean>
当然你也可以使用一个单独的数据库参数配置文件来配置,比如
- 首先你要创建一个参数配置文件,比如db.properties
jdbc.user=root
jdbc.password=1234
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql:///springjdbc
jdbc.initialPoolSize=5
jdbc.maxPoolSize=10
- 此时配置数据源
<!-- 配置数据源 -->
<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="driverClass" value="${jdbc.driverClass}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="initialPoolSize" value="${jdbc.initialPoolSize}"></property>
<property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
</bean>
- 配置JdbcTemplate的bean
<!-- 配置JDBC Template -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
3、怎么使用JdbcTemplate
- 首先,当然是在你需要的类文件里获得这个bean
private ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
private JdbcTemplate jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");
接下来就是JdbcTemplate的一些方法
JdbcTemplate的方法主要分为三大类
- update
- query
- execute
execute类型的方法在此不做赘述,主要说明update和query
1)更新
此类方法用作SQL的INSERT、UPDATE、DELETE,而update又分为update(更新)和batchUpdate(批量更新)
update
不具名参数
一般来说,下面这个方法就满足了我们的需求
update(String, Object...)
这里的第一个参数传入的是一个SQL,接下来的参数是SQL的占位符参数,具体使用可以参考下面代码
String sql = "INSERT INTO employees (id, name, email, dept_id) VALUES (NULL ,?, ?,?)";
jdbcTemplate.update(sql, "Eclipse", "eclipse@e.com", 1);
需要注意的是,占位符与参数的对应关系应该一一对应。
具名参数
但是,JdbcTemplate还支持具名参数的update,如果你的SQL像下面这样
String sql = "INSERT INTO employees (id, name, email, dept_id) VALUES (NULL ,:name, :email, :deptid)";
那么你需要另外一个NamedParameterJdbcTemplate
来支持具名参数的SQL执行
同样的,你需要在applicationContext.xml里面配置这个bean
<!-- 配置Named JDBC Template -->
<bean id="namedJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="dataSource"></constructor-arg>
</bean>
注意,里面不再是property
而是constructor-arg
然后上面那个SQL只需要按照下面这种格式就可以执行了
String sql = "INSERT INTO employees (id, name, email, dept_id) VALUES (NULL ,:name, :email, :deptid)";
Map<String,Object> paramMap = new HashMap<>();
paramMap.put("name", "John");
paramMap.put("email", "john@e.com");
paramMap.put("deptid", 1);
namedJdbcTemplate.update(sql,paramMap);
在这里看来,操作的似乎更复杂了,但是与此同时他还有另外一个用法
String sql = "INSERT INTO employees (id, name, email, dept_id) VALUES (NULL ,:name, :email, :deptid)";
Employee employee = new Employee();
employee.setName("Tom");
employee.setEmail("tom@email.com");
employee.setDeptid(2);
SqlParameterSource paramSource = new BeanPropertySqlParameterSource(employee);
namedJdbcTemplate.update(sql, paramSource);
用一个对象来更新,是不是比较好用了。
这里需要注意的有两点:
Employee
类的字段名应该和SQL中名字一致,当然指的是:name
这种- 需要提交的对象需要用
BeanPropertySqlParameterSource
包装一下
batchUpdate
不具名参数
批量更新采用的当然也可以使用不具名的SQL,就像这样
String sql = "INSERT INTO employees (id, name, email, dept_id) VALUES (NULL ,?, ?,?)";
List<Object[]> batchArgs = new ArrayList<>();
batchArgs.add(new Object[] { "Eclipse-batch-1", "eclipse-1@e.com", 1 });
batchArgs.add(new Object[] { "Eclipse-batch-2", "eclipse-2@e.com", 1 });
batchArgs.add(new Object[] { "Eclipse-batch-3", "eclipse-3@e.com", 2 });
batchArgs.add(new Object[] { "Eclipse-batch-4", "eclipse-4@e.com", 3 });
batchArgs.add(new Object[] { "Eclipse-batch-5", "eclipse-5@e.com", 1 });
jdbcTemplate.batchUpdate(sql, batchArgs);
具名参数
也可以用具名参数
String sql = "INSERT INTO employees (id, name, email, dept_id) VALUES (NULL ,:name, :email, :deptid)";
Employee employee = null;
List<SqlParameterSource> sParameterSources = new ArrayList<>();
SqlParameterSource paramSource;
// 这里是为了测试,才用这种方法来造了一堆数据
for (int i = 0; i < 10; i++) {
employee = new Employee();
employee.setName("Tom-" + i);
employee.setEmail("tom" + i +"@email.com");
employee.setDeptid(2);
paramSource = new BeanPropertySqlParameterSource(employee);
sParameterSources.add(paramSource);
}
// 第二个参数传入的是SqlParameterSource数组
namedJdbcTemplate.batchUpdate(sql, sParameterSources.toArray(new SqlParameterSource[sParameterSources.size()]));
2)查找
此类方法用作SQL的SELECT,并且同样适用具名与不具名两种方式
不具名参数
返回一个对象
String sql = "SELECT id, name, email FROM employees WHERE id = ?";
RowMapper<Employee> rowMapper = new BeanPropertyRowMapper<>(Employee.class);
Employee employee = jdbcTemplate.queryForObject(sql, rowMapper, 1);
需要注意的是
SQL里面的字段应该与
Employee
类里面的字段名一致需要一个一个映射器
BeanPropertyRowMapper
来指明映射关系,而且传给jdbcTemplate的参数也是BeanPropertyRowMapper的对象不是调用 queryForObject(String sql, Class requiredType, Object... args) 方法!
而需要调用 queryForObject(String sql, RowMapper rowMapper, Object... args)
返回一个列表
String sql = "SELECT id, name, email FROM employees WHERE id > ?";
RowMapper<Employee> rowMapper = new BeanPropertyRowMapper<>(Employee.class);
List<Employee> employees = jdbcTemplate.query(sql, rowMapper, 5);
这里同样需要注意调用的方法,不是 queryForList(String sql, Object[] args, int[] argTypes)
方法,而是query(String sql, RowMapper<Employee> rowMapper, Object... args)
返回一个特殊的值
String sql = "SELECT count(id) FROM employees";
long count = jdbcTemplate.queryForObject(sql, Long.class);
这里调用的是queryForObject(String, Class<T>)
,当SQL里面有参数时可以调用这个方法queryForObject(String, Class<T>, Object...)
具名参数
具名参数的操作方法与前面的更新操作大同小异,小心注意调用方法的参数类型一般不会出什么错