springJDBC和SpringJDBCTemplate解决方案探究
先来看一个纯JDBC的例子,体会一下springJDBC和SpringJDBCTemplate两者的区别
一个Customer类
package com.mkyong.customer.model; import java.sql.Timestamp; public class Customer
{
int custId;
String name;
int age; public Customer(int custId, String name, int age) {
this.custId = custId;
this.name = name;
this.age = age;
} public int getCustId() {
return custId;
}
public void setCustId(int custId) {
this.custId = custId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
} @Override
public String toString() {
return "Customer [age=" + age + ", custId=" + custId + ", name=" + name
+ "]";
} }
Dao类:
package com.mkyong.customer.dao; import com.mkyong.customer.model.Customer; public interface CustomerDAO
{
public void insert(Customer customer);
public Customer findByCustomerId(int custId);
}
DaoImpl类:
package com.mkyong.customer.dao.impl; import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException; import javax.sql.DataSource; import com.mkyong.customer.dao.CustomerDAO;
import com.mkyong.customer.model.Customer; public class JdbcCustomerDAO implements CustomerDAO
{
private DataSource dataSource; public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
} public void insert(Customer customer){ String sql = "INSERT INTO CUSTOMER " +
"(CUST_ID, NAME, AGE) VALUES (?, ?, ?)";
Connection conn = null; //每次都要重新声明一个conection try {
conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql); //每次都要进行conn.prepareStatment操作
ps.setInt(, customer.getCustId());
ps.setString(, customer.getName());
ps.setInt(, customer.getAge());
ps.executeUpdate(); //每次都要提交更新
ps.close(); //每次都要手动关闭数据库连接 } catch (SQLException e) { //每次都要进行异常处理。导致大量冗余的代码
throw new RuntimeException(e); } finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {}
}
}
} public Customer findByCustomerId(int custId){ String sql = "SELECT * FROM CUSTOMER WHERE CUST_ID = ?"; Connection conn = null; try {
conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(, custId);
Customer customer = null;
ResultSet rs = ps.executeQuery();
if (rs.next()) {
customer = new Customer(
rs.getInt("CUST_ID"),
rs.getString("NAME"),
rs.getInt("Age")
);
}
rs.close();
ps.close();
return customer;
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {}
}
}
}
}
上述的例子充满了大量的冗余代码。,CRUD操作都要对应的写:
conn.open(); conn.prepareStatment(); conn.close() 以及异常处理....等等
这样子显得非常多余,可以有更加优雅的解决方案吗? 废话当然有,Look~↓
提供了JdbcTemplate 来封装数据库jdbc操作细节:
包括: 数据库连接[打开/关闭] ,异常转义 ,SQL执行 ,查询结果的转换
使用模板方式封装 jdbc数据库操作-固定流程的动作,提供丰富callback回调接口功能,方便用户自定义加工细节,更好模块化jdbc操作,简化传统的JDBC操作的复杂和繁琐过程。
看下面代码:
package com.mkyong.customer.dao.impl; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils;
import org.springframework.jdbc.core.simple.ParameterizedBeanPropertyRowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport; import com.mkyong.customer.dao.CustomerDAO;
import com.mkyong.customer.model.Customer;
import com.mkyong.customer.model.CustomerParameterizedRowMapper; public class SimpleJdbcCustomerDAO extends SimpleJdbcDaoSupport implements CustomerDAO
{
//insert example
public void insert(Customer customer){ String sql = "INSERT INTO CUSTOMER " +
"(CUST_ID, NAME, AGE) VALUES (?, ?, ?)"; getSimpleJdbcTemplate().update(sql, customer.getCustId(),
customer.getName(),customer.getAge()
); } //insert with named parameter
public void insertNamedParameter(Customer customer){ String sql = "INSERT INTO CUSTOMER " +
"(CUST_ID, NAME, AGE) VALUES (:custId, :name, :age)"; Map<String, Object> parameters = new HashMap<String, Object>();
parameters.put("custId", customer.getCustId());
parameters.put("name", customer.getName());
parameters.put("age", customer.getAge()); getSimpleJdbcTemplate().update(sql, parameters); } //insert batch example
public void insertBatch(final List<Customer> customers){ String sql = "INSERT INTO CUSTOMER " +
"(CUST_ID, NAME, AGE) VALUES (?, ?, ?)"; List<Object[]> parameters = new ArrayList<Object[]>();
for (Customer cust : customers) {
parameters.add(new Object[] {cust.getCustId(), cust.getName(), cust.getAge()});
}
getSimpleJdbcTemplate().batchUpdate(sql, parameters); } //insert batch with named parameter
public void insertBatchNamedParameter(final List<Customer> customers){ String sql = "INSERT INTO CUSTOMER " +
"(CUST_ID, NAME, AGE) VALUES (:custId, :name, :age)"; List<SqlParameterSource> parameters = new ArrayList<SqlParameterSource>();
for (Customer cust : customers) { parameters.add(new BeanPropertySqlParameterSource(cust)); }
getSimpleJdbcTemplate().batchUpdate(sql,
parameters.toArray(new SqlParameterSource[]));
} //insert batch with named parameter
public void insertBatchNamedParameter2(final List<Customer> customers){ SqlParameterSource[] params = SqlParameterSourceUtils.createBatch(customers.toArray());
getSimpleJdbcTemplate().batchUpdate(
"INSERT INTO CUSTOMER (CUST_ID, NAME, AGE) VALUES (:custId, :name, :age)",
params); } //insert batch example with SQL
public void insertBatchSQL(final String sql){ getJdbcTemplate().batchUpdate(new String[]{sql}); } //query single row with ParameterizedRowMapper
public Customer findByCustomerId(int custId){ String sql = "SELECT * FROM CUSTOMER WHERE CUST_ID = ?"; Customer customer = getSimpleJdbcTemplate().queryForObject(
sql, new CustomerParameterizedRowMapper(), custId); return customer;
} //query single row with ParameterizedBeanPropertyRowMapper (Customer.class)
public Customer findByCustomerId2(int custId){ String sql = "SELECT * FROM CUSTOMER WHERE CUST_ID = ?"; Customer customer = getSimpleJdbcTemplate().queryForObject(
sql,ParameterizedBeanPropertyRowMapper.newInstance(Customer.class), custId); return customer;
} //query mutiple rows with ParameterizedBeanPropertyRowMapper (Customer.class)
public List<Customer> findAll(){ String sql = "SELECT * FROM CUSTOMER"; List<Customer> customers =
getSimpleJdbcTemplate().query(sql, ParameterizedBeanPropertyRowMapper.newInstance(Customer.class)); return customers;
} //query mutiple rows with ParameterizedBeanPropertyRowMapper (Customer.class)
public List<Customer> findAll2(){ String sql = "SELECT * FROM CUSTOMER"; List<Customer> customers =
getSimpleJdbcTemplate().query(sql, ParameterizedBeanPropertyRowMapper.newInstance(Customer.class)); return customers;
} public String findCustomerNameById(int custId){ String sql = "SELECT NAME FROM CUSTOMER WHERE CUST_ID = ?"; String name = getSimpleJdbcTemplate().queryForObject(
sql, String.class, custId); return name; } public int findTotalCustomer(){ String sql = "SELECT COUNT(*) FROM CUSTOMER"; int total = getSimpleJdbcTemplate().queryForInt(sql); return total;
} }
细心你,会发现JdbcTemplate的实例中有一系列的方法如:queryForXXX,update,delete大大简化了JDBC操作。
当然,还可以再进一步的优化一下,就是通过依赖注入,直接把jdbcTemplate注入到dao类的jdbcT字段。
快动手试试吧! 提示:Spring还提供了和Hibernate整合的SpringHibernateTemplate解决方案哦。
springJDBC和SpringJDBCTemplate解决方案探究的更多相关文章
- JavaScript异步编程解决方案探究
javascript的天生单线程特性,使得异步编程对它异常重要,早期的通常做法是用回调函数来解决.但是随着逻辑的复杂,和javascript在服务端的大显神通,使得我们很容易就陷入“回调陷井”的万丈深 ...
- MySQL MHA FailOver后,原Master节点自动以Slave角色加入解群的研究与实现
MHA是一套MySQL高可用管理软件,除了检测Master宕机后,提升候选Slave为New Master之外(漂虚拟IP),还会自动让其他Slave与New Master 建立复制关系.MHA Ma ...
- 对TCP连接被重置解决方案的探究
分类: 网络与安全 对TCP连接被重置解决方案的探究——跨过GFW通向自由网络的可行途径 2010年05月25日 星期二 上午 00:19 这个标题有点长——其实开始只想写破折号之前的部分,因为这种技 ...
- 【iOS发展-53】实例探究:scrollView使用方法和解决方案无法滚动核心
案例效果: (1)基本的就是练习scrollView的使用方法.界面里面的其它元素基本都是UIView和UIButton堆砌起来的. (2)主要用代码实现.当然,能够先用storyboard拖个scr ...
- jQuery中事件绑定到bind、live、delegate、on方法的探究
1. 给页面上的某个元素绑定事件,最初采用下面的方式实现: $(‘selector’).click(function(){ //code }); 缺点: 不能同时绑定多个事件,不能绑定动态的元素. 后 ...
- 业务安全通用解决方案——WAF数据风控
业务安全通用解决方案——WAF数据风控 作者:南浔@阿里云安全 “你们安全不要阻碍业务发展”.“这个安全策略降低用户体验,影响转化率”——这是甲方企业安全部门经常听到合作团队抱怨.但安全从业者加入公司 ...
- iOS中的预编译指令的初步探究
目录 文件包含 #include #include_next #import 宏定义 #define #undef 条件编译 #if #else #endif #if define #ifdef #i ...
- angular懒加载机制 刷新后无法回退解决方案
今天在项目中遇到一个很奇怪的问题,使用oclazyload来懒加载angular的模块,刷新页面后,单击回退按钮无法返回上一个页面.估计是使用懒加载机制销毁了angular内部的state关联,导致无 ...
- c#接口深入一步探究其作用,适合新人了解
前言 前一篇浅显的述说了一下c#接口的作用,并用了一个不怎么好的例子述说了一下.时隔一天,在看完大家的评论后我在论坛中查看了很多前辈们对c#接口的描述,发现大家对例子的说明不是太容易让我们这些新人理解 ...
随机推荐
- Python 官方文件
7.2. 文件读写 函数 open() 返回 文件对象,通常的用法需要两个参数:open(filename, mode). >>> f = open('workfile', 'w') ...
- C# 在网页中将Base64编码的字符串显示成图片
在写一个接口,返回的json里面有图片,是Base64编码的字符串. 测试接口的时候,发现原来在html显示,是直接可以将Base64编码的字符串显示成图片的. 格式如下: <img src=d ...
- 探索未知种族之osg类生物---呼吸分解之事件循环二
VPM矩阵 1.V 表示摄像机的观察矩阵(View Matrix),它的作用是把对象从世界坐标系变换到摄像机坐标系.因此,对于世界坐标系下的坐标值 worldCoord(x0, y0, z0),如果希 ...
- (O)阻止默认事件和阻止冒泡的应用场景
场景1:阻止默认事件 比如这样的一个需求 点击取消a标签按钮的时候会触发一些js动作,但是不能让这个a标签产生跳转行为, 所以需要在点击取消的时候 阻止冒泡,防止其跳转. <a id='ca ...
- [转载]linux中sed的用法
转自:http://www.cnblogs.com/emanlee/archive/2013/09/07/3307642.html sed命令行格式为: sed [-nefri] ‘ ...
- python -u
标准错误(std.err):直接打印到屏幕 标准输出(std.out):需要缓存后再输出到屏幕 sys.stdout.write("stdout1") sys.stderr.wri ...
- 使用GZipStream压缩和解压文件
最近做了一个用.NET里的GZipStream压缩解压缩gzip文件的小程序. GZipStream在System.IO.Compression底下,使用起来也很简单.虽然GZipStream是Str ...
- DOM-DOMTree-查找
1. 什么是DOM: Document Object Model 专门操作网页内容的API js=ES+DOM+BOM DOM是由W3C指定的API标准 为什么: 为了统一各个浏览器操作网页内容的AP ...
- PHP函数可变参数
PHP自定义函数中支持可变数量的参数 在PHP 5.5 及更早的版本中,使用函数func_num_args() , func_get_arg() , func_get_args()实现: 我们举个例子 ...
- JavaScript的进阶篇
一.Array对象.数组对象 1)创建数组对象 //Array 对象用于在单个的变量中存储多个值. //语法: //创建方式1: ,,]; //创建方式2: new Array(); // 创建数组时 ...