NamedParameterJdbcTemplate类拓展了JdbcTemplate类,对JdbcTemplate类进行了封装从而支持**具名参数特性**。
什么是具名参数?
SQL 按名称(以冒号开头)⽽不是按位置进⾏指定。
例如:
private final String QUERY_SQL = "INSERT INTO T_USER(username,password) VALUES(?,?)";
private final String QUERY_SQL = "INSERT INTO T_USER(username,password) VALUES(:username,:password)";
NamedParameterJdbcTemplate主要提供以下三类方法:execute方法、query及queryForXXX方法、update及batchUpdate方法。
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-jdbcartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<scope>runtimescope>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
另外:jdbc依赖也可以换成
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>5.0.9.RELEASEversion>
dependency>
#MySql8.0
spring:
datasource:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/数据库名?useSSL=false&characterEncoding=utf-8&useUnicode=true&serverTimezone=Asia/Shanghai
username: 数据库用户名
password: 数据库密码
注意:数据库的id主键设置成自动递增
,所以添加的时候不用考虑id
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TUser implements Serializable {
private Integer id;
private String username;
private String password;
}
可以使用SqlParameterSource实现具名参数,默认实现有 :
这个接口为了实现sql查询结果和对象间的转换
,可以自己实现,也可以使用系统实现,主要实现类有:
API: int update(String sql, Map
@Autowired
private NamedParameterJdbcTemplate template;
//添加数据
Map<String,Object> map = new HashMap<>();
map.put("username","刘亦菲");
map.put("password","4983ghh");
template.update("INSERT INTO T_USER(username,password) VALUES(:username,:password)",map);
//修改数据
Map<String,Object> map = new HashMap<>();
map.put("username","刘诗诗");
map.put("password","ewgg");
map.put("id",4);
template.update("UPDATE T_USER SET USERNAME = :username,PASSWORD = :password WHERE ID = :id",map);
// 删除数据
Map<String,Object> map = new HashMap<>();
map.put("id",4);
template.update("DELETE FROM T_USER WHERE ID = :id",map);
API: int update(String sql, SqlParameterSource paramSource)
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ConditionDTO {
private String password;
private String username;
}
ConditionDTO conditionDTO = new ConditionDTO();
conditionDTO.setUsername("成龙");
conditionDTO.setPassword("2432tgh");
BeanPropertySqlParameterSource beanParam = new BeanPropertySqlParameterSource(conditionDTO);
template.update("INSERT INTO T_USER(username,password) VALUES(:username,:password)",beanParam);
注意:用BeanPropertySqlParameterSource作为参数的时候,可以将参数DTO属性存值单独出来一个方法,这样可以解耦,代码维护相对轻松。如下:
private ConditionDTO getConditionDTO() {
ConditionDTO conditionDTO = new ConditionDTO();
conditionDTO.setUsername("成龙");
conditionDTO.setPassword("2432tgh");
return conditionDTO;
}
BeanPropertySqlParameterSource beanParam = new BeanPropertySqlParameterSource(getConditionDTO());
template.update("INSERT INTO T_USER(username,password) VALUES(:username,:password)",beanParam);
API: int update(String sql, SqlParameterSource paramSource)
MapSqlParameterSource mapSql = new MapSqlParameterSource();
mapSql.addValue("username","李连杰")
.addValue("password","huewrgowrei");
template.update("INSERT INTO T_USER(username,password) VALUES(:username,:password)",mapSql);
注意:单行单列不是单独的一行或者单独的一列数据,单列单行是只有一个数据,如下:
API: public < T > T queryForObject(String sql, Map
API: public < T > T queryForObject(String sql, SqlParameterSource paramSource, Class
Integer count = template.queryForObject(
"SELECT COUNT(*) FROM T_USER", new HashMap<>(), Integer.class);
使用EmptySqlParameterSource:
String username = template.queryForObject( "SELECT USERNAME FROM T_USER WHERE ID = 4", EmptySqlParameterSource.INSTANCE, String.class);
多行单列形式:
API: public < T> List< T> queryForList(String sql, Map
API: public < T> List< T> queryForList(String sql, SqlParameterSource paramSource, Class< T> elementType)
List< String> nameList = template.queryForList("SELECT USERNAME FROM T_USER", new HashMap<>(), String.class);
nameList.forEach(System.out::println);
控制台打印结果:
解释:数据库中的一行数据对应的就是java中的一个bean实体
API:public < T> T queryForObject(String sql, Map< String, ?> paramMap, RowMapper< T>rowMapper)
API: public < T> T queryForObject(String sql, SqlParameterSource paramSource, RowMapper< T> rowMapper)
//BeanPropertyRowMapper会把下划线转化为驼峰属性
TUser user = template.queryForObject(
"SELECT * FROM T_USER LIMIT 1", new HashMap<>(), new BeanPropertyRowMapper<TUser>(TUser.class));
System.out.println("查询出来的user是:"+user);
API: public Map< String, Object> queryForMap(String sql, Map< String, ?> paramMap)
API: public Map< String, Object> queryForMap(String sql, SqlParameterSource paramSource)
@RequestMapping("/querySingleTwo")
public Map testQueryForObjectTwo() {
Map< String, Object> userMap = template.queryForMap("SELECT * FROM T_USER LIMIT 1", new HashMap<>());
System.out.println(userMap);
return userMap;
}
postman返回结果:
API: public < T> List< T> query(String sql, Map< String, ?> paramMap, RowMapper< T> rowMapper)
API: public < T> List< T> query(String sql, SqlParameterSource paramSource, RowMapper< T> rowMapper)
API: public < T> List< T> query(String sql, RowMapper< T> rowMapper)
@RequestMapping("/querySingleTwo")
public List< TUser> testQueryForObjectTwo() {
List< TUser> userList = template.query(
"SELECT * FROM T_USER",
new BeanPropertyRowMapper<>(TUser.class)
);
return userList;
}
postman返回结果:
[
{
"id": 1,
"username": "admin",
"password": "admin"
},
{
"id": 2,
"username": "abc",
"password": "123"
},
{
"id": 3,
"username": "abcd",
"password": "1234"
},
{
"id": 4,
"username": "abcde",
"password": "12345"
},
{
"id": 109,
"username": "刘亦菲",
"password": "4983ghh"
},
{
"id": 110,
"username": "刘亦菲",
"password": "4983ghh"
},
{
"id": 111,
"username": "成龙",
"password": "2432tgh"
},
{
"id": 112,
"username": "李连杰",
"password": "huewrgowrei"
}
]
API: public List< Map< String, Object>> queryForList(String sql, Map< String, ?> paramMap)
API: public List< Map< String, Object>> queryForList(String sql, SqlParameterSource paramSource)
@RequestMapping("/querySingleTwo")
public List<Map<String, Object>> testQueryForObjectTwo() {
List<Map<String, Object>> mapList = template.queryForList(
"SELECT * FROM T_USER", new HashMap<>());
return mapList;
}
postman返回结果:
[
{
"id": 1,
"username": "admin",
"password": "admin"
},
{
"id": 2,
"username": "abc",
"password": "123"
},
{
"id": 3,
"username": "abcd",
"password": "1234"
},
{
"id": 4,
"username": "abcde",
"password": "12345"
},
{
"id": 109,
"username": "刘亦菲",
"password": "4983ghh"
},
{
"id": 110,
"username": "刘亦菲",
"password": "4983ghh"
},
{
"id": 111,
"username": "成龙",
"password": "2432tgh"
},
{
"id": 112,
"username": "李连杰",
"password": "huewrgowrei"
}
]
NamedParameterJdbcTemplate还新增了KeyHolder类,使⽤它我们可以获得主键,类似Mybatis中的useGeneratedKeys。
代码示例:
@RequestMapping("/querySingleTwo")
public int testQueryForObjectTwo() {
String sql = "INSERT INTO T_USER(username,password) VALUES(:username,:password)";
ConditionDTO conditionDTO = new ConditionDTO("r43g", "呼呼");
SqlParameterSource sqlParameterSource = new BeanPropertySqlParameterSource(conditionDTO);
KeyHolder keyHolder = new GeneratedKeyHolder();
template.update(sql, sqlParameterSource, keyHolder);
int k = keyHolder.getKey().intValue();
System.out.println("主键值是:"+k);
return k;
}
返回结果就是新增的主键。
方法源码:
List<TUser> list = new ArrayList<>();
TUser tUser1 = new TUser();
tUser1.setPassword("t7493857vd");
tUser1.setUsername("给会儿");
TUser tUser2 = new TUser();
tUser2.setPassword("erwghrthey");
tUser2.setUsername("国瑞");
list.add(tUser1);
list.add(tUser2);
SqlParameterSource[] batch = SqlParameterSourceUtils.createBatch(list.toArray());
template.batchUpdate("INSERT INTO T_USER(username,password) VALUES(:username,:password)",batch);
List<TUser> list = new ArrayList<>();
TUser tUser1 = new TUser();
tUser1.setPassword("eryg");
tUser1.setUsername("个人谈话人");
tUser1.setId(109);
TUser tUser2 = new TUser();
tUser2.setPassword("我二哥");
tUser2.setUsername("个羊肉汤");
tUser1.setId(110);
TUser tUser3 = new TUser();
tUser3.setPassword("gerhr6");
tUser3.setUsername("反倒是规范");
tUser3.setId(111);
list.add(tUser1);
list.add(tUser2);
list.add(tUser3);
SqlParameterSource[] batch = SqlParameterSourceUtils.createBatch(list.toArray());
template.batchUpdate("UPDATE T_USER SET USERNAME = :username,PASSWORD = :password WHERE ID = :id",batch);
List<TUser> list = new ArrayList<>();
TUser tUser1 = new TUser();
tUser1.setId(109);
TUser tUser2 = new TUser();
tUser2.setId(112);
TUser tUser3 = new TUser();
tUser3.setId(113);
list.add(tUser1);
list.add(tUser2);
list.add(tUser3);
SqlParameterSource[] batch = SqlParameterSourceUtils.createBatch(list.toArray());
template.batchUpdate("DELETE FROM T_USER WHERE ID = :id",batch);