本文的完整示例代码,见github仓库。小q只在文中介绍最关键的代码块。

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中配置开启它的web配置端。

  h2:console:enable: truepath: /h2-consolesettings:trace: trueweb-allow-others: true

启动之后,就可以通过下面的地址访问h2的console。

可以看到里面有一张叫做goods_basic的表。它是怎么创建进去的呢?先来看一下我们的datasource配置。

spring:datasource:driver-class-name: org.h2.Driverurl: jdbc:h2:mem:test;MODE=MYSQL;CASE_INSENSITIVE_IDENTIFIERS=TRUE;schema: classpath:sql/h2/schema.sql#data: classpath:sql/h2/data.sql

其中, spring.datasource.schema所指定的sql文件,将会在项目启动的时候,自动执行,这当然也是有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语法。通过在h2里面指定MODE=MYSQL属性,就可以把h2切换到mysql的语法。虽然h2在项目实际运行中感觉总是差那么一点意思,但对于测试来说,不得不说是个好工具。
到此为止,我们的准备工作就完成了,可以看到就是普通的datasource配置,简单的很。

2.如何启用spring-data-jdbc?

由于我们在前面引入的是starter的jar包,那就代表一些配置某人就在后台完成了。下面来看一下,创建一个Dao(Repository),是有多简单。
没错,我们只需要继承PagingAndSortingRepository或者CrudRepository,就可以了,和jpa的一样。

org.springframework.data.repository.PagingAndSortingRepository
org.springframework.data.repository.CrudRepository

看一下上面的路径,和jpa和jdbc是没什么关系的,这就是spring-data抽象层的强大之处。

看一下我下面定义的这个dao,它实际上表现了常见的四种书写方式。

/*** 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注解

@Query("select * from goods_basic where code=:code")List<GoodsBasic> findByCode2(String code);

如果条件很多,这个方法名将会变得很长很长。在service层调用的时候你会一直喊卧槽!

这种复杂查询语句,你可能需要使用Query注解来完成。写在接口里的方法,此时将失去语意表达的意义。你可以使用任意的方法名,只需要把你的sql写在注解里就可以了。

2.4 灵活的自定义
但对于想要灵活的控制sql行为的应用来说,上面这几种方式就不行了。
比如,根据输入条件的有无,做一些逻辑判断。做一些类似mybatis的动态sql,或者使用StringBuilder来拼接一些sql。
注意我们的基础Dao,继承了一个接口,叫做Complex。spring-data-jdbc约定,这个接口的实现,放在ComplexImpl中,否则就会报错。所以,这又是一个约定所实现的魔法。
我们定定义了一个test方法,期望通过传入的code获取一个列表

public interface Complex<T> {List<T> test(String code);
}

为了支持这种自定义查询,我做了一个基类。里面注入了一个jdbc的模版类,还注入了一个JdbcAggregateOperations

public abstract class BaseRepository {/*** 高度封装的JDBC操作,可直接保存实体*/@Getter@Autowiredprivate JdbcAggregateOperations operations;/*** 普通命名的JDBC查询和操作,可使用 {@link org.springframework.jdbc.core.BeanPropertyRowMapper}* 完成高级自动装配,可自动完成驼峰和下划线的自动映射*/@Getter@Autowiredprivate NamedParameterJdbcTemplate template;
}

来看一下我们的实现类。

public class ComplexImpl<T> extends BaseRepository implements Complex<T> {@Overridepublic 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、创建爱你更新时间以及一个乐观锁版本号。这里的Id注解是org.springframework.data.annotation.Id,而不是javax的。

@Data
public abstract class AbstractEntity {@Idprivate Long id;private Date created;private Date modified;@Versionprivate Long version;
}

里面的created和modified字段,如果忘了写怎么办?难道要写一个过滤器么?

不需要那么麻烦,我们可以追加一个callback。

下面的代码,就是一个自动添加更新时间的例子。非常的好用。

@Configuration
public class DataJdbcConfiguration extends AbstractJdbcConfiguration {@Beanpublic BeforeSaveCallback<AbstractEntity> absEntityBeforeSet() {return (entity, aggregateChange) -> {entity.setModified(new Date());return entity;};}
}

4. 小结

spring-data-jdbc是一个比较新的技术,现在的实践文章还是很少。小Q在这里尝试了一个语句的四种写法,对此还是深有感慨的。

现在的技术框架,背后做了很多工作,靠约定实现了很多功能。我来发表一下对于这些sql写作方式的见解。

1.CRUD方式
这个很简单,在不同的ORM框架下迁移也很方便,如果没有其他必要,建议只需要继承一个接口类就可以了。2.根据方法名查询
这个在参数比较少的时候,比较推荐,因为很清晰,也能在jpa之间进行切换。3.使用Query
对于稍微复杂的sql,建议使用这种方式。和jpa的写法一样,jpa中开启nativeSQL,和它的效果是一样的。4.灵活自定义
这个约定方式不错,适合非常复杂的业务逻辑场景。5.QueryDSL
querydsl作为一门通用的查询语言,用在Spring data jdbc上,也是可以的。但它要生成一些额外的代码,个人比较有洁癖,暂未使用。
可以说,有了sping-data-jdbc,又不需要ORM去给你做什么缓存,用起来真是爽呆了。

作者:小姐姐味道
链接:https://juejin.im/post/6887110115959242759
来源:掘金

boot jpa mysql postman spring_听说过spring-data-jdbc么?来个最佳实践相关推荐

  1. boot jpa mysql postman spring_springboot使用spring-data-jpa操作MySQL数据库

    我们在上一篇搭建了一个简单的springboot应用,这一篇将介绍使用spring-data-jpa操作数据库. 新建一个MySQL数据库,这里数据库名为springboot,建立user_info数 ...

  2. JPA的单向一对多关联(oneToMany)实现示例(基于Spring Boot + JPA +MySQL,表自动维护)

    本篇的环境 本篇基于Spring Boot + JPA+ MySQL. 表自动维护: 配置 ddl-auto: update,使用 Hibernate 根据类自动维护表. 本篇的示例 这里有两个类: ...

  3. Spring Boot + JPA +MySQL 数据操作及示例环境搭建(自动建表)

    JPA 是Java官方提供的数据持久的统一API , 是一个接口标准,并没有具体实现. JPA的实现常见的有: Hibernate TopLink (Eclipse Link) Spring Boot ...

  4. spring data jdbc 基本使用

    文章目录 配置 使用 创建表 创建实体类 创建操作接口Repository 读写数据 总结 官方文档: https://docs.spring.io/spring-data/jdbc/docs/1.0 ...

  5. 【转】Spring Data JDBC - Reference Documentation

    Spring Data JDBC - Reference Documentation Jens Schauder, Jay Bryant, Mark Paluch, Bastian Wilhelm V ...

  6. Spring Data JDBC入门使用Demo

    Spring Data JDBC入门使用Demo Spring Data JDBC is a simple, limited, opinionated ORM. Spring Data JDBC特点: ...

  7. Spring Data JDBC 详解

    目录 一.JPA背景 二.Spring Boot 整合Spring data JDBC 1. 配置数据源 2. 配置Druid的admin后台 3. Spring-data-jdbc常用接口查询策略 ...

  8. Spring Data JDBC通用DAO实现–迄今为止最轻量的ORM

    我很高兴宣布Spring Data JDBC存储库项目的第一个版本. 这个开放源代码库的目的是为基于Spring框架中 JdbcTemplate关系数据库提供通用,轻量且易于使用的DAO实现,与项目的 ...

  9. Spring Data JDBC、引用和聚合

    之前的博客文章中,我.描述了如何设置和使用 Spring Data JDBC.我还描述了使 Spring Data 原标题:Spring认证|Spring Data JDBC.引用和聚合 JDBC 比 ...

最新文章

  1. Android 模糊效果
  2. 深度解析:服务器架构和技术变革
  3. 2.Strings and Console Output(字符串与输出)
  4. mysql实现decode_Oracle中的DECODE()函数,MySQL中怎么实现DECODE()函数
  5. 微信小程序之 3d轮播(swiper来实现)
  6. 从Client应用场景介绍IdentityServer4(二)
  7. lg android平台驱动程序,lg g3刷KDZ教程-KDZ线刷工具及USB驱动下载
  8. javascript获取css行内样式
  9. html中一级标题和二级标题,如何设置一级二级三级标题
  10. PHP获取上周一,获取指定日期的上周日期,上周一
  11. 台式计算机 蓝牙,台式电脑蓝牙在哪里打开(手把手教你打开台式电脑蓝牙)...
  12. 解决layui form组件使用botton按钮提交页面自动刷新问题
  13. U盘装系统:魔方U盘启动制作
  14. 【NLP相关】开源中文NLP大模型及项目集合
  15. Gunicorn配置详解
  16. Python--提高pip的下载速度
  17. 2022-12-09 Ubuntu16.4中访问另一台Ubuntu samba共享出来的目录方法
  18. VSCode语法高亮 禁用括号花俏的颜色
  19. 使用C#为SAP2000开发第一个插件
  20. C语言程序——变量的赋值

热门文章

  1. 关于在linux操作系统中中不能删除创建创建的用户的操作
  2. js生成元素的事件不执行问题
  3. 聊聊这两年我用到的面试套路和收获
  4. Android攻城狮ListView
  5. Android为TV端助力 转载:Java 泛型
  6. BZOJ3808 : Neerc2012 Labyrinth of the Minotaur
  7. 学C/C++的同学们,有福了!
  8. 46岁谷歌创始人佩奇、布林双双卸任,皮查伊接任母公司CEO
  9. 希腊字母常用指代意义及其中文读音
  10. 我的世界正版moba服务器,hello_world