如果我们不使用spring或使用spring但不使用spring的jdbcTemplate模板的时候我们要取得一个数据库的连接以及关闭要经过如下几步:
1、使用Java反射加载驱动
2、通过DriverManager 的getConnection() 方法获取Connection对象
3、获取Statement 或PrepareStatement
4、 调用Statement 或PrepareStatement的方法进行数据ddl dcl dml 操作
5、获取结果
6、释放资源
7、如果有异常,处理异常 (异常在哪里都有可能出现)
我们发现我们想要的或者说和业务相关的只有4、5这两个,其他的和业务无关,但是这些必须要有,而且有个特点不管是怎样这些都是固定不变的,也就和一个流程中的某些固定事务相似,所以spring使用模板方法模式对其进行了封装,具体的如下:
我们知道Spring 没有提供orm框架但是spring对jdbc使用模板方法模式进行了封装,在使用的过程我们不用处理数据库的连接,资源的释放以及异常处理,这些固定的操作spring的jdbcTemplate已经帮我们处理了!
下面看看,spring 的jdbcTemplate 模板的结构:
jdbcTemplate是线程安全的,在应用中使用一个jdbcTemplate,所以我们在xml配置文件中进行配置。
使用Spring的jdbcTemplate模板进行数据库操作实例:
1、javaBean:
package com.inspur.data;
/**
*@author WHD
*2015-2-4
*/
public class User {
private int age;
private String name;
public User(){}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2、接口: UserDao
package com.inspur.data;
import java.util.List;
/**
*@author WHD
*2015-2-4
*/
public interface UserDao {
public void SaveUser(User user);
}
3、接口实现类
StudentDaoImp
package com.inspur.data;
import org.springframework.jdbc.core.JdbcTemplate;
/** *@author WHD *2015-2-5 */
public class StudentDaoImp implements UserDao {
private JdbcTemplate jdbcTemplate;
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public void SaveUser(User user) {
String sql = "delete from springjdbctest where age=3 ";
int res = jdbcTemplate.update(sql);
System.out.println("del 执行结果" + res);
}
public void test() {
System.out.println("test");
}
}
4、接口实现类
package com.test.comp;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import com.test.model.User;
/**
* @author WHD data 2016年5月29日
*/
public class UserDaoImp implements UserDao {
// jdbcTemplate对象 提供了操作数据库的方法
private JdbcTemplate jdbcTemplate;
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public void SaveUser(User user) {
// TODO Auto-generated method stub
String sql = "insert into springjdbctest values(?,?)";
int result=jdbcTemplate.update(sql,
new Object[] { user.getAge(), user.getName() }, new int[] {
java.sql.Types.INTEGER, java.sql.Types.VARCHAR });
System.out.println(result);
}
public void tell() {
System.out.println("daoimp");
}
public List findUser() {
String sql = "select age,name from springjdbctest";
final List list = new ArrayList();
jdbcTemplate.query(sql, new RowCallbackHandler() {
// 这里封装的还是挺方便的,你不用自己对ResultSet 进行遍历取值,可以按照下面的方式直接循环取值
@Override
public void processRow(java.sql.ResultSet res) throws SQLException {
User user = new User();
user.setAge(Integer.parseInt(res.getString("age")));
user.setName(res.getString("name"));
list.add(user);
user = null;
}
});
return list;
}
// 获取总数
public int count() {
int count = jdbcTemplate
.queryForInt("select count(*) from springjdbctest");
return count;
}
}
5、配置文件
com.mysql.jdbc.Driver
jdbc:mysql://localhost:3306/myspringjdbcdb
root
admin
6、测试类
package com.test;
import java.util.List;
import java.util.Map;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.inspur.data.StudentDaoImp;
import com.inspur.data.User;
import com.inspur.data.UserDaoImp;
import junit.framework.TestCase;
/** *@author WHD *2014-10-4 */
public class TestDisk extends TestCase{
public void test(){
// spring ApplicationContext 容器
ApplicationContext act = new ClassPathXmlApplicationContext("ApplicationContext.xml");
//从容器中获取bean
UserDaoImp userdaoimp=(UserDaoImp)act.getBean("userDaoImp");
StudentDaoImp studentdaoimp=(StudentDaoImp)act.getBean("studentDaoImp");
User user= new User();
user.setAge(3);
user.setName("name3");
userdaoimp.tell();
userdaoimp.SaveUser(user);
List list=userdaoimp.findUser();
for(User data:list){
System.out.println("查询结果:"+data.getAge()+" "+data.getName());
}
// 查询结果:
int count=userdaoimp.count();
System.out.println(count);
}
}
小结: 从上面的代码我们看到相比直接使用jdbc 来获取数据库链接以及数据查询组装使用spring的jdbcTemplate 来实现就方便快捷了很多,比如我们只需要在配置文件中配置DataSource 数据源以及jdbcTemplate ,有了这两个我们就不用管那些Connection、preparedStatement、以及ResultSet 这些他已经帮我们完成了。这样只需要我们做的就是告诉jdbcTemplate 我们要什么要的数据即sql 以及参数。相比jdbc确实方便快捷了很多。而且jdbcTemplate是线程安全的我们就不用管了。
上面的是使用了spring的jdbcTemplate模板,下面使用mapper 也就是在sql和应用之间加一道墙隔开我们不和sql打交道
1、Javabean
package com.inspur.jdbcMapper;
/**
*@author WHD
*2015-2-5
*/
public class Person {
private int age;
private String name;
public Person(){}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2、继承SqlUpdate实现隔离
package com.inspur.jdbcMapper;
import java.sql.Types;
import javax.sql.DataSource;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.object.SqlUpdate;
/**
*@author WHD
*2015-2-5
*/
public class InsertPerson extends SqlUpdate{
public InsertPerson(DataSource datasource){
//注入数据源
setDataSource(datasource);
//设置sql语句
setSql("insert into springjdbctest values(?,?)");
//设置参数类型
declareParameter(new SqlParameter(Types.INTEGER));
declareParameter(new SqlParameter(Types.VARCHAR));
compile();
}
public int insert(Person person){
Object []params= new Object[]{person.getAge(),person.getName()
};
// 调用父类的update方法按照之前设置的sql以及参数进行操作
return update(params);
}
}
3、继承SqlUpdate实现隔离
package com.inspur.jdbcMapper;
import java.sql.Types;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.object.SqlUpdate;
/**
*@author WHD
*2015-2-9
*/
public class DeletePerson extends SqlUpdate{
public DeletePerson(javax.sql.DataSource dataSource){
//设置数据源
setDataSource(dataSource);
//设置sql语句
setSql("delete from springjdbctest where age=?");
//设置参数类型
declareParameter(new SqlParameter(Types.INTEGER));
}
public int delete(Person person){
Object []params= new Object[]{person.getAge()};
//调用父类的方法,执行sql 按照设置的参数条件进行操作!
return update(params);
}
}
4、业务中的方法调用2中方法进行insert,但这里也就是业务中我们不用谢sql语句
package com.inspur.jdbcMapper;
/**
*@author WHD
*2015-2-5
*/
public class MyInsert {
private InsertPerson insertPerson;
public InsertPerson getInsertPerson() {
return insertPerson;
}
//set 注入
public void setInsertPerson(InsertPerson insertPerson) {
this.insertPerson = insertPerson;
}
public int insert(Person person){
System.out.println("执行插入");
//调用InsertPerson的insert方法,其实是调用了SqlUpdate的update()方法进行了sql操作
return insertPerson.insert(person);
}
public void tell(){
System.out.println("执行插入");
}
}
5、业务中的方法调用3中方法进行delete,执行3中的方法但我们不用写sql语句
package com.inspur.jdbcMapper;
/**
*@author WHD
*2015-2-9
*/
public class MyDelete {
private DeletePerson deletePerson;
public DeletePerson getDeletePerson() { return deletePerson;}
//set注入
public void setDeletePerson(DeletePerson deletePerson) {
this.deletePerson = deletePerson;
}
public int delete (Person person){
System.out.println("执行persondelete");
return deletePerson.delete(person);
}
}
6、配置文件
com.mysql.jdbc.Driver
jdbc:mysql://localhost:3306/myspringjdbcdb
root
admin
7、测试类
package com.test;
import java.util.List;import java.util.Map;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.inspur.jdbcMapper.MyDelete;
import com.inspur.jdbcMapper.MyInsert;
import com.inspur.jdbcMapper.MySelect;
import com.inspur.jdbcMapper.Person;
import junit.framework.TestCase;
/**
*@author WHD
*2014-10-4
*/
public class TestDisk extends TestCase{
public void testSpring(){
// spring 容器加载配置文件中的bean
ApplicationContext act = new ClassPathXmlApplicationContext("appMapper.xml");
// 从容器中获取bean
MyInsert myinsert= (MyInsert)act.getBean("myInsert");
MyDelete myDelete=(MyDelete)act.getBean("myDelete");
Person p= new Person();
p.setAge(8);
p.setName("name8");
myinsert.tell();
myinsert.insert(p);
myDelete.delete(p);
System.out.println("结束");
}
}
小结:
从上面的代码我们看书,下面使用sqlupdate的update方法来操作的这种方式让我们从业务中吧sql语句分离出去了,不用在业务代码中编写sql 语句。
sqlupdate 这个类中要设置这些参数:1、dataSource 数据源的设置 2、sql 语句的设置 3、参数类型的设置 ok 有了数据源,有了sql语句有了条件参数那就是执行了,调用sqlupdate 这个类的update 方法来执行之前设置的sql。在具体的业务类中使用sprig的注入方式来注入实现了sqlupdate类的类,这样我们就可以在业务层只需要调用类的方法并传递参数就可以不用在写sql 以及数据的处理,这样就把数据库相关的所有操作分离出了业务层。
但是话又说回来,你发现没不管使用jdbcTemplate 还是SqlUpdate 页都是那些步骤,1、数据源的设置 2、sql语句以及查询条件 3、查询结果获取,相比之前的纯jdbc我们省去了链接数据库获取Connection 以及获取sql载体Statement、preparedStatement 以及结果集ResultSet ,我们省去的这些也就是spring 替我们做了的,其实你在学习其他orm 框架是你也会发下,他们也是一样的步骤,哪些固定的一样的事情框架都已替我们处理了,还有就是把sql从java代码或者说把sql从我们的业务代码中分离出去了。这样方便维护代码也比较干净。
我个人觉的这些也就是框架带来的好处!