您的位置:首页 > 编程语言

JDBC之使用策略模式和模板方法模式优化代码

2017-07-29 15:27 666 查看
在处理ResultSet时,不同的方法处理的方式是不一样的,但在继承的时候,rowMapper方法只能以一种方式实现,因此可以将对ResultSet处理的部分单独提取成一个抽象的部分,在不同的方法需要处理的时候,各自以自己的方式进行定义。

1、定义一个策略接口RowMapper

package cn.itcast.jdbc.dao.refactor;

import java.sql.ResultSet;
import java.sql.SQLException;

/**
* 策略接口
*/
public interface RowMapper {

/**
* 策略方法
* @param rs
* @return
* @throws SQLException
*/
public Object mapRow(ResultSet rs) throws SQLException;

}
2、定义Dao模板类
package cn.itcast.jdbc.dao.refactor;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import cn.itcast.jdbc.JdbcUtils;
import cn.itcast.jdbc.dao.DaoException;

/**
* 自定义Dao处理结果集的模板方法
*/
public class MyDaoTemplate {

/**
* 执行查询操作的模板方法
* @param sql
* @param args
* @param rowMapper
* @return
*/
public Object find(String sql, Object[] args, RowMapper rowMapper) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;

try {
conn = JdbcUtils.getConnection();
ps = conn.prepareStatement(sql);
for(int i = 0; i < args.length; i ++) {
ps.setObject(i + 1, args[i]);
}
rs = ps.executeQuery();
Object obj = null;
if(rs.next()) {
//这里的执行交给具体的执行方法去处理
obj = rowMapper.mapRow(rs);
}
return obj;
} catch (SQLException e) {
throw new DaoException(e.getMessage(), e);
} finally {
JdbcUtils.free(rs, ps, conn);
}

}
}
3、编写Dao的实现类
package cn.itcast.jdbc.dao.refactor;

import java.sql.ResultSet;
import java.sql.SQLException;

import cn.itcast.jdbc.domain.User;

/**
* 使用模板方法模式和策略模式进行优化代码
*/
public class UserDaoImpl2 {

private MyDaoTemplate template = new MyDaoTemplate();

/**
* 根据姓名查询用户
* @param loginName
* @return
*/
public User findUser(String loginName) {
String sql = "select id, name, money, birthday"
+ " from user where name = ?";
Object[] args = new Object[]{loginName};
//显式创建一个行映射器
RowMapper mapper = new UserRowMapper();
Object user =this.template.find(sql, args, mapper);
return (User) user;
}

/**
* 根据id查询用户姓名
* @param id
* @return
*/
public String findUserName(int id) {
String sql = "select name from user where id = ?";
Object[] args = new Object[]{id};
//通过匿名内部类的方式创建一个行映射器
Object name = this.template.find(sql, args, new RowMapper(){

public Object mapRow(ResultSet rs) throws SQLException {
return rs.getString("name");
}

});
return (String) name;
}

}

class UserRowMapper implements RowMapper {

/**
* 具体的方法
*/
public Object mapRow(ResultSet rs) throws SQLException {
User user = new User();
user.setId(rs.getInt("id"));
user.setName(rs.getString("name"));
user.setMoney(rs.getFloat("money"));
user.setBirthday(rs.getDate("birthday"));
return user;
}

}
4、编写测试类进行测试
package cn.itcast.jdbc.dao.refactor;

import org.junit.Test;

import cn.itcast.jdbc.domain.User;

public class TestUserDaoImpl2 {

private UserDaoImpl2 impl2 = new UserDaoImpl2();

/**
* 测试根据姓名查询用户
*/
@Test
public void testFindUser() {
User user = impl2.findUser("lisi");
System.out.println(user);
}

/**
* 测试根据id查询用户姓名
*/
@Test
public void testFindUserName() {
String username = impl2.findUserName(2);
System.out.println(username);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息