相关文章推荐
叛逆的青蛙  ·  Java ...·  2 月前    · 
腼腆的拖把  ·  .net core RSA ...·  8 月前    · 
行走的烤土司  ·  IBM MQ ...·  1 年前    · 

在使用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;
                    在使用JdbcTemplate时,一般传参都是用的?来绑定参数,但是对于某种情况就不适用了,例如Sql中如果存在IN,那么写SQL的时候就会比较麻烦,例如,咱们要查ID在某个范围内的数据,一般情况下咱们这么写:List ids = new ArrayList();ids.add("id1");ids.add("id2");ids.add("id3");String sql = "SEL
				
jdbcTemplate 中查询出来的日期值为 :2021-08-26 00:00:00 jdbcTemplate.query(sql, (RowMapper<Persion>) (resultSet, index) -> { Persion p = new Persion(); p.setBirthday(resultSet.getDate("birthday")); System.out.println(p.getBirthday()); // 假设格式化之后
最近项目换用SpringMVC + Spring JdbcTemplate,没有用orm,发现执行的sql无法打印出来,查了下解决办法。 在log4j.properties增加如下配置: log4j.logger.org.springframework.jdbc.core.JdbcTemplate=debug 注意:这个日志级别只能配置为debug。一如ibatis中想打印sql时也
查看了JdbcTemplate的反编译源码,发现打印语句的地方,其日志级别为debug, 因此,添加log4j参数:log4j.logger.org.springframework.jdbc.core.JdbcTemplate=debug [code="java"]pu... JDBCTeamplate使用步骤: 1.引入相关的jar包 druid mysql-connector srping-jdbc sprint-tx spring-orm 2.创建数据库连接池properties文件 jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mybatis jdbc.user
spring使用jdbc处理mysql时,sql语句存在别名的情况下,获取结果总是缺少字段,代码如下所示: [code="java"] String sql = "select count(*) as num from yxtj_dqjl a"; System.out.println("result:"+jdbcTemplate.queryForList(sql)); [/co...
在项目工程中,我们一定会使用程序去连接数据库,Spring 中给我们提供了两个特别方便连接数据库的操作:JdbcTemplateNamedParameterJdbcTemplate,如果不用Spring 提供的 JdbcTemplate,必须创建大量的冗余代码(创建连接,关闭连接,处理异常)中的所有DAO数据库的操作方法 - 插入,更新和删除。下面就介绍如果使用。 工程项目结构 数......