1. 程式人生 > >使用NamedParameterJdbcTemplate指定命名引數

使用NamedParameterJdbcTemplate指定命名引數

在本文中,我們將介紹如何在連線到後端Postgres資料庫的Spring啟動應用程式中使用NamedParameterJdbcTemplate。我們將使用NamedParameterJdbcTemplate從Postgres DB插入,更新和刪除員工。為了保持設計的合理性,我將dao,service和controller分開了。服務只是本文的一個轉折點。

概觀

NamedParameterJdbcTemplate是一個模板類,它允許一組基本的JDBC操作。它有一個底層的經典JdbcTemplate,允許用'?'執行本機SQL查詢 佔位符在準備好的報表的執行時間。NamedParameterJdbcTemplate實現NamedParameterJdbcOperations介面,並在JdbcOperations介面中儲存JdbcTemplate物件的引用。

先決條件

  1. jdk1.8已安裝
  2. Postgres 10.x已安裝

讓我們現在設定專案:

  • 從https://start.spring.io/下載示例Spring Boot專案
  • 更新pom.xml如下:
<?xml  version =“1.0”encoding =“UTF-8”?>
< project  xmlns = “http://maven.apache.org/POM/4.0.0”  xmlns:xsi = “http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation = “http://maven.apache.org/POM/4.0.0 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 varchar100NOT  NULL
  employeeId varchar11NOT  NULL
employeeAddress varchar100)DEFAULT NULL
employeeEmail varchar100)DEFAULT NULL
 主要關鍵(employeeId)
);
  • 在資原始檔夾中建立data.sql,以便在啟動期間載入第一組員工。否則可以跳過:

insert into employee(employeeId, employeeName , employeeAddress,employeeEmail) values('1','Jack','USA','[email protected]');

  • 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 < StringObject >  map = new  HashMap < StringObject >();  
 地圖。把(“僱員”,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 < StringObject >  map = new  HashMap < StringObject >();  
 地圖。把(“僱員”,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插入了一個條目。

圖片標題

TEST3:更新員工

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

圖片標題

圖片標題

測試4:刪除員工

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

圖片標題

圖片標題

結論

我們已經學會了如何使用Postgres設定Spring Boot並使用NameParameterJdbcTemplate來進行CRUD操作。