Spring Boot JDBC 参数别名 SQL(NamedParameterJdbcTemplate)

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6


在 SpringBoot 中基本的 jdbc 连接操作数据库,可以详见​​《Spring Boot JDBC 连接数据库》​​ ,本文简述在 SQL 中使用别名参数。

上文我们使用 JdbcTemplate 来操作数据库SQL,在 SQL 语句中传递参数使用 ​​?号​​占位代替,这样就要求我们参数集合和问号个数及顺序必须保持一致。

除此之外,Spring 还提供了另外一种可以为参数定义别名来为 SQL 提供参数的方式,就是使用 ​​NamedParameterJdbcTemplate​​ 类取代 JdbcTemplate 来操作 SQL,使用方法如下文所述。

使用

pom 依赖依旧是 ​​spring-boot-starter-jdbc​

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

Java 测试用例代码如下:

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.util.Assert;

import java.util.HashMap;
import java.util.Map;

@SpringBootTest
class Demo1SpringJdbcApplicationTests {

@Autowired
private JdbcTemplate jdbcTemplate;

@Autowired
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;

@Test
void contextLoads() {
Map<String, Object> resMap1 = jdbcTemplate.queryForMap("select * from config_info where id = ?",
new Object[]{"1"});

Map<String, Object> paramMap = new HashMap<>();
paramMap.put("id", "1");
Map<String, Object> resMap2 = namedParameterJdbcTemplate.queryForMap(
"select * from config_info where id = :id", paramMap);

Assert.isTrue(resMap1.get("id").equals(resMap2.get("id")), "Fail");
}

}
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=test123

总结就是添加相关依赖,然后配置 properties 文件的数据源,最后直接注入 ​​NamedParameterJdbcTemplate​​ 就可以使用了。


如果是某项目使用的原生 Spring 框架,没有使用 springboot 自动配置,在尝试直接注入 ​​NamedParameterJdbcTemplate​​​ 时发现 spring 容器中没有该类对象时。则可以通过自行构造对象的方法来实例化对象,可以使用 ​​dataSource​​​ 参数和 ​​jdbcTemplate​​​ 参数构造 ​​NamedParameterJdbcTemplate​​ 对象。

代码如下示例:

@Bean
@ConditionalOnMissingBean
public NamedParameterJdbcTemplate crateNamedParameterJdbcTemplate(DataSource dataSource){
return new NamedParameterJdbcTemplate(dataSource);
}

或者

@Bean
@ConditionalOnMissingBean
public NamedParameterJdbcTemplate crateNamedParameterJdbcTemplate(JdbcTemplate jdbcTemplate){
return new NamedParameterJdbcTemplate(jdbcTemplate);
}

然后就可以注入 ​​NamedParameterJdbcTemplate​​ 使用了。

这种在SQL中使用别名的方式,对参数的顺序和个数就没有这么严格的要求了,你只需要保证你SQL中使用的所有别名在参数Map中一定存在即可,参数Map中的内容可以多于SQL中变量的实际需求。

关于SQL IN 条件

对于 SQL 条件有 IN 的语句,NamedParameterJdbcTemplate 的支持要比问号方式友好的多,问号参数方式在遇到 in 条件时,需要 append 很多问号,然后参数也要对应上,in 的个数越多看起来越崩溃。

NamedParameterJdbcTemplate 把条件中的 IN 看做是一个完整的变量,直接又通透,如下代码示例:

@Autowired
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;

@Override
public List<ConfigInfo> selectItemByIds(String itemIds) {
Map<String,Object> paramMap = new HashMap<String, Object>();
try {
String sql = "SELECT * FROM config_info WHERE id IN(:itemIds)";
paramMap.put("itemIds", Arrays.asList(itemIds.split(",")));
return namedParameterJdbcTemplate.query(sql,paramMap, new BeanPropertyRowMapper<ConfigInfo>(ConfigInfo.class));
} catch (DataAccessException e) {
return null;
}
}

(ENG)


阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Spring