Посмотрите на своего мужчину:
List<Student> getStudentsOfGradeStateAndGenderWithPositionalParams(int grade, String state, String gender) {
String sql = "select student_id, student_name, age, grade, gender, state from student where grade = ? and state = ? and gender = ?";
return jdbcTemplate.query(sql, new Object[]{grade, state, gender}, new StudentRowMapper());
}
А теперь на меня:
List<Student> getStudentsOfGradeStateAndGenderWithPositionalParams(int grade, String state, String gender) {
String sql = "select student_id, student_name, age, grade, gender, state from student where grade = ? and state = ? and gender = ?";
return jdbcClient.sql(sql)
.param(grade)
.param(state)
.param(gender)
.query(new StudentRowMapper()).list();
}
Это и есть новая фича Spring Framework 6.1, которая предоставляет интерфейс
JdbcClient, благодаря которому параметры запроса можно указывать прямо в chain-вызовах.Предположим, что у нас есть таблица
student с полями student_id (INT), student_name (VARCHAR(255)), age (INT), grade (INT), gender (VARCHAR(10)) и state VARCHAR(100)Объявим bean:
@Repository
class StudentDao {
@Autowired
private JdbcClient jdbcClient;
}
JdbcClient готов к использованию.Нам также завезли поддержку именованных параметров:
int getCountOfStudentsOfGradeStateAndGenderWithNamedParam(int grade, String state, String gender) {
String sql = "select student_id, student_name, age, grade, gender, state from student where grade = :grade and state = :state and gender = :gender";
var countCallbackHandler = new RowCountCallbackHandler();
jdbcClient.sql(sql)
.param("grade", grade)
.param("state", state)
.param("gender", gender)
.query(countCallbackHandler);
return countCallbackHandler.getRowCount();
}
Если необходимо обратиться к параметру запроса по индексу:
List<Student> getStudentsOfGradeStateAndGenderWithParamIndex(int grade, String state, String gender) {
String sql = "select student_id, student_name, age, grade, gender, state from student"
+ " where grade = ? and state = ? and gender = ?";
return jdbcClient.sql(sql)
.param(1, grade)
.param(2, state)
.param(3, gender)
.query(new StudentResultExtractor());
}
А еще можем вытащить значения полей прямо из объекта класса, но в этот раз продемонстрируем пример с использованием перегруженного метода
param(), который в качестве третьего параметра примет тип данных, чтобы избежать возможных проблем при сопоставлении типов между Java-приложением и БД (например, при использовании null-значений), после чего вызвать метод update():
Integer insertWithSetParamWithNamedParamAndSqlType(Student student) {
String sql = "INSERT INTO student (student_name, age, grade, gender, state) VALUES (:name, :age, :grade, :gender, :state)";
var noOfRowsAffected = this.jdbcClient.sql(sql)
.param("name", student.getStudentName(), Types.VARCHAR)
.param("age", student.getAge(), Types.INTEGER)
.param("grade", student.getGrade(), Types.INTEGER)
.param("gender", student.getStudentGender(), Types.VARCHAR)
.param("state", student.getState(), Types.VARCHAR)
.update()
return noOfRowsAffected;
}
Можно передать целый список параметров, однако в этом случае необходимо использовать метод
params() (таким же образом можно использовать и объект Map в качестве входного параметра):
Optional<Student> getStudentsOfGradeStateAndGenderWithParamsInList(List params) {
String sql = "select student_id, student_name, age, grade, gender, state from student"
+ " where grade = ? and state = ? and gender = ? limit 1";
return jdbcClient.sql(sql)
.params(params)
.query(new StudentRowMapper()).optional();
}
По итогу интерфейс
JdbcClient объединяет возможности JdbcTemplate и NamedParameterJdbcTemplate, предоставляя более удобный API для работы с JDBC. Благодаря этому можно вызывать методы цепочкой.Ставьте 🔥 если фича кажется полезной
