传智播客李勇Jdbc视频笔记(43-48)

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));
		}
	}

你可能感兴趣的:(DAO,sql,jdbc)