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#接口的描述,发现大家对例子的说明不是太容易让我们这些新人理解 ...
随机推荐
- win7系统 无线上网卡 共享网络,设置成wifi热点
给家人买了一个新的智能手机,用的移动神州行套餐,没有开通3G,想更新一些应用软件,于是想到能不能用电脑上的无线上网卡. 在网上找到了一方法,试了一下,还真是可以. 步骤如下: 用无线上网卡拨号上网,并 ...
- 简单DP入门四连发
复习一下一直不太懂的dp. dp博大精深,路还长着呢 第一题;http://acm.hdu.edu.cn/showproblem.php?pid=2084 从下往上就是水题 #include<c ...
- libusb开发
转:https://www.cnblogs.com/ele-eye/p/3261970.html
- SQL语句的三大类
数据定义语言(DDL Data Defination Language):用于创建和定义数据库对象,并且将对这些对象的定义保存到数据库字典中,通过DDL语句可以创建数据库对象.修改数据库对象.删除数据 ...
- Vue学习笔记:基础
Vue实例 每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始的 插值 数据绑定最常见的形式就是使用“Mustache”语法(双大括号)的文本插值 指令 指令的定义:Direct ...
- Python中sys和os模块的区别
sys: This module provides access to some variables used or maintained by the interpreter and to func ...
- c# 通过按钮获取文件夹和打开磁盘文件
Button控件获取文件夹: FolderBrowserDialog fileDialog = new FolderBrowserDialog(); if (fileDialog.ShowDialog ...
- 【转】Centos 7 修改主机名hostname
在CentOS中,有三种定义的主机名:静态的(static),瞬态的(transient),和灵活的(pretty).“静态”主机名也称为内核主机名,是系统在启动时从/etc/hostname自动初始 ...
- [zhuan]SQLServer查询最近一天,三天,一周,一月,一季度方法
三天 select * from T_news where datediff(day,addtime,getdate())<= 2 and datediff(day,addtime,getdat ...
- ajax +jsp+iframe无刷新上传文件[转]
http://hi.baidu.com/zj360202/blog/item/f23e3711f929c774cb80c475.html ajax jsp 无刷新上传文件 2009-10-26 16: ...