使用NamedParameterJdbcTemplate指定命名参数

在本文中,我们将介绍如何在连接到后端Postgres数据库的Spring启动应用程序中使用NamedParameterJdbcTemplate。我们将使用NamedParameterJdbcTemplate从Postgres DB插入,更新和删除员工。为了保持设计的合理性,我将dao,service和controller分开了。服务只是本文的一个转折点。

概观
NamedParameterJdbcTemplate是一个模板类,它允许一组基本的JDBC操作。它有一个底层的经典JdbcTemplate,允许用'?'运行本机SQL查询 占位符在准备好的报表的执行时间。NamedParameterJdbcTemplate实现NamedParameterJdbcOperations接口,并在JdbcOperations接口中保存JdbcTemplate对象的引用。

先决条件
jdk1.8已安装
Postgres 10.x已安装
让我们现在设置项目:

https://start.spring.io/下载... Boot项目
更新pom.xml如下:
<?xml version =“1.0”encoding =“UTF-8”?>
< project xmlns = “http://maven.apache.org/POM/4...” xmlns:xsi = “http://www.w3.org/2001/XMLSch...
xsi:schemaLocation = “http://maven.apache.org/POM/4... http://maven.apache.org/xsd/maven-4.0.0.xsd” >
< modelVersion > 4.0.0 </ modelVersion >
< parent >
< groupId > org.springframework.boot </ groupId >
< artifactId > spring-boot-starter-parent </ artifactId >
< version > 2.1.1.RELEASE </ version >
< relativePath /> <! - 从存储库查找父级 - >
</ parent >
< groupId > com.sample </ groupId >
< artifactId > postgress </ artifactId >
< version > 0.0.1-SNAPSHOT </ version >
< name > postgress </ name >
< description > Spring Boot的演示项目</ description >
< properties >
< java.version > 1.8 </ java.version >
</ properties >
< dependencies >
< 依赖>
< groupId > org.springframework.boot </ groupId >
< artifactId > spring-boot-starter </ artifactId >
</ dependency >
< 依赖>
< groupId > org.springframework.boot </ groupId >
< artifactId > spring-boot-starter-web </ artifactId >
</ dependency >
< 依赖>
< groupId > org.springframework.boot </ groupId >
< artifactId > spring-boot-starter-jdbc </ artifactId >
</ dependency >
< 依赖>
< groupId > org.postgresql </ groupId >
< artifactId > postgresql </ artifactId >
< scope > runtime </ scope >
</ dependency >
< 依赖>
< groupId > org.springframework.boot </ groupId >
< artifactId > spring-boot-starter-test </ artifactId >
< scope > test </ scope >
</ dependency >
</ dependencies >
< build >
< plugins >
< 插件>
< groupId > org.springframework.boot </ groupId >
< artifactId > spring-boot-maven-plugin </ artifactId >
</ plugin >
</ plugins >
</ build >
</ project >
spring-boot-starter-jdbcartifact会给出所有spring jdbc相关的jar,并且org.postgresql.postgresql会在运行时具有Postgres jdbc驱动程序的依赖关系。

在资源文件夹中创建schema.sql。将在服务器启动时创建一个employee表。如果您不希望在服务器启动期间配置初始数据库,则可以忽略此项。通常,对于构建生产就绪的应用程序,可以忽略此步骤,因为将直接在DB中使用脚本创建表。
CREATE TABLE员工

employeeName varchar(100)NOT NULL,
employeeId varchar(11)NOT NULL,
employeeAddress varchar(100)DEFAULT NULL,
employeeEmail varchar(100)DEFAULT NULL,
主要关键(employeeId)
);
在资源文件夹中创建data.sql,以便在启动期间加载第一组员工。否则可以跳过:
insert into employee(employeeId, employeeName , employeeAddress,employeeEmail) values('1','Jack','USA','jack@gmail.com');

application.properties中的更改,以使用Postgres DB的URL,用户名和密码配置数据源。5432是Postgres的默认端口。Hibernate将自动获取PostgresSQLDialect。
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-AUTO =无
spring.jpa.hibernate.show-SQL =真
spring.datasource.url = JDBC:在PostgreSQL://本地主机:5432 / postgres的
spring.datasource.username = postgres的
spring.datasource.password =管理员
spring.datasource.initialization模式=总是
spring.datasource.initialize =真
spring.datasource.schema =类路径:/schema.sql
spring.datasource.continue上误差=真
spring.jpa.hibernate.ddl-auto将关闭来自实体对象的表的休眠自动创建。通常,如果定义了实体,Hibernate会运行它。但是我们将使用JdbcTemplate的本机SQL查询,因此,我们可以将其关闭,因为我们不会创建任何实体。

spring.datasource.initialization-mode标记为始终,因为我们希望每次启动时都会初始化数据库。这是可选的,用于此示例目的。

spring.datasource.initialize=true 将标记初始化为真。

spring.datasource.continue-on-error=true 尽管数据初始化有任何错误,仍会继续启动应用程序。

spring.datasource.schema 是需要初始化的架构路径。

spring.datasource.urlPostgres DB的URL。它也可以是远程数据库。

spring.datasource.username 数据库的用户名

spring.datasource.password 数据库的密码

创建一个dao接口和dao实现
包 com。样品。事后。道 ;
导入 java。util。清单 ;
进口 com。样品。事后。实体。员工 ;
公共 接口 EmployeeDao {
List < Employee > findAll();
void insertEmployee(Employee emp);
void updateEmployee(Employee emp);
void executeUpdateEmployee(Employee emp);
public void deleteEmployee(Employee emp);
}
包 com。样品。事后。道 ;
导入 java。sql。PreparedStatement ;
导入 java。sql。SQLException ;
导入 java。util。HashMap ;
导入 java。util。清单 ;
导入 java。util。地图 ;
进口 组织。弹簧框架。道。DataAccessException ;
进口 组织。弹簧框架。jdbc。核心。PreparedStatementCallback ;
进口 组织。弹簧框架。jdbc。核心。namedparam。MapSqlParameterSource ;
进口 组织。弹簧框架。jdbc。核心。namedparam。NamedParameterJdbcTemplate ;
进口 组织。弹簧框架。jdbc。核心。namedparam。SqlParameterSource ;
进口 组织。弹簧框架。jdbc。支持。GeneratedKeyHolder ;
进口 组织。弹簧框架。jdbc。支持。KeyHolder ;
进口 组织。弹簧框架。刻板印象。存储库 ;
进口 com。样品。事后。实体。员工 ;
进口 com。样品。事后。映射器。EmployeeRowMapper ;
@Repository
公共 类 EmployeeDaoImpl 实现 EmployeeDao {
public EmployeeDaoImpl(NamedParameterJdbcTemplate template){

    这个。template  =  template ;  

}
NamedParameterJdbcTemplate 模板 ;
@覆盖
public List < Employee > findAll(){
返回 模板。query(“select * from employee”,new EmployeeRowMapper());
}
@覆盖
public void insertEmployee(Employee emp){
final String sql = “insert into employee(employeeId,employeeName,employeeAddress,employeeEmail)values(:employeeId,:employeeName,:employeeEmail,:employeeAddress)” ;

    KeyHolder  holder  =  new  GeneratedKeyHolder();
    SqlParameterSource  param  =  new  MapSqlParameterSource()

。的addValue(“雇员”,EMP。getEmployeeId())
。的addValue(“employeeName” ,EMP。getEmployeeName())
。的addValue(“employeeEmail” ,EMP。getEmployeeEmail())
。的addValue(“employeeAddress” ,EMP。getEmployeeAddress());

    模板。update(sql,param,holder);

}
@覆盖
public void updateEmployee(Employee emp){
final String sql = “update employee set employeeName =:employeeName,employeeAddress =:employeeAddress,employeeEmail =:employeeEmail where employeeId =:employeeId” ;

    KeyHolder  holder  =  new  GeneratedKeyHolder();
    SqlParameterSource  param  =  new  MapSqlParameterSource()

。的addValue(“雇员”,EMP。getEmployeeId())
。的addValue(“employeeName” ,EMP。getEmployeeName())
。的addValue(“employeeEmail” ,EMP。getEmployeeEmail())
。的addValue(“employeeAddress” ,EMP。getEmployeeAddress());

    模板。update(sql,param,holder);

}
@覆盖
public void executeUpdateEmployee(Employee emp){
final String sql = “update employee set employeeName =:employeeName,employeeAddress =:employeeAddress,employeeEmail =:employeeEmail where employeeId =:employeeId” ;
Map < String,Object > map = new HashMap < String,Object >();
地图。把(“雇员”,EMP。getEmployeeId());
地图。把(“employeeName” ,EMP。getEmployeeName());
地图。把(“employeeEmail” ,EMP。getEmployeeEmail());
地图。把(“employeeAddress” ,EMP。getEmployeeAddress());
模板。execute(sql,map,new PreparedStatementCallback < Object >(){

@覆盖  
public  Object  doInPreparedStatement(PreparedStatement  ps)  
        抛出 SQLException,DataAccessException {  
    返回 ps。executeUpdate();  
}  

});
}
@覆盖
public void deleteEmployee(Employee emp){
final String sql = “从员工中删除employeeId =:employeeId” ;
Map < String,Object > map = new HashMap < String,Object >();
地图。把(“雇员”,EMP。getEmployeeId());
模板。execute(sql,map,new PreparedStatementCallback < Object >(){

@覆盖  
public  Object  doInPreparedStatement(PreparedStatement  ps)  
        抛出 SQLException,DataAccessException {  
    返回 ps。executeUpdate();  
}  

});
}
}
findAll()检索所有雇员,然后使用下面描述的RowMapper将结果集映射到Employee对象。

insertEmployee()将使用template.update(sql,param, holder) param是SqlParameterSource 来插入一个雇员,它将在用冒号标记的查询中动态映射值。插入数据时,GeneratedKeyHolder将返回自动生成的值。

executeUpdateEmployee()将使用更新员工 template.execute

模板。execute(sql,map,new PreparedStatementCallback < Object >(){

@覆盖  
public  Object  doInPreparedStatement(PreparedStatement  ps)  
        抛出 SQLException,DataAccessException {  
    返回 ps。executeUpdate();  
}  

});
EmployeeRowMapper将使用POJO 从select查询中检索的结果集映射。
包 com。样品。事后。映射器 ;
导入 java。sql。ResultSet ;
导入 java。sql。SQLException ;
进口 组织。弹簧框架。jdbc。核心。RowMapper ;
进口 com。样品。事后。实体。员工 ;
公共 类 EmployeeRowMapper 实现 RowMapper < Employee > {
@覆盖
public Employee mapRow(ResultSet rs,int arg1)抛出 SQLException {
Employee emp = new Employee();
emp。setEmployeeId(RS。的getString(“雇员”));
emp。setEmployeeName(RS。的getString(“employeeName” ));
emp。setEmployeeEmail(RS。的getString(“employeeEmail” ));

    返回 emp ;

}
}
您可以按如下方式创建控制器和服务类:
包 com。样品。事后。服务 ;
导入 java。util。清单 ;
导入 javax。注释。资源 ;
进口 组织。弹簧框架。刻板印象。组件 ;
进口 com。样品。事后。道。员工道 ;
进口 com。样品。事后。实体。员工 ;
@零件
公共 类 EmployeeServiceImpl 实现 EmployeeService {
@Resource
员工道 雇员道 ;
@覆盖
public List < Employee > findAll(){
返回 员工道。findAll();
}
@覆盖
public void insertEmployee(Employee emp){
employeeDao。insertEmployee(emp);
}
@覆盖
public void updateEmployee(Employee emp){
employeeDao。updateEmployee(emp);
}
@覆盖
public void executeUpdateEmployee(Employee emp){
employeeDao。executeUpdateEmployee(emp);
}
@覆盖
public void deleteEmployee(Employee emp){
employeeDao。deleteEmployee(emp);
}
}
包 com。样品。事后。控制器 ;
导入 java。util。清单 ;
导入 javax。注释。资源 ;
进口 组织。弹簧框架。网络。绑定。注释。DeleteMapping ;
进口 组织。弹簧框架。网络。绑定。注释。GetMapping ;
进口 组织。弹簧框架。网络。绑定。注释。PostMapping ;
进口 组织。弹簧框架。网络。绑定。注释。PutMapping ;
进口 组织。弹簧框架。网络。绑定。注释。RequestBody ;
进口 组织。弹簧框架。网络。绑定。注释。RequestMapping ;
进口 组织。弹簧框架。网络。绑定。注释。RestController ;
进口 com。样品。事后。实体。员工 ;
进口 com。样品。事后。服务。EmployeeService ;
@RestController
@RequestMapping(“/ postgressApp”)
public class ApplicationController {
@Resource
EmployeeService employeeService ;
@GetMapping(value = “/ employeeList”)
public List < Employee > getEmployees(){
返回 employeeService。findAll();
}
@PostMapping(value = “/ createEmp”)
public void createEmployee(@RequestBody Employee emp){
employeeService。insertEmployee(emp);
}
@PutMapping(value = “/ updateEmp”)
public void updateEmployee(@RequestBody Employee emp){
employeeService。updateEmployee(emp);
}
@PutMapping(value = “/ executeUpdateEmp”)
public void executeUpdateEmployee(@RequestBody Employee emp){
employeeService。executeUpdateEmployee(emp);
}
@DeleteMapping(value = “/ deleteEmpById”)
public void deleteEmployee(@RequestBody Employee emp){
employeeService。deleteEmployee(emp);
}
}
现在让我们使用POSTMAN验证更改:

测试1:获取员工列表

HTTP://本地主机:8080 / PostgresApp / EmployeeList的

图片标题

测试2:创建员工

HTTP://本地主机:8080 / PostgresApp / createEmp

图片标题

我们看到JONES插入了一个条目。

图片标题

测试3:更新员工

HTTP://本地主机:8080 / PostgresApp / executeUpdateEmp

图片标题

图片标题

测试4:删除员工

HTTP://本地主机:8080 / PostgresApp / deleteEmpById

图片标题

图片标题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值