43、使用JdbcTemplate工具类简化对象查询
(1)new RowMapper就是实现一个行映射器,就是对ResultSet的处理,那么内部是一个借口我们在传递参数的时候,可以用
匿名类的方式实现,因为sql是我们自己写的,所以ResultSet如何映射有你自己处理
static JdbcTemplate jdbc = new JdbcTemplate(JdbcUtils.getDataSource());
static User findUser1(String name) {
String sql = "select id, name, money, birthday from user where name=?";
Object[] args = new Object[] { name };
Object user = jdbc.queryForObject(sql, args, new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum) 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;
}
});
return (User) user;
}
(2)new BeanPropertyRowMapper在创建这个对象的时候需要传递一个.class文件,JdbcTemplete会通过反射技术
把ResultSet中的值取出来封装成一个对象返回回去。
static User findUser(String name) {
String sql = "select id, name, money, birthday from user where name=?";
Object[] args = new Object[] { name };
Object user = jdbc.queryForObject(sql, args, new BeanPropertyRowMapper(
User.class));
return (User) user;
}
44、JdbcTemplate类中的其他各个查询方法
在这一小节中展示了JdbcTemplete中提供的各种方法,下面列举了几个都是前面我们自己写jdbc程序的时候能实现的
只不过jdbcTemplete更进一步的做了更好的封装:
//得到Map类型的结果
static Map getData(int id) {
String sql = "select id as userId, name, money, birthday from user where id="
+ id;
return jdbc.queryForMap(sql);
}
//得到Object类型的结果
static String getUserName(int id) {
String sql = "select name from user where id=" + id;
Object name = jdbc.queryForObject(sql, String.class);
return (String) name;
}
//得到int类型的结果
static int getUserCount() {
String sql = "select count(*) from user";
return jdbc.queryForInt(sql);
}
45、使用JdbcTemplate完成数据库修改和其他功能
介绍在JdbcTemplete中update许多方法的使用,其实和其他的都是一样的,就是传递参数、sql语句之类的,在前面的示例中
我们做过一个例子就是在保存一个对象之后呢,得到这个对象保存后在数据库的key值,那么在JdbcTemplete中也为我们提供
了相应的方法可以实现这一需求:
static int addUser(final User user) {
//调用execute方法,传递参数的时候也是使用一个匿名类然后要实现一个doInConnection的方法,在这个方法中
//他会把Connection对象创建好了之后交给你来处理,所以这也就很灵活。
jdbc.execute(new ConnectionCallback() {
public Object doInConnection(Connection con) throws SQLException,
DataAccessException {
String sql = "insert into user(name,birthday, money) values (?,?,?) ";
PreparedStatement ps = con.prepareStatement(sql,
Statement.RETURN_GENERATED_KEYS);
ps.setString(1, user.getName());
ps.setDate(2, new java.sql.Date(user.getBirthday().getTime()));
ps.setFloat(3, user.getMoney());
ps.executeUpdate();
ResultSet rs = ps.getGeneratedKeys();
if (rs.next())
user.setId(rs.getInt(1));
return null;
}
});
return 0;
}
46、使用支持命名参数的JdbcTemplate
这个支持命名参数的Jdbctemplete其实就是在JdbcTemplete的基础上对参数又进行了一系列的包装,让我们在对
sql语句中的参数进行传值的时候更加的方便和好用:
public class NamedJdbcTemplate {
//new一个支持命名参数的JdbcTemplete对象
static NamedParameterJdbcTemplate named = new NamedParameterJdbcTemplate(
JdbcUtils.getDataSource());
public static void main(String[] args) {
User user = new User();
user.setMoney(10);
user.setId(2);
System.out.println(findUser1(user));
}
static void addUser(User user) {
//构建sql语句,把需要传递的参数用名称的方法表示出来 需要注意的是 :如果用这种方式添加一个对象
//你的values()括号中的代表参数的值必须与User类中的属性是一致的才可以
String sql = "insert into user(name,birthday, money) values (:name,:birthday,:money) ";
//直接把方法参数传递过来的User对象给他,他会通过反射的方式找到sql语句中需要设置值的属性
//然后给他赋值,这就是为什么要求命名参数要与Javabean中的属性名称一致
SqlParameterSource ps = new BeanPropertySqlParameterSource(user);
//new keyHodler对象,他可以把添加这条记录后在数据库生成的id返回回来
KeyHolder keyHolder = new GeneratedKeyHolder();
//调用NamedParameterJdbcTemplate 的update方法
named.update(sql, ps, keyHolder);
//如果主键是int型 则返回一个int值
int id = keyHolder.getKey().intValue();
user.setId(id);
//如果主键是String或者是联合主键我们可以让它返回一个Map对象,然后遍历得到相应的数据
Map map = keyHolder.getKeys();
}
//这个方法演示的是把sql语句中需要传递的参数按照名称放到Map中调用方法的时候,直接把Map对象传递进去就可以给sql
//赋值了,这和针对"?"赋值来说不容易出错因为如果采用?作为占位符然后赋值 顺序必须要正确否则就会出错。
static User findUser(User user) {
String sql = "select id, name, money, birthday from user "
+ "where money > :m and id < :id";
Map params = new HashMap();
// params.put("n", user.getName());
params.put("m", user.getMoney());
params.put("id", user.getId());
Object u = named.queryForObject(sql, params, new BeanPropertyRowMapper(
User.class));
return (User) u;
}
//这个方法与findUser方法中所使用的方式基本是一样的
static User findUser1(User user) {
//构建sql语句,用相应的名称作为占位符:注意与Javabean中属性名称一样
String sql = "select id, name, money, birthday from user "
+ "where money > :money and id < :id";
//直接把User对象传递给他,他会自动找到sql中需要赋值的参数并且赋值
SqlParameterSource ps = new BeanPropertySqlParameterSource(user);
//调用方法执行sql new BeanPropertyRowMapper我们把相应的.class文件传递进去,他会把sql语句执行的
//结果封装成相应的对象
Object u = named.queryForObject(sql, ps, new BeanPropertyRowMapper(
User.class));
return (User) u;
}
}
47、使用SimpleJdbcTemplate和泛型技术简化代码
如果说NamedParameterJdbcTemplate是对Jdbctemplete的一层封装,那么SimpleJdbcTemplate是对NamedParameterJdbcTemplate的
有一层的封装,在这里类必须在jdk1.5以上才可以使用,因为他用到了可变参数泛型的相关知识。
public class SimpleJdbcTemplateTest {
//new 一个 SimpleJdbcTemplate 的对象
static SimpleJdbcTemplate simple = new SimpleJdbcTemplate(JdbcUtils
.getDataSource());
//可以把需要转换成的类型作为参数传递进去(泛型)
//static <T>T find(String name, Class<T> clazz);
static User find(String name) {
//构建sql语句
String sql = "select id, name, money, birthday from user where name=? and money > ?";
//调用queryForObject()方法,第一个参数传递sql ,第二个参数和我们上面的用法一样,就是将执行的结果封装
//成为一个相应类型的对象 那么第三个参数就是传递sql语句中需要传递的参数。在这个方法中他是一个可变参数
//Object... args
User user = simple.queryForObject(sql,
ParameterizedBeanPropertyRowMapper.newInstance(User.class),
name, 100f);
return user;
}
}
现在我们有一个SimpleJdbcTemplate对象,但是如果我想用NamedParameterJdbcTemplate中的相应的方法怎么办呢?虽然SimpleJdbcTemplate
是对NamedParameterJdbcTemplate的封装,但是有些方法并没有:
(1)在SimpleJdbcTemplate对象中使用NamedParameterJdbcTemplate对象:simple.getNamedParameterJdbcOprations().相应的方法
(2)在SimpleJdbcTemplate对象中使用Jdbctemplete对象:simple.getJdbcOprations().相应的方法
48、使用JdbcTemplate实现DAO和用工厂灵活切换实现
用我们前面学习过的Jdbctemplete来从新实现前面例子中写的Userdao这个接口,代码会简洁很多。
public class UserDaoSpringImpl implements UserDao {
private SimpleJdbcTemplate simpleJdbcTemplate = new SimpleJdbcTemplate(
JdbcUtils.getDataSource());
public void addUser(User user) {
String sql = "insert into user (name, money, birthday) values (:name, :money, :birthday)";
SqlParameterSource param = new BeanPropertySqlParameterSource(user);
KeyHolder keyHolder = new GeneratedKeyHolder();
this.simpleJdbcTemplate.getNamedParameterJdbcOperations().update(sql,
param, keyHolder);
user.setId(keyHolder.getKey().intValue());
}
public void delete(User user) {
String sql = "delete from user where id=?";
this.simpleJdbcTemplate.update(sql, user.getId());
}
public User findUser(String loginName, String password) {
String sql = "select id, name, money, birthday from user where name=?";
return this.simpleJdbcTemplate.queryForObject(sql,
ParameterizedBeanPropertyRowMapper.newInstance(User.class),
loginName);
}
public User getUser(int userId) {
String sql = "select id, name, money, birthday from user where id=?";
return this.simpleJdbcTemplate.queryForObject(sql,
ParameterizedBeanPropertyRowMapper.newInstance(User.class),
userId);
}
public void update(User user) {
String sql = "update user set name=?, birthday=?, money=? where id=? ";
this.simpleJdbcTemplate.update(sql, user.getName(), user.getBirthday(),
user.getMoney(), user.getId());
sql = "update user set name=:name, birthday=:birthday, money=:money where id=:id ";
this.simpleJdbcTemplate.update(sql, new BeanPropertySqlParameterSource(
user));
}
}