Spring JDBC – Tại sao cần Spring JDBC, Code ví dụ với JdbcTemplate

Spring JDBC – Tại sao cần Spring JDBC, Code ví dụ với JdbcTemplate

Database sử dụng: Mysql

Spring version 5

1. Spring JdbcTemplate là gì? So sánh Spring JDBC với JDBC

Các vấn đề tồn tại với JDBC API:

  • Cần viết nhiều code trước và sau thực hiện query (tạo connection, statement, đóng resultset, đóng connection…)
  • Cần phải xử lý transaction

Spring JdbcTemplate cũng tiến hành giao tiếp với database thông qua cơ chế của JDBC nhưng nó cải thiện được các vấn đề trên, cung cấp các method viết query trực tiếp -> tiết kiệm thời gian…

Spring JDBC – Tại sao cần Spring JDBC, Code ví dụ với JdbcTemplate

2. Code ví dụ với JdbcTemplate

Tạo database “spring-jdbc”

CREATE SCHEMA `spring-jdbc` ;

(Xem lại: Cài đặt và cấu hình MySQL)

Spring JDBC - Hướng dẫn Spring JDBC, Code ví dụ với JdbcTemplate

Bây giờ mình sẽ viết 1 chương trình Java kết nối tới database spring-jdbc

  • Tạo 1 table ‘user_info’ với 3 column (id, name, address) trong đó id kiểu int là primary key và tự tăng; name và address kiểu varchar
  • Thêm, sửa, xóa, truy vấn với table ‘user_info’ đã tạo ở trên.

Spring JDBC - Tại sao cần Spring JDBC, Code ví dụ với JdbcTemplate

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>

Trong đó spring-jdbc là thư viện dành cho sử dụng spring jdbc, mysql-connector-java là thư viện jdbc làm việc với mysql

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>

</beans>
  • datasource – là class tiện ích dùng để truy cập database. Nó lưu thông tin kết nối database như url, username, password… Bạn cũng có thể lấy ra connection từ datasource và thực hiện truy vấn database giống jdbc thông thường, ví dụ
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
JdbcTemplate jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");
DriverManagerDataSource dataSource = (DriverManagerDataSource) ctx.getBean("dataSource");
Connection con = dataSource.getConnection();
String sql = "...";
Statement statement = (Statement) con.prepareStatement(sql);
PreparedStatement pStatement = con.prepareStatement(sql);
CallableStatement cStatement = con.prepareCall(sql);

Class entities

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;
  }

  // getter - setter

}

2.1 Tạo table với JdbcTemplate

package stackjava.com.springjdbc.mainapp;

import java.sql.SQLException;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;

public class CreateTable {
  public static void main(String[] args) throws SQLException {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    JdbcTemplate jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");

    /* -------------- Create table user_info ----------------- */
    String sql = "CREATE TABLE user_info (" +
        "  id int(11) NOT NULL AUTO_INCREMENT," +
        "  name varchar(45) DEFAULT NULL," +
        "  address varchar(255) DEFAULT NULL," +
        "  PRIMARY KEY (id)" +
        ")";
    jdbcTemplate.execute(sql);
    ((ClassPathXmlApplicationContext) ctx).close();

    System.out.println("Table is Created!");
  }
}

method execute của JdbcTemplate dùng để thực hiện các câu SQL đơn, DDL (tạo, sửa, xóa, table)

Kết quả:

Spring JDBC - Hướng dẫn Spring JDBC, Code ví dụ với JdbcTemplate

2.2 Insert row với JdbcTemplate

package stackjava.com.springjdbc.mainapp;

import java.sql.SQLException;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;

public class InsertRow {
  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.update(sql, "Vin Diesel", "USA");
    jdbcTemplate.update(sql, "Dwayne Jonhson", "USA");
    jdbcTemplate.update(sql, "Doremon", "Japan");
    ((ClassPathXmlApplicationContext) ctx).close();
    System.out.println("Inserted!");
  }
}

Thực hiện insert 4 record vào table user_info (id tự tăng nên mình không truyền id vào câu SQL)

Method update của JdbcTemplate dùng để thực hiện các câu SQL thao tác dữ liệu như INSERT, UPDATE, DELTE

  • Nếu method update của bạn không có tham số truyền vào câu SQL thì nó sẽ thực hiện thông qua Statement
  • Nếu method update của bạn truyền tham số vào câu SQL thì nó thực hiện thông qua PreparedStatement

Ở đây mình truyền name với address vào câu SQL do đó nó thực hiện thông qua PreparedStatement)

(Xem lại: So sánh Statement với PreparedStatement, CallableStatement)

Kết quả:

method update của JdbcTemplate dùng để thực hiện các câu SQL thao tác dữ liệu như INSERT, UPDATE, DELTE

2.3 Thực hiện SELECT dữ liệu thông qua JdbcTemplate

package stackjava.com.springjdbc.mainapp;

import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;

import stackjava.com.springjdbc.entities.User;
import stackjava.com.springjdbc.entities.UserMapper;

public class SelectRow {
  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 WHERE address = ?";
    List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql, "USA");
    for (Map<String, Object> row : rows) {
      System.out.println(row.get("id") +"  " + row.get("name") + "  " + row.get("address"));
    }
    
    System.out.println("----------------------------------");
    List<User> listUser2 = jdbcTemplate.query(sql, new UserMapper(), "USA");
    for (User user: listUser2) {
      System.out.println(user.getId() + "  " +user.getName() + "  " + user.getAddress());
    }

    ((ClassPathXmlApplicationContext) ctx).close();
  }
}
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;

  }

}

Ở đây mình thực hiện select theo 2 cách

  • Cách thứ nhất: List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql, "USA"); sẽ trả về danh sách các map chứa column name và giá trị tương ứng. (mỗi row tương ứng với 1 map)
  • Cách thứ hai: List<User> listUser2 = jdbcTemplate.query(sql, new UserMapper(), "USA"); sẽ chuyển kết quả trả về sang đối tượng User

(“USA” là tham số truyền vào câu SQL)

Kết quả:

2.3 Thực hiện SELECT dữ liệu thông qua JdbcTemplate

2.4 Thực hiện UPDATE dữ liệu thông qua JdbcTemplate

package stackjava.com.springjdbc.mainapp;

import java.sql.SQLException;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;

public class UpdateRow {
  public static void main(String[] args) throws SQLException {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    JdbcTemplate jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");
    String sql = "UPDATE user_info SET address = 'VietNam' WHERE address = 'England';";
    jdbcTemplate.update(sql);
    ((ClassPathXmlApplicationContext) ctx).close();
    System.out.println("Updated!");
  }
}

Ở đây mình thực hiện update addres từ “England” sang “Address”

Kết quả:

2.4 Thực hiện UPDATE dữ liệu thông qua JdbcTemplate

2.5 Thực hiện DELETE dữ liệu thông qua JdbcTemplate

package stackjava.com.springjdbc.mainapp;

import java.sql.SQLException;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;

public class DeleteRow {
  public static void main(String[] args) throws SQLException {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    JdbcTemplate jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");
    String sql = "DELETE FROM user_info WHERE address = 'Japan';";
    jdbcTemplate.update(sql);
    ((ClassPathXmlApplicationContext) ctx).close();
    System.out.println("Deleted!");
  }
}

Xóa user có address = “Japan”

Kết quả:

2.5 Thực hiện DELETE dữ liệu thông qua JdbcTemplate

Spring JDBC – Tại sao cần Spring JDBC, Code ví dụ với JdbcTemplate

Okay, Done!

Download code ví dụ trên tại đây.

References:

https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/jdbc/core/JdbcTemplate.html

https://docs.spring.io/spring/docs/current/spring-framework-reference/data-access.html#jdbc

stackjava.com