Оригинал: Ape Logic, добро пожаловать, пожалуйста, сохраните источник для перепечатки. Подписывайтесь на Xiaoq, чтобы изучать Java — самый быстрый способ продвижения.
Полный пример кода этой статьи см. в репозитории github. Xiaoq вводит в текст только самые важные блоки кода.
https://github.com/yuanluoji/purestart-springboot-data-jdbc
Многие знают Mybatis, знают Jpa, но очень мало знают о новой технологии, родившейся в 2019 году. Это:spring-data-jdbc
. Название общее, но содержание определенно актуально.
Обратите внимание, что речь идет оdata-jdbc
, вместо обычногоjdbc
. у него есть что-то вродеjpa
Некоторые функции , такие как возможность вывода sql на основе имен методов, базовый CRUD и т. д., также позволяют писать собственный sql.
Самое главное, что это очень освежает и не нужно полагаться на hibernte или jpa.
Спустя долгое время он вышел и использовал его, это было потрясающе. Их взаимосвязь можно увидеть на рисунке ниже.
Вы можете видеть, что spring-data-jdbc совпадает с spring-data-jpa и принадлежит к серии spring-data. Давайте применим это на практике и посмотрим лучшие практики.
1. Подготовка конфигурации
После создания проекта Springboot вам необходимо добавить зависимость spring-data-jdbc.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
Для удобства демонстрации здесь я использую базу данных h2. Вы можете настроить сторону веб-конфигурации, чтобы открыть ее в springboot.
h2:
console:
enable: true
path: /h2-console
settings:
trace: true
web-allow-others: true
После запуска вы можете получить доступ к консоли h2 по следующему адресу.
Вы можете видеть, что есть таблица с именем goods_basic. Как он был создан? Давайте сначала посмотрим на нашу конфигурацию источника данных.
spring:
datasource:
driver-class-name: org.h2.Driver
url: jdbc:h2:mem:test;MODE=MYSQL;CASE_INSENSITIVE_IDENTIFIERS=TRUE;
schema: classpath:sql/h2/schema.sql
#data: classpath:sql/h2/data.sql
Среди них файл sql, указанный в spring.datasource.schema, будет автоматически выполняться при запуске проекта, что, конечно же, такжеAutoConfigure
завершить. Давайте посмотрим на наш оператор создания таблицы.
CREATE TABLE `goods_basic` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`code` varchar(255) NOT NULL DEFAULT '' COMMENT '编码,不可重复;',
`barcode` varchar(255) NOT NULL COMMENT '69开头的13位标准码',
`short_name` varchar(255) NOT NULL COMMENT '商品名称',
`photos` json DEFAULT NULL COMMENT '商品图片',
`properties` json NOT NULL COMMENT '商品属性,或者规格',
`unit` varchar(8) NOT NULL COMMENT '单位;最多8个字节',
`state` tinyint NOT NULL DEFAULT '1',
`created` datetime NOT NULL COMMENT '创建时间',
`modified` datetime NOT NULL COMMENT '更新时间',
`version` bigint NOT NULL DEFAULT '0' COMMENT '乐观锁版本号',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_account_role` (`code`,`barcode`) USING BTREE
) ;
Вы можете видеть, что это совершенно синтаксис mysql. Указав в h2MODE=MYSQL
атрибут, вы можете переключить h2 на синтаксис mysql. Хотя h2 всегда кажется немного менее интересным в реальной работе проекта, нужно сказать, что это хороший инструмент для тестирования.
На этом наши приготовления завершены.Вы можете видеть, что это обычная конфигурация источника данных, которая очень проста.
2. Как включить spring-data-jdbc?
Поскольку мы представили стартовый пакет jar ранее, это означает, что некоторая конфигурация выполняется кем-то в фоновом режиме. Давайте посмотрим, как просто создать Дао (Репозиторий).
Правильно, нам просто нужно унаследоватьPagingAndSortingRepository
илиCrudRepository
, можно, и так же, как jpa.
org.springframework.data.repository.PagingAndSortingRepository
org.springframework.data.repository.CrudRepository
Глядя на приведенный выше путь, он не имеет ничего общего с jpa и jdbc, которые являются силой уровня абстракции данных spring.
Взгляните на это дао, которое я определил ниже, на самом деле оно представляет четыре распространенных способа письма.
/**
* Copyright (c) 2020. All Rights Reserved.
* @author yuanluoji
* @date 2020/10/16
*/
public interface GoodsBasicRepository extends PagingAndSortingRepository<GoodsBasic, Integer>,
Complex<GoodsBasic> {
List<GoodsBasic> findByCode(String code);
@Query("select * from goods_basic where code=:code")
List<GoodsBasic> findByCode2(String code);
}
2.1 CRUD по умолчанию
Когда вы наследуете интерфейс CrudRepository, у вас уже есть возможности CRUD по умолчанию.Вы можете вызывать save, findAll и другие методы для прямого чтения и записи сущностей без какого-либо сопоставления.
Это проще и удобнее, чем MyBatis, потому что MyBatis вам не нужен MyBatisPlus, чтобы получить ту же функциональность.
Когда вы наследуете интерфейс PagingAndSortingRepository, помимо CRUD, у него есть еще и функция пейджинга.
2.2 Прямой запрос на основе имени метода
В течение некоторого времени, используя jpa, вы можете напрямую писать имя метода в соответствии с правилами и выполнять функцию запроса без написания SQL. Теперь это также доступно в jdbc.
в кодеfindByCode
метод, смыслcode
, чтобы запросить текущий объект. Этот процесс будет переведен на:
select * from goods_basic where code = :code
Нам больше не нужен sql. Ниже приведена базовая таблица сопоставления. Это все стандартный sql, и это можно сделать в имени метода.
2.3 Использование аннотации запроса
@Query("select * from goods_basic where code=:code")
List<GoodsBasic> findByCode2(String code);
Если условий много, имя метода станет очень длинным. Когда вызывается сервисный уровень, вы будете продолжать кричать!
Вам может понадобиться использовать аннотацию Query для завершения таких сложных операторов запроса. Методы, написанные в интерфейсе, в это время потеряют смысл семантического выражения. Вы можете использовать любое имя метода, просто напишите свой sql в аннотации.
2.4 Гибкая настройка
Но для приложений, которые хотят гибко управлять поведением SQL, вышеуказанных методов недостаточно.
Например, по наличию или отсутствию входных условий сделать какие-то логические суждения. Сделайте какой-нибудь динамический sql, например mybatis, или используйте StringBuilder, чтобы соединить какой-нибудь sql.
Обратите внимание, что наш базовый Dao наследует интерфейс с именемComplex
. Spring-data-jdbc соглашается с тем, что реализация этого интерфейса должна быть размещена в ComplexImpl, иначе будет сообщено об ошибке. Так что, опять же, это магия конвенции.
Мы определяем тестовый метод, который ожидает получить список через входящий код.
public interface Complex<T> {
List<T> test(String code);
}
Для поддержки этого пользовательского запроса я создал базовый класс. В него вводится класс шаблона jdbc, а также вводится класс шаблона jdbc.JdbcAggregateOperations
.
public abstract class BaseRepository {
/**
* 高度封装的JDBC操作,可直接保存实体
*/
@Getter
@Autowired
private JdbcAggregateOperations operations;
/**
* 普通命名的JDBC查询和操作,可使用 {@link org.springframework.jdbc.core.BeanPropertyRowMapper}
* 完成高级自动装配,可自动完成驼峰和下划线的自动映射
*/
@Getter
@Autowired
private NamedParameterJdbcTemplate template;
}
Взгляните на наш класс реализации.
public class ComplexImpl<T> extends BaseRepository implements Complex<T> {
@Override
public List<T> test(String code) {
StringBuilder sb = new StringBuilder("select * from goods_basic");
Map params = new HashMap();
if (!StringUtils.isEmpty(code)) {
sb.append(" where code=:code");
params.put("code", code);
}
List x = getTemplate().query(sb.toString(), params, new BeanPropertyRowMapper<>(GoodsBasic.class));
return x;
}
}
использоватьBeanPropertyRowMapper
, вы можете избежать громоздкого копирования атрибутов, и код становится очень освежающим.
3. Конфигурация сущности
Часто сущности имеют много общих свойств. Это должно быть извлечено и настроено снаружи. Ниже приведена базовая сущность, которую я определил. Содержит идентификатор, время создания обновления и номер версии оптимистичной блокировки. Аннотация Id здесьorg.springframework.data.annotation.Id
, а не джавакс.
@Data
public abstract class AbstractEntity {
@Id
private Long id;
private Date created;
private Date modified;
@Version
private Long version;
}
Что, если я забуду написать созданные и измененные поля внутри? Должен ли я написать фильтр?
Не нужно беспокоиться, мы можем добавить обратный вызов.
Следующий код является примером автоматического добавления времени обновления. Очень полезно.
@Configuration
public class DataJdbcConfiguration extends AbstractJdbcConfiguration {
@Bean
public BeforeSaveCallback<AbstractEntity> absEntityBeforeSet() {
return (entity, aggregateChange) -> {
entity.setModified(new Date());
return entity;
};
}
}
4. Резюме
spring-data-jdbc — относительно новая технология, и практических статей пока мало. Сяо Кью попробовал четыре способа написать здесь предложение, и он был глубоко тронут этим.
Текущая техническая структура проделала большую работу и реализовала многие функции по соглашению. Позвольте мне высказать свое мнение о том, как написаны эти sql.
1. CRUD-метод
Это очень просто, а также очень удобно мигрировать под разные ORM-фреймворки, если нет другой необходимости, то рекомендуется просто наследовать интерфейсный класс.
2. Запрос по имени метода
Это рекомендуется, когда параметры относительно малы, потому что это очень понятно и также может переключаться между jpa.
3. Используйте запрос
Этот метод рекомендуется для немного более сложного sql. Как и при написании jpa, в jpa включается nativeSQL, и его действие такое же.
4. Гибкая настройка
Этот метод соглашения хорош, он подходит для очень сложных сценариев бизнес-логики.
5.QueryDSL
В качестве общего языка запросов querydsl также можно использовать с данными Spring jdbc. Но для этого нужно генерировать дополнительный код, а у меня есть привычка к чистоте, поэтому я еще не использовал его.
Можно сказать, что с помощью sping-data-jdbc вам не нужно кэшировать ORM, что действительно здорово использовать.
Опять же, полный пример кода для этой статьи можно найти в репозитории github.
https://github.com/yuanluoji/purestart-springboot-data-jdbc
Если это поможет вам, пожалуйста, не забудьте проголосовать за меня. Ваша поддержка является движущей силой моего творчества, и в будущем будет больше высококачественного контента, которым я могу поделиться с вами.
Многие люди притворяются декадентами, и я советую вам не давать себя одурачить. Не отказывайтесь от каждой мысли о желании учиться, потому что это может быть вашим будущим «я», взывающим о помощи. Я Сяо Кью, и я буду прогрессировать вместе с вами. Нетрудно сдаться, но должно быть здорово упорствовать.