Для виконання SQL-інструкції не потрібно багато коду. Потрібно DataSource
та JdbcTemplate
,
включно з допоміжними методами, які надаються разом з JdbcTemplate
. У цьому прикладі показано, що має
бути у складі мінімального, але повністю функціонального класу, який створює нову таблицю:
import javax.sql.DataSource;
import org.springframework.jdbc.core.JdbcTemplate;
public class ExecuteAStatement {
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = новий JdbcTemplate(dataSource);
}
public void doExecute() {
this.jdbcTemplate.execute("create table mytable (id integer, name varchar(100))");
}
}
import javax.sql.DataSource
import org.springframework.jdbc.core.JdbcTemplate
class ExecuteAStatement(dataSource: DataSource) {
private val jdbcTemplate = JdbcTemplate(dataSource)
fun doExecute() {
jdbcTemplate.execute("create table mytable (id integer, name varchar(100))")
}
}
Виконання запитів
Деякі методи запитів повертають єдине значення. Щоб отримати лічильник або конкретне значення з одного рядка,
використовуй queryForObject(..)
. Останній перетворює повертається Type
з JDBC на
Java-клас, переданий як аргумент. Якщо перетворення типу недійсне, буде згенеровано виняток InvalidDataAccessApiUsageException
.
Наступний приклад містить два методи запиту, один для int
, а інший для String
:
import javax.sql.DataSource;
import org.springframework.jdbc.core.JdbcTemplate;
public class RunAQuery {
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = новий JdbcTemplate(dataSource);
}
public int getCount() {
return this.jdbcTemplate.queryForObject("select count(*) from mytable", Integer.class);
}
public String getName() {
return this.jdbcTemplate.queryForObject("select name from mytable", String.class);
}
}
import javax.sql.DataSource
import org.springframework.jdbc.core.JdbcTemplate
class RunAQuery(dataSource: DataSource) {
private val jdbcTemplate = JdbcTemplate(dataSource)
val count: Int
get() = jdbcTemplate.queryForObject("select count(*) from mytable")!!
val name: String?
get() = jdbcTemplate.queryForObject("select name from mytable")
}
На додаток до методів запиту з єдиним результатом кілька методів повертають список із записом для кожного рядка, який
повернув запит. Найбільш типізованим методом є queryForList(..)
, який повертає List
, де
кожен елемент є Map
, що містить по одному запису для кожного стовпця, використовуючи ім'я стовпця як
ключ. Якщо до попереднього прикладу додати метод для отримання списку всіх рядків, він може виглядати так:
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = новий JdbcTemplate(dataSource);
}
public List<Map<String, Object>> getList() {
return this.jdbcTemplate.queryForList("select * from mytable");
}
private val jdbcTemplate = JdbcTemplate(dataSource)
fun getList(): List<Map<String, Any>> {
return jdbcTemplate.queryForList("select * from mytable")
}
Отриманий список буде виглядати так:
[{name=Bob, id=1}, {name=Mary, id=2}]
Оновлення бази даних
У наступному прикладі стовпець оновлюється для певного первинного ключа:
import javax.sql.DataSource;
import org.springframework.jdbc.core.JdbcTemplate;
public class ExecuteAnUpdate {
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = новий JdbcTemplate(dataSource);
}
public void setName(int id, String name) {
this.jdbcTemplate.update("update mytable set name = ? where id = ?", name, id);
}
}
import javax.sql.DataSource
import org.springframework.jdbc.core.JdbcTemplate
class ExecuteAnUpdate(dataSource: DataSource) {
private val jdbcTemplate = JdbcTemplate(dataSource)
fun setName(id: Int, name: String) {
jdbcTemplate.update("update mytable set name = ? where id = ?", name, id)
}
}
У попередньому прикладі SQL-інструкція містить плейсхолдери для параметрів рядка. Можна передати значення параметрів як аргументи змінної довжини (varargs) або, як альтернативу, як масив об'єктів. Таким чином, тобі потрібно явно огорнути примітивні типи в класи-обгортки примітивних типів, або використовувати автопакування.
Отримання автоматично згенерованих ключів
Допоміжний метод update()
підтримує отримання первинних ключів, створених базою даних. Ця підтримка є
частиною JDBC 3.0. Подробиці див. у розділі 13.6 специфікації. Метод приймає PreparedStatementCreator
як перший аргумент, і саме так встановлюється потрібна інструкція вставки. Іншим аргументом є KeyHolder
,
який містить згенерований ключ при успішному поверненні з оновлення. Немає єдиного стандартного способу створення
відповідного PreparedStatement
(що пояснює, чому сигнатура методу така, якою вона є). Наступний приклад
працює на Oracle, але не може працювати на інших платформах:
final String INSERT_SQL = "insert in my_test (name) values(?)";
final String name = "Rob";
KeyHolder keyHolder = New GeneratedKeyHolder();
jdbcTemplate.update(connection -> {
PreparedStatement ps = connection.prepareStatement(INSERT_SQL, new String[] {"id"});
ps.setString(1, name);
return ps;
}, keyHolder);
// keyHolder.getKey() тепер містить згенерований ключ
val INSERT_SQL = "insert in my_test (name) values(?)"
val name = "Rob"
val keyHolder = GeneratedKeyHolder()
jdbcTemplate.update({
it.prepareStatement (INSERT_SQL, arrayOf("id")).apply { setString(1, name) }
}, keyHolder)
// keyHolder.getKey() тепер містить згенерований ключ
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ