Spring JDBC – Ví dụ PreparedStatement, ResultSetExtractor, RowMapper, NamedParameterJdbcTemplate trong Spring JDBC
Trong bài này chúng ta sẽ tìm hiểu một số class trong Spring JDBC như ResultSetExtractor, RowMapper, NamedParameterJdbcTemplate, SimpleJdbcTemplate.
Tạo cơ sở dữ liệu
Tạo database “spring-jdbc”
CREATE SCHEMA `spring-jdbc` ;
(Xem lại: Cài đặt và cấu hình MySQL)
Tạo table “user_info”
CREATE TABLE `spring-jdbc`.`user_info` ( `id` INT NOT NULL AUTO_INCREMENT, `name` VARCHAR(45) NULL, `address` VARCHAR(255) NULL, PRIMARY KEY (`id`));
Code ví dụ:
Thư viện sử dụng:
<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> <groupId>stackjava.com</groupId> <artifactId>SpringJDBC</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>6.0.6</version> </dependency> </dependencies> </project>
File spring config:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/spring-jdbc" /> <property name="username" value="root" /> <property name="password" value="admin1234" /> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <bean id="npJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate"> <constructor-arg ref="dataSource"></constructor-arg> </bean> </beans>
PreparedStatement
Trong bài trước, khi thực hiện query insert mình có nói khi insert với tham số truyền vào thì spring JDBC sẽ insert thông qua PreparedStatement thay vì Statement.
Ở phần này chúng ta sẽ chỉ rõ việc thực hiện query với PreparedStatement thông qua PreparedStatementCallback
Ví dụ:
package stackjava.com.springjdbc.mainapp; import java.sql.PreparedStatement; import java.sql.SQLException; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.PreparedStatementCallback; public class DemoPreparedStatementCallback { public static void main(String[] args) throws SQLException { ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); JdbcTemplate jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate"); String sql = "INSERT INTO user_info (name, address) VALUES (?, ?);"; // jdbcTemplate.update(sql, "Harry Potter", "England"); jdbcTemplate.execute(sql, new PreparedStatementCallback<Boolean>() { public Boolean doInPreparedStatement(PreparedStatement ps) throws SQLException, DataAccessException { ps.setString(1, "Harry Potter"); ps.setString(2, "England"); return ps.execute(); } }); ((ClassPathXmlApplicationContext) ctx).close(); System.out.println("Inserted!"); } }
Kết quả:
NamedParameterJdbcTemplate
NamedParameterJdbcTemplate hỗ trợ việc insert data bằng việc đặt tên các tham số, với cách này chúng ta sử dụng tên các tham số thay vì dùng dấu ‘?’, cách này tốt hơn việc chúng ta phải nhớ tên các column.
Ví dụ:
package stackjava.com.springjdbc.mainapp; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.PreparedStatementCallback; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; public class DemoPreparedStatementCallback { public static void main(String[] args) throws SQLException { ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); NamedParameterJdbcTemplate npJdbcTemplate = (NamedParameterJdbcTemplate) ctx.getBean("npJdbcTemplate"); String sql = "INSERT INTO user_info (name, address) VALUES (:name, :address);"; Map<String, String> paramMap = new HashMap<String, String>(); paramMap.put("name", "Sylvester Stallon"); paramMap.put("address", "USA"); npJdbcTemplate.execute(sql, paramMap, new PreparedStatementCallback<Boolean>() { public Boolean doInPreparedStatement(PreparedStatement ps) throws SQLException, DataAccessException { return ps.execute(); } }); ((ClassPathXmlApplicationContext) ctx).close(); System.out.println("Inserted!"); } }
Khi sử dụng method execute của NamedParameterJdbcTemplate, các đối tham số trong câu SQL sẽ tự động lấy tương ứng với các đối tượng trong paramMap có key trùng với param name để truyền vào PreparedStatement.
Kết quả:
ResultSetExtractor, RowMapper
Cả ResultSetExtractor và RowMapper đều được sử dụng để chuyển đổi dữ liệu từ câu query select thành các đối tượng mong muốn:
package stackjava.com.springjdbc.entities; public class User { private int id; private String name; private String address; public User() { } public User(int id, String name, String address) { this.id = id; this.name = name; this.address = address; } @Override public String toString() { return "User [id=" + id + ", name=" + name + ", address=" + address + "]"; } // getter - setter }
package stackjava.com.springjdbc.entities; import java.sql.ResultSet; import java.sql.SQLException; import org.springframework.jdbc.core.RowMapper; public class UserMapper implements RowMapper<User>{ public User mapRow(ResultSet rs, int rowNum) throws SQLException { User user= new User(); user.setId(rs.getInt("id")); user.setName(rs.getString("name")); user.setAddress(rs.getString("address")); return user; } }
package stackjava.com.springjdbc.mainapp; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.ResultSetExtractor; import stackjava.com.springjdbc.entities.User; import stackjava.com.springjdbc.entities.UserMapper; public class DemoResultSetExtractor_RowMapper { public static void main(String[] args) throws SQLException { ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); JdbcTemplate jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate"); String sql = "SELECT * FROM user_info"; System.out.println("------------ Using row ResultSetExtractor ----------------------"); List<User> listUser1 = jdbcTemplate.query(sql, new ResultSetExtractor<List<User>>() { public List<User> extractData(ResultSet rs) throws SQLException, DataAccessException { List<User> list = new ArrayList<User>(); while (rs.next()) { User user = new User(); user.setId(rs.getInt("id")); user.setName(rs.getString("address")); user.setAddress(rs.getString("address")); list.add(user); } return list; } }); for (User user: listUser1) { System.out.println(user); } System.out.println("------------ Using RowMapper ----------------------"); List<User> listUser2 = jdbcTemplate.query(sql, new UserMapper()); for (User user : listUser2) { System.out.println(user); } ((ClassPathXmlApplicationContext) ctx).close(); } }
Kết quả:
------------ Using row ResultSetExtractor ---------------------- User [id=1, name=England, address=England] User [id=2, name=USA, address=USA] ------------ Using RowMapper ---------------------- User [id=1, name=Harry Potter, address=England] User [id=2, name=Sylvester Stallon, address=USA]
Okay, Done!
Phần sau chúng ta sẽ tìm hiểu về Spring JDBC Batch, và Transaction với Spring JDBC.
Download code ví dụ trên tại đây
Spring JDBC – Ví dụ PreparedStatement, ResultSetExtractor, RowMapper, NamedParameterJdbcTemplate trong Spring JDBC
References:
https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/jdbc/core/RowMapper.html