原文地址http://www.voidcn.com/article/p-cwqegtpg-hx.html

在使用JdbcTemplate时,一般传参都是用的?来绑定参数,但是对于某种情况就不适用了,例如Sql中如果存在IN,那么写SQL的时候就会比较麻烦,例如,咱们要查ID在某个范围内的数据,一般情况下咱们这么写:

List<String> ids = new ArrayList<String>();
ids.add("id1");
ids.add("id2");
ids.add("id3");
String sql = "SELECT * FROM TEST WHERE ID IN(";
for(int i = 0; i<ids.size();i++){
sql+="?";
if(i!=ids.size()){
sql+=",";
}
}
sql+=")";
List result = getJdbcTemplate.queryForList(sql, ids.toArray());

这里需要提到的类就是NamedParameterJdbcTemplate,他是Spring给开发者提供的一个基于JdbcTemplate的类,他支持命名参数特性。包含了JdbcTemplate中的大部分方法,主要有三类:execute方法、query及queryForXXX方法、update及batchUpdate方法。

咱们可以看一个由NamedParameterJdbcTemplate完成的上述例子:

List<String> ids = new ArrayList<String>();
ids.add("id1");
ids.add("id2");
ids.add("id3");
String sql = "SELECT * FROM TEST WHERE ID IN(:ids)";
Map params = new HashMap();
params.addValue("ids", ids);
NamedParameterJdbcTemplate jdbcTemplate = null;
jdbcTemplate = new NamedParameterJdbcTemplate(getJdbcTemplate());
List reslut = jdbcTemplate.query(sql, params);

可以看到Sql中的参数可以用 :[name] 的方式书写,在执行之前,所有的参数可以放在一个Map中,key为Sql中的参数名,这样的话,就简化了咱们自己拼写Sql的工作量。
其实,这只是NamedParameterJdbcTemplate的好处之一,另一个好处就是,对于同一个参数,多次出现在一条sql中时,也很好处理。
例如咱们要查一个数据,传入的时间参数要在字段F1和字段F2之间。那么可以这么写:

String sql = "SELECT * FROM TEST WHERE F1>:time and F2<:time";
Map params = new HashMap();
params.addValue("time", new Date());
NamedParameterJdbcTemplate jdbcTemplate = null;
jdbcTemplate = new NamedParameterJdbcTemplate(getJdbcTemplate());
List reslut = jdbcTemplate.query(sql, params);

上面咱们利用NamedParameterJdbcTemplate查询时,是将所有参数放入到了一个Map中,其实NamedParameterJdbcTemplate为咱们提供的参数模型不止Map。还有SqlParameterSource和BeanPropertySqlParameterSource。
其中SqlParameterSource和咱们用Map一样,他只是对Map进行了封装。
而BeanPropertySqlParameterSource封装了一个JavaBean对象,通过JavaBean对象属性来决定命名参数的值。
例如咱们创建了一个Bean。

public class User {
private int id;
private String userName;
private String password;
//省略getter和setter
}

现在验证一个登录信息是否正确:

public boolean login(String userName,String password){
NamedParameterJdbcTemplate namedParameterJdbcTemplate = null;
namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(getJdbcTemplate());
User user = new User();
model.setUserName("jialeens");
model.setPassword("hehe");
String sql = "SELECT COUNT(1) FROM USER WHERE USERNAME=:userName AND PASSWORD=:password";
SqlParameterSource paramSource = new BeanPropertySqlParameterSource(user);
int size = namedParameterJdbcTemplate.queryForInt(sql, paramSource);
return size==1;
}

可以看到,传入的参数是一个对象Bean,Sql在执行时,会根据Sql中的参数名去获取对应Bean中的属性。

NamedParameterJdbcTemplate内部包含了一个JdbcTemplate,所以JdbcTemplate能做的事情NamedParameterJdbcTemplate都能干; NamedParameterJdbcTemplate相对于JdbcTemplate主要增加了参数可以命名的功能。
public Object queryForObject(String sql, Map paramMap, RowMapper rowMapper)
public Object queryForObject(String sql, SqlParameterSource paramSource, RowMapper rowMapper)
SqlParameterSource的两个主要实现MapSqlParameterSource
和BeanPropertySqlParameterSource
public int update(String sql, SqlParameterSource paramSource, KeyHolder generatedKeyHolder)保存数据获得主键。

public class NamedJdbcTemplate {
// JdbcTemplate是线程安全的
static JdbcTemplate jdbc = new JdbcTemplate(JdbcUtils.getDataSource());
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(findUser(user));
System.out.println(findUser1(user));
}
static void addUser(User user){
String sql = "insert into user(name,birthday, money) values (:name,:birthday,:money) ";//:后的命名要与列名一致
SqlParameterSource ps=new BeanPropertySqlParameterSource(user);//从user中取出数据,与sql语句中一一对应将数据换进去
KeyHolder keyHolder=new GeneratedKeyHolder();
named.update(sql, ps, keyHolder);
int id=keyHolder.getKey().intValue();//获得主键
user.setId(id);
//Map map=keyholder.getKeys();//这样可以得到联合主键的值
//keyholder.getKeyList();//这样可以得到一些主主键值,若一次添加好几条记录
}
static User findUser1(User user) {
String sql = "select id, name, money, birthday from user where money>:money and id<:id";
SqlParameterSource ps=new BeanPropertySqlParameterSource(user);
Object u=named.queryForObject(sql, ps, new BeanPropertyRowMapper(User.class));
return (User) u;
}
static User findUser(User user) {
String sql = "select id, name, money, birthday from user where money>:m and id<:id";
Object[] args = new Object[] {user.getName(),user.getMoney(),user.getId() };
Map params=new HashMap();
params.put("m", user.getMoney());
params.put("id", user.getId());
Object u=named.queryForObject(sql, params, new BeanPropertyRowMapper(User.class));
return (User) u;
}

Spring JdbcTemplate使用别名传参(NamedParameterJdbcTemplate)的更多相关文章

  1. axios&spring前后端分离传参规范总结

    前后端分离开发的场景下,开发人员的工作内容更加专注与专业,但是也产生了一些额外的沟通成本.比如:本文中为大家说明的前后端参数传递与接受方法.本文主要是面对前端使用axios,后端使用Spring进行参 ...

  2. spring mvc 重定向加传参

    常用: ModelAndViewi: return new ModelAndView("redirect:/toList");  或者 ii:return "redire ...

  3. JdbcTemplate in()传参

    1. 实体类 import java.util.List; public class Param { private List<String> names; private List< ...

  4. MyBatis 强大之处 多环境 多数据源 ResultMap 的设计思想是 缓存算法 跨数据库 spring boot rest api mybaits limit 传参

    总结: 1.mybaits配置工2方面: i行为配置,如数据源的实现是否利用池pool的概念(POOLED – This implementation of DataSource pools JDBC ...

  5. jdbcTemplate传参使用Map或List

    List传参方式 举个例子 sql = "select * from table where id=? and param=?": sql中的参数要用?形式,然后使用list.ad ...

  6. VueJs(11)---vue-router(命名路由,命名视图,重定向别名,路由组件传参)

    vue-router 上篇文章讲了第一篇vue-router相关文章,文章地址:VueJs(10)---vue-router(进阶1) 一.命名路由 有时候,通过一个名称来标识一个路由显得更方便一些, ...

  7. spring mvc controller间跳转 重定向 传参(转)

    spring mvc controller间跳转 重定向 传参 url:http://zghbwjl.blog.163.com/blog/static/12033667220137795252845/ ...

  8. Spring cloud Feign不支持对象传参解决办法[完美解决]

    spring cloud 使用 Feign 进行服务调用时,不支持对象参数. 通常解决方法是,要么把对象每一个参数平行展开,并使用 @RequestParam 标识出每一个参数,要么用 @Reques ...

  9. Spring JdbcTemplate 和 NamedParameterJdbcTemplate 使用

    1.简单介绍 DAO层 的一般使用常见的是MyBatis 和 Hibernate,但是Hibernate是重量级的,而且学习成本较高,Mybatis 需要编写大量配置文件及接口文件,对于简单的项目应用 ...

随机推荐

  1. 基于.NET平台常用的框架整理 转自 http://www.cnblogs.com/zhuyongblogs/p/5353751.html

    常用的一些开源组件整理: 导出Excel报表的插件:NOPI.dll(基于微软OpenXml实现)开源的作业调度和自动任务框架:Quartz.NET用于大数据搜索引擎的全文检索框架:Lucene.ne ...

  2. Console程序下监控EFCore生成的SQL语句!

    最近这两天在使用控制台程序学习EFCore,突然想看看生成的SQL语句,所以在网上找到一位大神的分享的方法! 准备工作: 1). MySqlEFCore NuGet:   Pomelo.EntityF ...

  3. Linux下Mysql5.7忘记密码

    一.问题 linux下的mysql5.7忘记密码 二.解决 第一步:打开mysql5.7的配置文件my.cnf,并在里面增加一行:skip-grant-tables   保存并退出(:wq) [roo ...

  4. RESTful规范总结

    思维导图xmind文件:https://files-cdn.cnblogs.com/files/benjieming/RESTful%E8%A7%84%E8%8C%83.zip

  5. 立即执行函数(function(){})()与闭包

    立即执行函数 匿名(function(){})() 当一个匿名函数被括起来,然后再在后面加一个括号,这个匿名函数就能立即运行起来. $(function(){}) $(function(){});是$ ...

  6. SpringApplication到底run了什么(上)

    在上篇文章:SpringBoot源码解析:创建SpringApplication对象实例中,我们详细描述了SpringApplication对象实例的创建过程,本篇文章继续看run方法的执行逻辑吧 p ...

  7. 【开发工具】- Xshell过期了怎么办?

    点击下边链接下载免费版 http://www.netsarang.com/download/free_license.html

  8. android studio学习----构建(gradle )依赖时使用动态依赖的问题

    今天在看Dan Lew大神的博客发现最新的文章就是 “Don't use dynamic versions for your dependencies” Everyone, please, to st ...

  9. 第二篇Scrum冲刺博客

    第二篇Scrum冲刺博客 一.站立式会议 提供当天站立式会议照片一张 二.每个人的工作 成员 已完成工作 明天计划完成的工作 遇到的困难 林剑峰 初步学习小程序的编写.博客园的撰写 初步完成用户界面 ...

  10. Hashtable,HashMap和ConcurrentHashMap的原理及区别

    一.原理 Hashtable 底层数组+链表实现,无论key还是value都不能为null,线程安全,实现线程安全的方式是在修改数据时锁住整个HashTable,效率低,ConcurrentHashM ...