使用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/下載示例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-jdbc
artifact會給出所有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','[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.url
Postgres 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插入了一個條目。
TEST3:更新員工
HTTP://本地主機:8080 / PostgresApp / executeUpdateEmp
測試4:刪除員工
HTTP://本地主機:8080 / PostgresApp / deleteEmpById
結論
我們已經學會了如何使用Postgres設定Spring Boot並使用NameParameterJdbcTemplate來進行CRUD操作。