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#接口的描述,发现大家对例子的说明不是太容易让我们这些新人理解 ...
随机推荐
- 事件类型(js)
焦点事件:在页面获得或失去焦点时触发. 与document.hasFocus和document.activeElement属性配合,可以得到用户在页面的行踪. blur:元素失去焦点时触发.这个事件不 ...
- iOS.Objective-C.Dependency.Graphing-v0.1
当Project越来越复杂,模块间的依赖就会很复杂,不合理的依赖就出现:不必要的依赖,双向依赖等等. 在iOS Application Project中可以将依赖定义为:对某个头文件的import. ...
- javascript 高级程序设计 四
新的一天开始,让我们伴随者轻快的心情,开始今天的笔记 1.操作符: (1): *./.-在ECMAScript中操作的时候,如果遇到有一个操作值不是数值型(Number),那么就会在后台调用numbe ...
- Jenkins2.0中的pipeline
jenkins的实现是标准的master/slave模式,用户与master交互,master将job分布到slave上运行. jenkins的基本概念: 1. master, 也就是jenkins的 ...
- String、StringBuffer、StringBuilder和StringTokenizer的区别
1)String.StringBuffer.StringBuilder都用于字符串操作,其中,String是不可变类,即String对象一旦被创建,其值不能被修改,而StringBuffer和Stri ...
- Spring ApplicationContext(十)finishRefresh
ApplicationContext(十)finishRefresh Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) 经过 ...
- 微信JSSDK接口previewImage
<div class="pics"> <img src="http://pic1.ytqmx.com:82/2015/0409/01/15.jpg!96 ...
- one or more
想到以后如果一直都是这样,那么以后的生活是多么多么可怕啊. 感觉毫无期盼.没有意义. 如果变得理所当然那是多么多么让人害怕的事,吓得让人发抖. 所以在以后漫长的岁月里,还是一个人吧 如果相互看不惯,感 ...
- IT资产管理详解
- sql number类型和varchar2类型
查询时,发现org_id 为number类型,zone_id为varchar2类型,需要转化 转换 to_char(),或者to_number select a.id,b.col,a.col from ...