这个是别人写的,觉得受用,所以存下来。。。。
Spring的JDBC框架能够承担资源管理和异常处理的工作,从而简化我们的JDBC代码,
让我们只需编写从数据库读写数据所必需的代 码。Spring把数据访问的样板代码隐藏到模板类之下,
结合Spring的事务管理,可以大大简化我们的代码.
Spring提供了 3个模板类:
JdbcTemplate:Spring里最基本的JDBC模板,利用JDBC和简单的索引参数查询提供对数据库的简单访问。
NamedParameterJdbcTemplate: 能够在执行查询时把值绑定到SQL里的命名参数,而不是使用索引参数。
SimpleJdbcTemplate:利用Java 5的特性,比如自动装箱、通用(generic)和可变参数列表来简化JDBC模板的使用。
具体使用哪个模板基本上取决于个人喜好。
使 用Spring的JdbcTemplate来实现简单的增删改查,首先建立测试数据表person
create table person(
id int not null primary key auto_increment,
name varchar(20) not null
)
导入依赖的jar包,由于测试中数据源使用的是dbcp数据源,需要以下jar包支持:
commons-logging.jar
commons-pool.jar
commons-dbcp.jar
同时还必须导入数据库驱动jar包:mysql-connector-java-3.1.8- bin.jar
建立实体bean
Person.java
Java 代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://www.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=package%20com.royzhou.jdbc%3B%0A%0Apublic%20class%20PersonBean%20%7B%0A%09private%20int%20id%3B%0A%09private%20String%20name%3B%0A%0A%09public%20PersonBean()%20%7B%0A%09%7D%0A%09%0A%09public%20PersonBean(String%20name)%20%7B%0A%09%09this.name%20%3D%20name%3B%0A%09%7D%0A%09%0A%09public%20PersonBean(int%20id%2C%20String%20name)%20%7B%0A%09%09this.id%20%3D%20id%3B%0A%09%09this.name%20%3D%20name%3B%0A%09%7D%0A%09%20%0A%09public%20int%20getId()%20%7B%0A%09%09return%20id%3B%0A%09%7D%0A%0A%09public%20void%20setId(int%20id)%20%7B%0A%09%09this.id%20%3D%20id%3B%0A%09%7D%0A%0A%09public%20String%20getName()%20%7B%0A%09%09return%20name%3B%0A%09%7D%0A%0A%09public%20void%20setName(String%20name)%20%7B%0A%09%09this.name%20%3D%20name%3B%0A%09%7D%0A%09%0A%09public%20String%20toString()%20%7B%0A%09%09return%20this.id%20%2B%20%22%3A%22%20%2B%20this.name%3B%0A%09%7D%0A%7D%0A" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- package com.royzhou.jdbc;
-
- public class PersonBean {
- private int id;
- private String name;
-
- public PersonBean() {
- }
-
- public PersonBean(String name) {
- this .name = name;
- }
-
- public PersonBean( int id, String name) {
- this .id = id;
- this .name = name;
- }
-
- public int getId() {
- return id;
- }
-
- public void setId( int id) {
- this .id = id;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this .name = name;
- }
-
- public String toString() {
- return this .id + ":" + this .name;
- }
- }
package com.royzhou.jdbc;public class PersonBean { private int id; private String name; public PersonBean() { } public PersonBean(String name) { this.name = name; } public PersonBean(int id, String name) { this.id = id; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String toString() { return this.id + ":" + this.name; }}
接口类:
PersonService.java
Java 代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://www.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=package%20com.royzhou.jdbc%3B%0A%0Aimport%20java.util.List%3B%0A%0Apublic%20interface%20PersonService%20%7B%0A%09%0A%09public%20void%20addPerson(PersonBean%20person)%3B%0A%09%0A%09public%20void%20updatePerson(PersonBean%20person)%3B%0A%09%0A%09public%20void%20deletePerson(int%20id)%3B%0A%09%0A%09public%20PersonBean%20queryPerson(int%20id)%3B%0A%09%0A%09public%20List%3CPersonBean%3E%20queryPersons()%3B%0A%7D%0A" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- package com.royzhou.jdbc;
-
- import java.util.List;
-
- public interface PersonService {
-
- public void addPerson(PersonBean person);
-
- public void updatePerson(PersonBean person);
-
- public void deletePerson( int id);
-
- public PersonBean queryPerson( int id);
-
- public List<PersonBean> queryPersons();
- }
package com.royzhou.jdbc;import java.util.List;public interface PersonService { public void addPerson(PersonBean person); public void updatePerson(PersonBean person); public void deletePerson(int id); public PersonBean queryPerson(int id); public List<PersonBean> queryPersons();}
实现类:
PersonServiceImpl.java
Java 代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://www.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=package%20com.royzhou.jdbc%3B%0A%0Aimport%20java.util.List%3B%0A%0Aimport%20javax.sql.DataSource%3B%0Aimport%20java.sql.Types%3B%0A%0Aimport%20org.springframework.jdbc.core.JdbcTemplate%3B%0A%0Apublic%20class%20PersonServiceImpl%20implements%20PersonService%20%7B%0A%0A%09private%20JdbcTemplate%20jdbcTemplate%3B%0A%09%0A%09%2F**%0A%09%20*%20%E9%80%9A%E8%BF%87Spring%E5%AE%B9%E5%99%A8%E6%B3%A8%E5%85%A5datasource%0A%09%20*%20%E5%AE%9E%E4%BE%8B%E5%8C%96JdbcTemplate%2C%E8%AF%A5%E7%B1%BB%E4%B8%BA%E4%B8%BB%E8%A6%81%E6%93%8D%E4%BD%9C%E6%95%B0%E6%8D%AE%E5%BA%93%E7%9A%84%E7%B1%BB%0A%09%20*%20%40param%20ds%0A%09%20*%2F%0A%09public%20void%20setDataSource(DataSource%20ds)%20%7B%0A%09%09this.jdbcTemplate%20%3D%20new%20JdbcTemplate(ds)%3B%0A%09%7D%0A%09%0A%09public%20void%20addPerson(PersonBean%20person)%20%7B%0A%09%09%2F**%0A%09%09%20*%20%E7%AC%AC%E4%B8%80%E4%B8%AA%E5%8F%82%E6%95%B0%E4%B8%BA%E6%89%A7%E8%A1%8Csql%0A%09%09%20*%20%E7%AC%AC%E4%BA%8C%E4%B8%AA%E5%8F%82%E6%95%B0%E4%B8%BA%E5%8F%82%E6%95%B0%E6%95%B0%E6%8D%AE%0A%09%09%20*%20%E7%AC%AC%E4%B8%89%E4%B8%AA%E5%8F%82%E6%95%B0%E4%B8%BA%E5%8F%82%E6%95%B0%E7%B1%BB%E5%9E%8B%0A%09%09%20*%2F%0A%09%09jdbcTemplate.update(%22insert%20into%20person%20values(null%2C%3F)%22%2C%20new%20Object%5B%5D%7Bperson.getName()%7D%2C%20new%20int%5B%5D%7BTypes.VARCHAR%7D)%3B%0A%09%7D%0A%0A%09public%20void%20deletePerson(int%20id)%20%7B%0A%09%09jdbcTemplate.update(%22delete%20from%20person%20where%20id%20%3D%20%3F%22%2C%20new%20Object%5B%5D%7Bid%7D%2C%20new%20int%5B%5D%7BTypes.INTEGER%7D)%3B%0A%09%7D%0A%0A%09public%20PersonBean%20queryPerson(int%20id)%20%7B%0A%09%09%2F**%0A%09%09%20*%20new%20PersonRowMapper()%E6%98%AF%E4%B8%80%E4%B8%AA%E5%AE%9E%E7%8E%B0RowMapper%E6%8E%A5%E5%8F%A3%E7%9A%84%E7%B1%BB%2C%0A%09%09%20*%20%E6%89%A7%E8%A1%8C%E5%9B%9E%E8%B0%83%2C%E5%AE%9E%E7%8E%B0mapRow()%E6%96%B9%E6%B3%95%E5%B0%86rs%E5%AF%B9%E8%B1%A1%E8%BD%AC%E6%8D%A2%E6%88%90PersonBean%E5%AF%B9%E8%B1%A1%E8%BF%94%E5%9B%9E%0A%09%09%20*%2F%0A%09%09PersonBean%20pb%20%3D%20(PersonBean)%20jdbcTemplate.queryForObject(%22select%20id%2Cname%20from%20person%20where%20id%20%3D%20%3F%22%2C%20new%20Object%5B%5D%7Bid%7D%2C%20new%20PersonRowMapper())%3B%0A%09%09return%20pb%3B%0A%09%7D%0A%0A%09%40SuppressWarnings(%22unchecked%22)%0A%09public%20List%3CPersonBean%3E%20queryPersons()%20%7B%0A%09%09List%3CPersonBean%3E%20pbs%20%3D%20(List%3CPersonBean%3E)%20jdbcTemplate.query(%22select%20id%2Cname%20from%20person%22%2C%20new%20PersonRowMapper())%3B%0A%09%09return%20pbs%3B%0A%09%7D%0A%0A%09public%20void%20updatePerson(PersonBean%20person)%20%7B%0A%09%09jdbcTemplate.update(%22update%20person%20set%20name%20%3D%20%3F%20where%20id%20%3D%20%3F%22%2C%20new%20Object%5B%5D%7Bperson.getName()%2C%20person.getId()%7D%2C%20new%20int%5B%5D%7BTypes.VARCHAR%2C%20Types.INTEGER%7D)%3B%0A%09%7D%0A%7D%0A" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- package com.royzhou.jdbc;
-
- import java.util.List;
-
- import javax.sql.DataSource;
- import java.sql.Types;
-
- import org.springframework.jdbc.core.JdbcTemplate;
-
- public class PersonServiceImpl implements PersonService {
-
- private JdbcTemplate jdbcTemplate;
-
-
-
-
-
-
- public void setDataSource(DataSource ds) {
- this .jdbcTemplate = new JdbcTemplate(ds);
- }
-
- public void addPerson(PersonBean person) {
-
-
-
-
-
- jdbcTemplate.update("insert into person values(null,?)" , new Object[]{person.getName()}, new int []{Types.VARCHAR});
- }
-
- public void deletePerson( int id) {
- jdbcTemplate.update("delete from person where id = ?" , new Object[]{id}, new int []{Types.INTEGER});
- }
-
- public PersonBean queryPerson( int id) {
-
-
-
-
- PersonBean pb = (PersonBean) jdbcTemplate.queryForObject("select id,name from person where id = ?" , new Object[]{id}, new PersonRowMapper());
- return pb;
- }
-
- @SuppressWarnings ( "unchecked" )
- public List<PersonBean> queryPersons() {
- List<PersonBean> pbs = (List<PersonBean>) jdbcTemplate.query("select id,name from person" , new PersonRowMapper());
- return pbs;
- }
-
- public void updatePerson(PersonBean person) {
- jdbcTemplate.update("update person set name = ? where id = ?" , new Object[]{person.getName(), person.getId()}, new int []{Types.VARCHAR, Types.INTEGER});
- }
- }
package com.royzhou.jdbc;import java.util.List;import javax.sql.DataSource;import java.sql.Types;import org.springframework.jdbc.core.JdbcTemplate;public class PersonServiceImpl implements PersonService { private JdbcTemplate jdbcTemplate; /** * 通过Spring容器注入datasource * 实例化JdbcTemplate,该类为主要操作数据库的类 * @param ds */ public void setDataSource(DataSource ds) { this.jdbcTemplate = new JdbcTemplate(ds); } public void addPerson(PersonBean person) { /** * 第一个参数为执行sql * 第二个参数为参数数据 * 第三个参数为参数类型 */ jdbcTemplate.update("insert into person values(null,?)", new Object[]{person.getName()}, new int[]{Types.VARCHAR}); } public void deletePerson(int id) { jdbcTemplate.update("delete from person where id = ?", new Object[]{id}, new int[]{Types.INTEGER}); } public PersonBean queryPerson(int id) { /** * new PersonRowMapper()是一个实现RowMapper接口的类, * 执行回调,实现mapRow()方法将rs对象转换成PersonBean对象返回 */ PersonBean pb = (PersonBean) jdbcTemplate.queryForObject("select id,name from person where id = ?", new Object[]{id}, new PersonRowMapper()); return pb; } @SuppressWarnings("unchecked") public List<PersonBean> queryPersons() { List<PersonBean> pbs = (List<PersonBean>) jdbcTemplate.query("select id,name from person", new PersonRowMapper()); return pbs; } public void updatePerson(PersonBean person) { jdbcTemplate.update("update person set name = ? where id = ?", new Object[]{person.getName(), person.getId()}, new int[]{Types.VARCHAR, Types.INTEGER}); }}
PersonRowMapper.java
Java 代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://www.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=package%20com.royzhou.jdbc%3B%0A%0Aimport%20java.sql.ResultSet%3B%0Aimport%20java.sql.SQLException%3B%0A%0Aimport%20org.springframework.jdbc.core.RowMapper%3B%0A%0Apublic%20class%20PersonRowMapper%20implements%20RowMapper%20%7B%0A%09%2F%2F%E9%BB%98%E8%AE%A4%E5%B7%B2%E7%BB%8F%E6%89%A7%E8%A1%8Crs.next()%2C%E5%8F%AF%E4%BB%A5%E7%9B%B4%E6%8E%A5%E5%8F%96%E6%95%B0%E6%8D%AE%0A%09public%20Object%20mapRow(ResultSet%20rs%2C%20int%20index)%20throws%20SQLException%20%7B%0A%09%09PersonBean%20pb%20%3D%20new%20PersonBean(rs.getInt(%22id%22)%2Crs.getString(%22name%22))%3B%0A%09%09return%20pb%3B%0A%09%7D%0A%7D%0A" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- package com.royzhou.jdbc;
-
- import java.sql.ResultSet;
- import java.sql.SQLException;
-
- import org.springframework.jdbc.core.RowMapper;
-
- public class PersonRowMapper implements RowMapper {
-
- public Object mapRow(ResultSet rs, int index) throws SQLException {
- PersonBean pb = new PersonBean(rs.getInt( "id" ),rs.getString( "name" ));
- return pb;
- }
- }
package com.royzhou.jdbc;import java.sql.ResultSet;import java.sql.SQLException;import org.springframework.jdbc.core.RowMapper;public class PersonRowMapper implements RowMapper { //默认已经执行rs.next(),可以直接取数据 public Object mapRow(ResultSet rs, int index) throws SQLException { PersonBean pb = new PersonBean(rs.getInt("id"),rs.getString("name")); return pb; }}
我们需要在bean.xml中配置DataSource,并且将datasource注入到我们的业务类中
Xml代 码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://www.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%0A%3Cbeans%20xmlns%3D%22http%3A%2F%2Fwww.springframework.org%2Fschema%2Fbeans%22%0A%20%20%20%20%20%20%20xmlns%3Axsi%3D%22http%3A%2F%2Fwww.w3.org%2F2001%2FXMLSchema-instance%22%0A%20%20%20%20%20%20%20xmlns%3Acontext%3D%22http%3A%2F%2Fwww.springframework.org%2Fschema%2Fcontext%22%20%0A%20%20%20%20%20%20%20xmlns%3Aaop%3D%22http%3A%2F%2Fwww.springframework.org%2Fschema%2Faop%22%0A%20%20%20%20%20%20%20xsi%3AschemaLocation%3D%22http%3A%2F%2Fwww.springframework.org%2Fschema%2Fbeans%0A%20%20%20%20%20%20%20%20%20%20%20http%3A%2F%2Fwww.springframework.org%2Fschema%2Fbeans%2Fspring-beans-2.5.xsd%0A%20%20%20%20%20%20%20%20%20%20%20http%3A%2F%2Fwww.springframework.org%2Fschema%2Fcontext%20http%3A%2F%2Fwww.springframework.org%2Fschema%2Fcontext%2Fspring-context-2.5.xsd%0A%20%20%20%20%20%20%20%20%20%20%20http%3A%2F%2Fwww.springframework.org%2Fschema%2Faop%20http%3A%2F%2Fwww.springframework.org%2Fschema%2Faop%2Fspring-aop-2.5.xsd%22%3E%0A%0A%09%20%3Ccontext%3Aproperty-placeholder%20location%3D%22classpath%3Ajdbc.properties%22%2F%3E%0A%09%20%3Cbean%20id%3D%22dataSource%22%20class%3D%22org.apache.commons.dbcp.BasicDataSource%22%20destroy-method%3D%22close%22%3E%0A%09%20%20%20%20%3Cproperty%20name%3D%22driverClassName%22%20value%3D%22%24%7BdriverClassName%7D%22%2F%3E%0A%09%20%20%20%20%3Cproperty%20name%3D%22url%22%20value%3D%22%24%7Burl%7D%22%2F%3E%0A%09%20%20%20%20%3Cproperty%20name%3D%22username%22%20value%3D%22%24%7Busername%7D%22%2F%3E%0A%09%20%20%20%20%3Cproperty%20name%3D%22password%22%20value%3D%22%24%7Bpassword%7D%22%2F%3E%0A%09%20%20%20%20%20%3C!--%20%E8%BF%9E%E6%8E%A5%E6%B1%A0%E5%90%AF%E5%8A%A8%E6%97%B6%E7%9A%84%E5%88%9D%E5%A7%8B%E5%80%BC%20--%3E%0A%09%09%20%3Cproperty%20name%3D%22initialSize%22%20value%3D%22%24%7BinitialSize%7D%22%2F%3E%0A%09%09%20%3C!--%20%E8%BF%9E%E6%8E%A5%E6%B1%A0%E7%9A%84%E6%9C%80%E5%A4%A7%E5%80%BC%20--%3E%0A%09%09%20%3Cproperty%20name%3D%22maxActive%22%20value%3D%22%24%7BmaxActive%7D%22%2F%3E%0A%09%09%20%3C!--%20%E6%9C%80%E5%A4%A7%E7%A9%BA%E9%97%B2%E5%80%BC.%E5%BD%93%E7%BB%8F%E8%BF%87%E4%B8%80%E4%B8%AA%E9%AB%98%E5%B3%B0%E6%97%B6%E9%97%B4%E5%90%8E%EF%BC%8C%E8%BF%9E%E6%8E%A5%E6%B1%A0%E5%8F%AF%E4%BB%A5%E6%85%A2%E6%85%A2%E5%B0%86%E5%B7%B2%E7%BB%8F%E7%94%A8%E4%B8%8D%E5%88%B0%E7%9A%84%E8%BF%9E%E6%8E%A5%E6%85%A2%E6%85%A2%E9%87%8A%E6%94%BE%E4%B8%80%E9%83%A8%E5%88%86%EF%BC%8C%E4%B8%80%E7%9B%B4%E5%87%8F%E5%B0%91%E5%88%B0maxIdle%E4%B8%BA%E6%AD%A2%20--%3E%0A%09%09%20%3Cproperty%20name%3D%22maxIdle%22%20value%3D%22%24%7BmaxIdle%7D%22%2F%3E%0A%09%09%20%3C!--%20%20%E6%9C%80%E5%B0%8F%E7%A9%BA%E9%97%B2%E5%80%BC.%E5%BD%93%E7%A9%BA%E9%97%B2%E7%9A%84%E8%BF%9E%E6%8E%A5%E6%95%B0%E5%B0%91%E4%BA%8E%E9%98%80%E5%80%BC%E6%97%B6%EF%BC%8C%E8%BF%9E%E6%8E%A5%E6%B1%A0%E5%B0%B1%E4%BC%9A%E9%A2%84%E7%94%B3%E8%AF%B7%E5%8E%BB%E4%B8%80%E4%BA%9B%E8%BF%9E%E6%8E%A5%EF%BC%8C%E4%BB%A5%E5%85%8D%E6%B4%AA%E5%B3%B0%E6%9D%A5%E6%97%B6%E6%9D%A5%E4%B8%8D%E5%8F%8A%E7%94%B3%E8%AF%B7%20--%3E%0A%09%09%20%3Cproperty%20name%3D%22minIdle%22%20value%3D%22%24%7BminIdle%7D%22%2F%3E%0A%09%20%3C%2Fbean%3E%0A%09%0A%3C%2Fbeans%3E%0A" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- <? 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"
- xmlns:aop = "http://www.springframework.org/schema/aop"
- xsi:schemaLocation ="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
- http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
-
- < context:property-placeholder location = "classpath:jdbc.properties" />
- < bean id = "dataSource" class = "org.apache.commons.dbcp.BasicDataSource" destroy-method = "close" >
- < property name = "driverClassName" value = "${driverClassName}" />
- < property name = "url" value = "${url}" />
- < property name = "username" value = "${username}" />
- < property name = "password" value = "${password}" />
-
- < property name = "initialSize" value = "${initialSize}" />
-
- < property name = "maxActive" value = "${maxActive}" />
-
- < property name = "maxIdle" value = "${maxIdle}" />
-
- < property name = "minIdle" value = "${minIdle}" />
- </ bean >
-
- </ beans >
<?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" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> <context:property-placeholder location="classpath:jdbc.properties"/> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${driverClassName}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> <!-- 连接池启动时的初始值 --> <property name="initialSize" value="${initialSize}"/> <!-- 连接池的最大值 --> <property name="maxActive" value="${maxActive}"/> <!-- 最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 --> <property name="maxIdle" value="${maxIdle}"/> <!-- 最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请去一些连接,以免洪峰来时来不及申请 --> <property name="minIdle" value="${minIdle}"/> </bean> </beans>
jdbc.properties
Java 代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://www.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=driverClassName%3Dorg.gjt.mm.mysql.Driver%0Aurl%3Djdbc%3Amysql%3A%2F%2Flocalhost%3A3306%2Froyzhou%3FuseUnicode%3Dtrue%26characterEncoding%3DUTF-8%0Ausername%3Droot%0Apassword%3D123456%0AinitialSize%3D1%0AmaxActive%3D500%0AmaxIdle%3D2%0AminIdle%3D1%0A" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- driverClassName=org.gjt.mm.mysql.Driver
- url=jdbc:mysql:
- username=root
- password=123456
- initialSize=1
- maxActive=500
- maxIdle=2
- minIdle=1
driverClassName=org.gjt.mm.mysql.Driverurl=jdbc:mysql://localhost:3306/royzhou?useUnicode=true&characterEncoding=UTF-8username=rootpassword=123456initialSize=1maxActive=500maxIdle=2minIdle=1
编 写我们的测试类:TestJdbcTemplate.java
Java 代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://www.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=package%20com.royzhou.jdbc%3B%0A%0Aimport%20org.springframework.context.ApplicationContext%3B%0Aimport%20org.springframework.context.support.ClassPathXmlApplicationContext%3B%0A%0Apublic%20class%20TestJdbcTemplate%20%7B%0A%09public%20static%20void%20main(String%5B%5D%20args)%20%7B%0A%09%09ApplicationContext%20ctx%20%3D%20new%20ClassPathXmlApplicationContext(%22bean.xml%22)%3B%0A%09%09PersonService%20ps%20%3D%20(PersonService)ctx.getBean(%22personService%22)%3B%0A%09%09ps.addPerson(new%20PersonBean(%22royzhou%22))%3B%0A%09%09PersonBean%20pb%20%3D%20ps.queryPerson(1)%3B%0A%09%09System.out.println(pb)%3B%0A%09%09pb.setName(%22haha%22)%3B%0A%09%09ps.updatePerson(pb)%3B%0A%09%09pb%20%3D%20ps.queryPerson(1)%3B%0A%09%09System.out.println(pb)%3B%0A%09%09ps.deletePerson(1)%3B%0A%09%09pb%20%3D%20ps.queryPerson(1)%3B%0A%09%09System.out.println(pb)%3B%0A%09%7D%0A%7D%0A" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- package com.royzhou.jdbc;
-
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
-
- public class TestJdbcTemplate {
- public static void main(String[] args) {
- ApplicationContext ctx = new ClassPathXmlApplicationContext( "bean.xml" );
- PersonService ps = (PersonService)ctx.getBean("personService" );
- ps.addPerson(new PersonBean( "royzhou" ));
- PersonBean pb = ps.queryPerson(1 );
- System.out.println(pb);
- pb.setName("haha" );
- ps.updatePerson(pb);
- pb = ps.queryPerson(1 );
- System.out.println(pb);
- ps.deletePerson(1 );
- pb = ps.queryPerson(1 );
- System.out.println(pb);
- }
- }
package com.royzhou.jdbc;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestJdbcTemplate { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml"); PersonService ps = (PersonService)ctx.getBean("personService"); ps.addPerson(new PersonBean("royzhou")); PersonBean pb = ps.queryPerson(1); System.out.println(pb); pb.setName("haha"); ps.updatePerson(pb); pb = ps.queryPerson(1); System.out.println(pb); ps.deletePerson(1); pb = ps.queryPerson(1); System.out.println(pb); }}
上面代码先插入一条记录,然后修改,之后删除,运行之后出现异常,异常信息:
EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0
难道Spring的 queryForObject在查找不到记录的时候会抛出异常,看了一下Spring的源代码 发现确实如此:
Java 代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://www.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=public%20Object%20queryForObject(String%20sql%2C%20Object%5B%5D%20args%2C%20int%5B%5D%20argTypes%2C%20RowMapper%20rowMapper)%20throws%20DataAccessException%20%7B%0A%09%09List%20results%20%3D%20(List)%20query(sql%2C%20args%2C%20argTypes%2C%20new%20RowMapperResultSetExtractor(rowMapper%2C%201))%3B%0A%09%09return%20DataAccessUtils.requiredUniqueResult(results)%3B%0A%09%7D%0A%0A%09public%20Object%20queryForObject(String%20sql%2C%20Object%5B%5D%20args%2C%20RowMapper%20rowMapper)%20throws%20DataAccessException%20%7B%0A%09%09List%20results%20%3D%20(List)%20query(sql%2C%20args%2C%20new%20RowMapperResultSetExtractor(rowMapper%2C%201))%3B%0A%09%09return%20DataAccessUtils.requiredUniqueResult(results)%3B%0A%09%7D%0A%0A%09public%20Object%20queryForObject(String%20sql%2C%20RowMapper%20rowMapper)%20throws%20DataAccessException%20%7B%0A%09%09List%20results%20%3D%20query(sql%2C%20rowMapper)%3B%0A%09%09return%20DataAccessUtils.requiredUniqueResult(results)%3B%0A%09%7D%0A%0A%09public%20static%20Object%20requiredUniqueResult(Collection%20results)%20throws%20IncorrectResultSizeDataAccessException%20%7B%0A%09%09int%20size%20%3D%20(results%20!%3D%20null%20%3F%20results.size()%20%3A%200)%3B%0A%09%09if%20(size%20%3D%3D%200)%20%7B%0A%09%09%09throw%20new%20EmptyResultDataAccessException(1)%3B%20%2F%2F%20%E9%97%AE%E9%A2%98%E5%9C%A8%E8%BF%99%E9%87%8C%0A%09%09%7D%0A%09%09if%20(!CollectionUtils.hasUniqueObject(results))%20%7B%0A%09%09%20%20%20%20throw%20new%20IncorrectResultSizeDataAccessException(1%2C%20size)%3B%0A%09%09%7D%0A%09%09return%20results.iterator().next()%3B%0A%09%7D%0A" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- public Object queryForObject(String sql, Object[] args, int [] argTypes, RowMapper rowMapper) throws DataAccessException {
- List results = (List) query(sql, args, argTypes, new RowMapperResultSetExtractor(rowMapper, 1 ));
- return DataAccessUtils.requiredUniqueResult(results);
- }
-
- public Object queryForObject(String sql, Object[] args, RowMapper rowMapper) throws DataAccessException {
- List results = (List) query(sql, args, new RowMapperResultSetExtractor(rowMapper, 1 ));
- return DataAccessUtils.requiredUniqueResult(results);
- }
-
- public Object queryForObject(String sql, RowMapper rowMapper) throws DataAccessException {
- List results = query(sql, rowMapper);
- return DataAccessUtils.requiredUniqueResult(results);
- }
-
- public static Object requiredUniqueResult(Collection results) throws IncorrectResultSizeDataAccessException {
- int size = (results != null ? results.size() : 0 );
- if (size == 0 ) {
- throw new EmptyResultDataAccessException( 1 );
- }
- if (!CollectionUtils.hasUniqueObject(results)) {
- throw new IncorrectResultSizeDataAccessException( 1 , size);
- }
- return results.iterator().next();
- }
public Object queryForObject(String sql, Object[] args, int[] argTypes, RowMapper rowMapper) throws DataAccessException { List results = (List) query(sql, args, argTypes, new RowMapperResultSetExtractor(rowMapper, 1)); return DataAccessUtils.requiredUniqueResult(results); } public Object queryForObject(String sql, Object[] args, RowMapper rowMapper) throws DataAccessException { List results = (List) query(sql, args, new RowMapperResultSetExtractor(rowMapper, 1)); return DataAccessUtils.requiredUniqueResult(results); } public Object queryForObject(String sql, RowMapper rowMapper) throws DataAccessException { List results = query(sql, rowMapper); return DataAccessUtils.requiredUniqueResult(results); } public static Object requiredUniqueResult(Collection results) throws IncorrectResultSizeDataAccessException { int size = (results != null ? results.size() : 0); if (size == 0) { throw new EmptyResultDataAccessException(1); // 问题在这里 } if (!CollectionUtils.hasUniqueObject(results)) { throw new IncorrectResultSizeDataAccessException(1, size); } return results.iterator().next(); }
发现当查找不到记录 是,requiredUniqueResult方法做了判断,抛出异 常, 想不明白为什么Spring要在这里做这样的判断,为啥不返回null????
重新修改 PersonServiceImple类,把queryPerson方法改为使用列表查询的方式再去根据index取
PersonServiceImpl.java
Java 代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://www.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=package%20com.royzhou.jdbc%3B%0A%0Aimport%20java.util.List%3B%0A%0Aimport%20javax.sql.DataSource%3B%0Aimport%20java.sql.Types%3B%0A%0Aimport%20org.springframework.jdbc.core.JdbcTemplate%3B%0A%0Apublic%20class%20PersonServiceImpl%20implements%20PersonService%20%7B%0A%0A%09private%20JdbcTemplate%20jdbcTemplate%3B%0A%09%0A%09%2F**%0A%09%20*%20%E9%80%9A%E8%BF%87Spring%E5%AE%B9%E5%99%A8%E6%B3%A8%E5%85%A5datasource%0A%09%20*%20%E5%AE%9E%E4%BE%8B%E5%8C%96JdbcTemplate%2C%E8%AF%A5%E7%B1%BB%E4%B8%BA%E4%B8%BB%E8%A6%81%E6%93%8D%E4%BD%9C%E6%95%B0%E6%8D%AE%E5%BA%93%E7%9A%84%E7%B1%BB%0A%09%20*%20%40param%20ds%0A%09%20*%2F%0A%09public%20void%20setDataSource(DataSource%20ds)%20%7B%0A%09%09this.jdbcTemplate%20%3D%20new%20JdbcTemplate(ds)%3B%0A%09%7D%0A%09%0A%09public%20void%20addPerson(PersonBean%20person)%20%7B%0A%09%09%2F**%0A%09%09%20*%20%E7%AC%AC%E4%B8%80%E4%B8%AA%E5%8F%82%E6%95%B0%E4%B8%BA%E6%89%A7%E8%A1%8Csql%0A%09%09%20*%20%E7%AC%AC%E4%BA%8C%E4%B8%AA%E5%8F%82%E6%95%B0%E4%B8%BA%E5%8F%82%E6%95%B0%E6%95%B0%E6%8D%AE%0A%09%09%20*%20%E7%AC%AC%E4%B8%89%E4%B8%AA%E5%8F%82%E6%95%B0%E4%B8%BA%E5%8F%82%E6%95%B0%E7%B1%BB%E5%9E%8B%0A%09%09%20*%2F%0A%09%09jdbcTemplate.update(%22insert%20into%20person%20values(null%2C%3F)%22%2C%20new%20Object%5B%5D%7Bperson.getName()%7D%2C%20new%20int%5B%5D%7BTypes.VARCHAR%7D)%3B%0A%09%7D%0A%0A%09public%20void%20deletePerson(int%20id)%20%7B%0A%09%09jdbcTemplate.update(%22delete%20from%20person%20where%20id%20%3D%20%3F%22%2C%20new%20Object%5B%5D%7Bid%7D%2C%20new%20int%5B%5D%7BTypes.INTEGER%7D)%3B%0A%09%7D%0A%0A%09%40SuppressWarnings(%22unchecked%22)%0A%09public%20PersonBean%20queryPerson(int%20id)%20%7B%0A%09%09%2F**%0A%09%09%20*%20new%20PersonRowMapper()%E6%98%AF%E4%B8%80%E4%B8%AA%E5%AE%9E%E7%8E%B0RowMapper%E6%8E%A5%E5%8F%A3%E7%9A%84%E7%B1%BB%2C%0A%09%09%20*%20%E6%89%A7%E8%A1%8C%E5%9B%9E%E8%B0%83%2C%E5%AE%9E%E7%8E%B0mapRow()%E6%96%B9%E6%B3%95%E5%B0%86rs%E5%AF%B9%E8%B1%A1%E8%BD%AC%E6%8D%A2%E6%88%90PersonBean%E5%AF%B9%E8%B1%A1%E8%BF%94%E5%9B%9E%0A%09%09%20*%2F%0A%09%09List%3CPersonBean%3E%20pbs%20%3D%20(List%3CPersonBean%3E)jdbcTemplate.query(%22select%20id%2Cname%20from%20person%20where%20id%20%3D%20%3F%22%2C%20new%20Object%5B%5D%7Bid%7D%2C%20new%20PersonRowMapper())%3B%0A%09%09PersonBean%20pb%20%3D%20null%3B%0A%09%09if(pbs.size()%3E0)%20%7B%0A%09%09%09pb%20%3D%20pbs.get(0)%3B%0A%09%09%7D%0A%09%09return%20pb%3B%0A%09%7D%0A%0A%09%40SuppressWarnings(%22unchecked%22)%0A%09public%20List%3CPersonBean%3E%20queryPersons()%20%7B%0A%09%09List%3CPersonBean%3E%20pbs%20%3D%20(List%3CPersonBean%3E)%20jdbcTemplate.query(%22select%20id%2Cname%20from%20person%22%2C%20new%20PersonRowMapper())%3B%0A%09%09return%20pbs%3B%0A%09%7D%0A%0A%09public%20void%20updatePerson(PersonBean%20person)%20%7B%0A%09%09jdbcTemplate.update(%22update%20person%20set%20name%20%3D%20%3F%20where%20id%20%3D%20%3F%22%2C%20new%20Object%5B%5D%7Bperson.getName()%2C%20person.getId()%7D%2C%20new%20int%5B%5D%7BTypes.VARCHAR%2C%20Types.INTEGER%7D)%3B%0A%09%7D%0A%7D%0A" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- package com.royzhou.jdbc;
-
- import java.util.List;
-
- import javax.sql.DataSource;
- import java.sql.Types;
-
- import org.springframework.jdbc.core.JdbcTemplate;
-
- public class PersonServiceImpl implements PersonService {
-
- private JdbcTemplate jdbcTemplate;
-
-
-
-
-
-
- public void setDataSource(DataSource ds) {
- this .jdbcTemplate = new JdbcTemplate(ds);
- }
-
- public void addPerson(PersonBean person) {
-
-
-
-
-
- jdbcTemplate.update("insert into person values(null,?)" , new Object[]{person.getName()}, new int []{Types.VARCHAR});
- }
-
- public void deletePerson( int id) {
- jdbcTemplate.update("delete from person where id = ?" , new Object[]{id}, new int []{Types.INTEGER});
- }
-
- @SuppressWarnings ( "unchecked" )
- public PersonBean queryPerson( int id) {
-
-
-
-
- List<PersonBean> pbs = (List<PersonBean>)jdbcTemplate.query("select id,name from person where id = ?" , new Object[]{id}, new PersonRowMapper());
- PersonBean pb = null ;
- if (pbs.size()> 0 ) {
- pb = pbs.get(0 );
- }
- return pb;
- }
-
- @SuppressWarnings ( "unchecked" )
- public List<PersonBean> queryPersons() {
- List<PersonBean> pbs = (List<PersonBean>) jdbcTemplate.query("select id,name from person" , new PersonRowMapper());
- return pbs;
- }
-
- public void updatePerson(PersonBean person) {
- jdbcTemplate.update("update person set name = ? where id = ?" , new Object[]{person.getName(), person.getId()}, new int []{Types.VARCHAR, Types.INTEGER});
- }
- }
package com.royzhou.jdbc;import java.util.List;import javax.sql.DataSource;import java.sql.Types;import org.springframework.jdbc.core.JdbcTemplate;public class PersonServiceImpl implements PersonService { private JdbcTemplate jdbcTemplate; /** * 通过Spring容器注入datasource * 实例化JdbcTemplate,该类为主要操作数据库的类 * @param ds */ public void setDataSource(DataSource ds) { this.jdbcTemplate = new JdbcTemplate(ds); } public void addPerson(PersonBean person) { /** * 第一个参数为执行sql * 第二个参数为参数数据 * 第三个参数为参数类型 */ jdbcTemplate.update("insert into person values(null,?)", new Object[]{person.getName()}, new int[]{Types.VARCHAR}); } public void deletePerson(int id) { jdbcTemplate.update("delete from person where id = ?", new Object[]{id}, new int[]{Types.INTEGER}); } @SuppressWarnings("unchecked") public PersonBean queryPerson(int id) { /** * new PersonRowMapper()是一个实现RowMapper接口的类, * 执行回调,实现mapRow()方法将rs对象转换成PersonBean对象返回 */ List<PersonBean> pbs = (List<PersonBean>)jdbcTemplate.query("select id,name from person where id = ?", new Object[]{id}, new PersonRowMapper()); PersonBean pb = null; if(pbs.size()>0) { pb = pbs.get(0); } return pb; } @SuppressWarnings("unchecked") public List<PersonBean> queryPersons() { List<PersonBean> pbs = (List<PersonBean>) jdbcTemplate.query("select id,name from person", new PersonRowMapper()); return pbs; } public void updatePerson(PersonBean person) { jdbcTemplate.update("update person set name = ? where id = ?", new Object[]{person.getName(), person.getId()}, new int[]{Types.VARCHAR, Types.INTEGER}); }}
再次运行测试类,输出:
1:royzhou
1:haha
null
得到预期的结果.
从上面代码可以看出,使用Spring提供的JDBCTemplate类很大程度减少了我们的代码量,
比起以前我们写JDBC操作, 需要先获取Connection,然后是PreparedStatement,再到Result,
使用Spring JDBCTemplate写出来的代码看起来更加简洁,开发效率也比较快.
在数据库的操作中,事务是一个重要的概念,举个例子:
大概每个人都有转账的经历。当我们从A帐户向B帐户转100元后,银行的系统会从A帐户上扣除100而在B帐户上加100,这是一般的正常现 象。
但是一旦系统出错了怎么办呢,这里我们假设可能会发生两种情况:
(1)A帐户上少了100元,但是B帐户却没有多100元。
(2)B 帐户多了100元钱,但是A帐户上却没有被扣钱。
这种错误一旦发生就等于出了大事,那么再假如一下,你要转账的是1亿呢?
所以上面的 两种情况分别是你和银行不愿意看到的,因为谁都不希望出错。那么有没有什么方法保证一旦A帐户上没有被扣钱而B帐户上也没有被加钱;
或者A帐户 扣了100元而B帐户准确无误的加上100元呢。也就是说要么转账顺利的成功进行,要么不转账呢?可以,这就是数据库事务机制所要起到 的作用和做的事情。
Spring对事务的管理有丰富的支持,Spring提供了编程式配置事务和声明式配置事务:
声 明式事务有以下两种方式
一种是使用Annotation注解的方式(官方推荐)
一种是基于Xml的方式
采用任何 一种方式我们都需要在我们的bean.xml中添加事务支持:
Xml代 码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://www.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%0A%3Cbeans%20xmlns%3D%22http%3A%2F%2Fwww.springframework.org%2Fschema%2Fbeans%22%0A%09xmlns%3Axsi%3D%22http%3A%2F%2Fwww.w3.org%2F2001%2FXMLSchema-instance%22%0A%09xmlns%3Acontext%3D%22http%3A%2F%2Fwww.springframework.org%2Fschema%2Fcontext%22%0A%09xmlns%3Aaop%3D%22http%3A%2F%2Fwww.springframework.org%2Fschema%2Faop%22%0A%09xmlns%3Atx%3D%22http%3A%2F%2Fwww.springframework.org%2Fschema%2Ftx%22%0A%09xsi%3AschemaLocation%3D%22http%3A%2F%2Fwww.springframework.org%2Fschema%2Fbeans%0A%20%20%20%20%20%20%20%20%20%20%20http%3A%2F%2Fwww.springframework.org%2Fschema%2Fbeans%2Fspring-beans-2.5.xsd%0A%20%20%20%20%20%20%20%20%20%20%20http%3A%2F%2Fwww.springframework.org%2Fschema%2Fcontext%20http%3A%2F%2Fwww.springframework.org%2Fschema%2Fcontext%2Fspring-context-2.5.xsd%0A%20%20%20%20%20%20%20%20%20%20%20http%3A%2F%2Fwww.springframework.org%2Fschema%2Faop%20http%3A%2F%2Fwww.springframework.org%2Fschema%2Faop%2Fspring-aop-2.5.xsd%0A%20%20%20%20%20%20%20%20%20%20%20http%3A%2F%2Fwww.springframework.org%2Fschema%2Ftx%20http%3A%2F%2Fwww.springframework.org%2Fschema%2Ftx%2Fspring-tx-2.5.xsd%22%3E%0A%0A%09%3Ccontext%3Aproperty-placeholder%20location%3D%22classpath%3Ajdbc.properties%22%20%2F%3E%0A%09%3Cbean%20id%3D%22dataSource%22%0A%09%09class%3D%22org.apache.commons.dbcp.BasicDataSource%22%0A%09%09destroy-method%3D%22close%22%3E%0A%09%09%3Cproperty%20name%3D%22driverClassName%22%20value%3D%22%24%7BdriverClassName%7D%22%20%2F%3E%0A%09%09%3Cproperty%20name%3D%22url%22%20value%3D%22%24%7Burl%7D%22%20%2F%3E%0A%09%09%3Cproperty%20name%3D%22username%22%20value%3D%22%24%7Bu
分享到:
- 浏览: 951 次
- 性别:
- 来自: 山东
评论