Spring Boot 之 Spring Data JPA(一)1、新建工程2、配置数据库3、代码结构4、从数据到逻辑总结

今天,我们用一个最简单的例子上手Spring Data JPA的开发。

1、新建工程

首先,我们使用STS建一个工程:

Paste_Image.png

这里我们示例使用H2数据库,主要是因为简单,使用其他数据库也是一样的,如果你用Web作为用户界面的话把Web选上,我们这里使用JUnit测试,所以不选也行。

Paste_Image.png

2、配置数据库

Spring Boot的配置内容参考官方文档:Appendix A. Common application properties 其中,我们关心的是:

# JPA (JpaBaseConfiguration, HibernateJpaAutoConfiguration)
# DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
spring.datasource.continue-on-error=false # Do not stop if an error occurs while initializing the database.
spring.datasource.data= # Data (DML) script resource references.
spring.datasource.data-username= # User of the database to execute DML scripts (if different).
spring.datasource.data-password= # Password of the database to execute DML scripts (if different).
spring.datasource.dbcp2.*= # Commons DBCP2 specific settings
spring.datasource.driver-class-name= # Fully qualified name of the JDBC driver. Auto-detected based on the URL by default.
spring.datasource.generate-unique-name=false # Generate a random datasource name.
spring.datasource.hikari.*= # Hikari specific settings
spring.datasource.initialize=true # Populate the database using 'data.sql'.
spring.datasource.jmx-enabled=false # Enable JMX support (if provided by the underlying pool).
spring.datasource.jndi-name= # JNDI location of the datasource. Class, url, username & password are ignored when set.
spring.datasource.name=testdb # Name of the datasource.
spring.datasource.password= # Login password of the database.
spring.datasource.platform=all # Platform to use in the schema resource (schema-${platform}.sql).
spring.datasource.schema= # Schema (DDL) script resource references.
spring.datasource.schema-username= # User of the database to execute DDL scripts (if different).
spring.datasource.schema-password= # Password of the database to execute DDL scripts (if different).
spring.datasource.separator=; # Statement separator in SQL initialization scripts.
spring.datasource.sql-script-encoding= # SQL scripts encoding.
spring.datasource.tomcat.*= # Tomcat datasource specific settings
spring.datasource.type= # Fully qualified name of the connection pool implementation to use. By default, it is auto-detected from the classpath.
spring.datasource.url= # JDBC url of the database.
spring.datasource.username= # Login user of the database.
spring.datasource.xa.data-source-class-name= # XA datasource fully qualified name.
spring.datasource.xa.properties= # Properties to pass to the XA data source.

# H2 Web Console (H2ConsoleProperties)
spring.h2.console.enabled=false # Enable the console.
spring.h2.console.path=/h2-console # Path at which the console will be available.
spring.h2.console.settings.trace=false # Enable trace output.
spring.h2.console.settings.web-allow-others=false # Enable remote access.

# JOOQ (JooqAutoConfiguration)
spring.jooq.sql-dialect= # SQLDialect JOOQ used when communicating with the configured datasource. For instance `POSTGRES`

# JPA (JpaBaseConfiguration, HibernateJpaAutoConfiguration)
spring.data.jpa.repositories.enabled=true # Enable JPA repositories.
spring.jpa.database= # Target database to operate on, auto-detected by default. Can be alternatively set using the "databasePlatform" property.
spring.jpa.database-platform= # Name of the target database to operate on, auto-detected by default. Can be alternatively set using the "Database" enum.
spring.jpa.generate-ddl=false # Initialize the schema on startup.
spring.jpa.hibernate.ddl-auto= # DDL mode. This is actually a shortcut for the "hibernate.hbm2ddl.auto" property. Default to "create-drop" when using an embedded database, "none" otherwise.
spring.jpa.hibernate.naming.implicit-strategy= # Hibernate 5 implicit naming strategy fully qualified name.
spring.jpa.hibernate.naming.physical-strategy= # Hibernate 5 physical naming strategy fully qualified name.
spring.jpa.hibernate.naming.strategy= # Hibernate 4 naming strategy fully qualified name. Not supported with Hibernate 5.
spring.jpa.hibernate.use-new-id-generator-mappings= # Use Hibernate's newer IdentifierGenerator for AUTO, TABLE and SEQUENCE.
spring.jpa.open-in-view=true # Register OpenEntityManagerInViewInterceptor. Binds a JPA EntityManager to the thread for the entire processing of the request.
spring.jpa.properties.*= # Additional native properties to set on the JPA provider.
spring.jpa.show-sql=false # Enable logging of SQL statements.

其实不止这些,但我们不会完全学完所有知识才能应用,以下的配置就可以让我们访问数据库了:

spring.datasource.url=jdbc:h2:file:d:/h2/data.db;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform= org.hibernate.dialect.H2Dialect
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.open-in-view=true 
spring.jpa.show-sql=false
spring.h2.console.enabled=false

3、代码结构

理论上我们可以任意的组织代码,Spring Boot给出了一个建议:

com
 +- example
     +- myproject
         +- Application.java
         |
         +- domain
         |   +- Customer.java
         |   +- CustomerRepository.java
         |
         +- service
         |   +- CustomerService.java
         |
         +- web
             +- CustomerController.java

从上图可以看出:domain放置实体和Repository,service放置业务逻辑,web放置Controller。我更习惯于另为一种组织,将domain拆分为entity和repo,将实体和Repository分别安放。Repository可以看作是DAO/DAL数据访问层或者数据访问对象。

4、从数据到逻辑

用上面的代码结构我们可以看出,一个Spring业务流程包括:数据结构(entity)、数据访问(repo/dal)、业务逻辑(service)和用户交互界面(web)。我们接下来按此顺序一一讲解

4.1、实体对象Entity

实体对象很简单,是和数据库表的映射,但框架已经把数据库操作封装了,且Java强调的面向对象,我认为实体直接看作是可以持久化的数据对象就好了,和数据库的关系只要心里明白就行。我们先实现一个记录数据的描述,这个记录没有什么实际意义,仅为演示Spring Data JPA的使用。代码如下:

@Entity
public class Records {
    @Id
    @GeneratedValue
    private Long id;
    @Column
    private String title;
    @Column
    private String description;
    @Column
    private Date updateDate;
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public Date getUpdateDate() {
        return updateDate;
    }
    public void setUpdateDate(Date updateDate) {
        this.updateDate = updateDate;
    }   
}

在实体类上使用@Entity注解说明这是一个实体类,@Id注解说明这是主键,@Column说明是普通字段,@GenerateValue主键生成策略默认native,H2是自增的。 这就是整个数据结构,包含了主键、标题、描述和更新时间。

4.2、Repository的实现

数据结构有了,接下来我们我操作这些数据,说白了就是增删查改、分页等等。要感谢Spring,这些功能大部分都为我们实现了,我们只需要扩展一个接口就行,不信看下面的代码:

@Repository
public interface RecordsRepo extends JpaRepository<Records, Long> {
}

看见没,不超过三行代码。@Repository说明这个接口是一个repository,也就是DAO/DAL。接口JpaRepository是一个很全的功能接口,我们不用实现它,Spring会自动为我们适配实现。

4.3、业务逻辑的实现

当我们可以操作数据时,就可以通过处理数据来实现业务逻辑了,代码如下:

@Service
public class RecordsService {
    
    @Autowired
    RecordsRepo recRepo;
    
    public Records save(Records rec) {
        return recRepo.save(rec);
    }
    
    public List<Records> list() {
        return recRepo.findAll();
    }
    
    public void delete(Records rec) {
        recRepo.delete(rec);
    }
    
    public Records get(Long id) {
        return recRepo.findOne(id);
    }
}

同样,这里也有一个@Service注解说明这是一个服务Bean,通过@Autowired注解将RecordsRepo注入到服务中,这样就能操作Records数据了。这时候我们就可以根据我们的需求和业务来编写我买的业务方法,因为这里只是一个demo,所以我们就简单的调用了repository方法。

4.4、检验成果

测试通常是通过对比输出值和期望值来进行检验的。简单的,我们只是通过用户界面来进行判断,例如:

4.4.1、Web页面操作测试

我们,通过Controller实现几个用户功能,代码如下:

@SpringBootApplication
@RestController
public class SpringBootJpaApplication {

    @Autowired
    RecordsService recSevc;
    
    public static void main(String[] args) {
        SpringApplication.run(SpringBootJpaApplication.class, args);
    }
    
    @RequestMapping("new")
    public Records newRecords() {
        Records rec = new Records();
        rec.setTitle("title" + Math.random());
        rec.setDescription("desc" + Math.random());
        rec.setUpdateDate(Calendar.getInstance().getTime());
        rec = recSevc.save(rec);
        return rec;
    }
    
    @RequestMapping("update")
    public Records updateRecords() {
        Records rec = recSevc.get(1l);
        rec.setTitle("modified");
        recSevc.save(rec);
        return rec;
    }
    
    @RequestMapping("delete")
    public String deleteRecords() {
        Records rec = recSevc.get(1l);
        recSevc.delete(rec);
        return "deleted";
    }
}

这里,注入了RecordsService,并通过用户请求实现了增改删功能。我们可以浏览器返回值查看返回值。另外,我们可以在H2控制台中查看数据库的变化,什么是H2控制台,如果你用过phpMyAdmin或其他数据库管理工具就明白了,这里不深入讨论。我们先配置一下application.properties:

spring.h2.console.enabled=true
spring.h2.console.path=/h2 #默认是/h2_console

我们先启动服务:

运行程序

在项目名称上,右键,Run As,Java Application 或者 Spring Boot App。 然后,我们在浏览器中输入http://host:port/[new|update|delete] 试试看。 同时,我们可以在浏览器中输入http://host:port/h2 看看数据库中数据的变化是否与预期一致:

H2控制台

4.4.2、JUnit单元测试

另外一种更专业的测试方法是我们可以写单元测试,这样我买的测试就可以不断迭代,而且有相应的工具帮我们进行测试分析,代码如下:

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootJpaApplicationTests {

    @Autowired
    RecordsService recSevc;
    
    @Test
    public void contextLoads() {
    }
    
    @Test
    public void testJpaRecords() {
        Records rec = new Records();
        rec.setTitle("title" + Math.random());
        rec.setDescription("desc" + Math.random());
        rec.setUpdateDate(Calendar.getInstance().getTime());
        rec = recSevc.save(rec);
        Long id = rec.getId();
        assertThat(rec.getId()).isNotNull();
        rec.setTitle("modified");
        rec = recSevc.save(rec);
        assertThat(rec.getTitle()).isEqualTo("modified");
        assertThat(rec.getId()).isEqualTo(id);
        
        List<Records> recs = recSevc.list();
        int size = recs.size();
        assertThat(size).isGreaterThan(0);
        
        rec = recSevc.get(id);
        assertThat(rec.getId()).isEqualTo(id);
        
        recSevc.delete(rec);
        rec = recSevc.get(id);
        assertThat(rec).isNull();
    }
}

同样是注解,这个@Test说明我们的执行的测试方法是testJpaRecords,不过这次我们运行的是JUnit Test,如下图所示:

启动执行测试用列

运行结果一闪而过,结果如何呢?请看:

JUnit窗口

IDE里面的JUnit 视图窗口,运行了两个测试方法,全部通过。这里仅是示例,实际测试应更复杂,需分析测试覆盖率等。

总结

回过头来再复习一遍,很简单,设计好你要操作的数据结构,编写操作数据的接口,在业务逻辑中操作数据,将数据处理结果返回给用户。

============================================================== Ionic 2 实例开发


Ionic 2 安装 环境安装 创建Ionic项目 测试运行项目 Ionic 2 项目结构 ./src/index.html ./src/ ./src/app/app.html Ionic 2 应用剖析 0 开始之前 1 创建一个新的Ionic 2 应用 2 目录结构 Root Components 模版 App Module 总结 Ionic 2 添加页面 创建页面 创建附加页面 使用 Ionic 2 开发Todo应用 0 开始之前 1 创建新的Ionic 2工程 2. 设置主页(Home page) 3 持久化数据保存 4 总结 Ionic 2 实现列表滑动删除按钮 1.创建Ionic2应用 2.准备列表数据 3.修改主页(HOME)的模版 4.创建方法删除数据 5.添加一个编辑按钮 总结 Angular 2 新概念和语法 Angular 2 & Ionic 2 概念 Angular 2 语法 Ionic 2 导航简明指南 入栈出栈(Pushing and Popping) 什么时候使用导航栈?什么时候使用rootPage? Ionic 2 基本导航功能 总结 Ionic 2 中使用管道处理数据 1.生成一个新应用 2.创建一个管道 3.使用管道 总结 Ionic 2 中使用HTTP与远程服务器交互数据 开始之前 我们需要一个列表 3.获取远程数据 4.推送数据到服务器 总结 Ionic 2 中的样式与主题 Ionic 2主题简介 创建Ionic 2应用主题的方式 没有苹果电脑打包iOS平台的 Ionic 2程序 开始之前 1 创建一个Ionic 2的应用 2 建立Ionic Cloud 3 生成证书和创建一个安全概要 4 使用Ionic Package 命令 总结 Ionic 2中使用百度地图和Geolocation 新建项目 加入百度地图SDK库 加载地图 获取定位 坐标转换 地图定位 激活百度地图导航 总结 在Ionic 2 Native中使用Cordova插件 Ionic 和 Cordova 的误解 使用Ionic Native 使用没有包含在Ionic Native中的插件 Ionic 2 中添加图表 1. 照例新建一个项目 2. 安装Chart.js 3. 在模版中使用 总结 Ionic 2 中的创建一个闪视卡片组件 1. 创建一个新的应用作为例子 2. 什么是组件? 3. 创建组件模版 4. 创建组件类 5. 创建 CSS 动画 6. 添加组件到模版 总结 Ionic 2 中创建一个照片倾斜浏览组件 1. 创建一个新的应用 2. 实现照片倾斜浏览组件 3. 使用照片倾斜浏览组件 总结 Ionic 2 中实现一个简单的进度条 理解 自定义组件中的 Input 和 output 1.创建一个新的应用 2.创建组件 修改src/components/progress-bar/progress-bar.ts如下: 3.使用这个组件 总结 使用VS Code在Chrome中调试Ionic 2 优化你的Ionic2应用 打开Angular产品模式 修改(click) 为 (tap) 使用 --prod 参数编译 总结 Ionic 2 开发遇到的问题及处理集 Console.log 不输出 编译Android报错:compileArmv7DebugJavaWithJavac 一些更新命令 错误:Error: listen EADDRINUSE 0.0.0.0:53703

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏JavaQ

深入Spring Boot (十):整合Mybatis框架详解

Spring Boot整合Mybatis支持XML配置和全注解两种方式,本篇将详细解说这两种方式的Mybatis整合,主要包含以下5部分内容: 数据源配置; 数...

4859
来自专栏一个会写诗的程序员的博客

《Kotin 极简教程》第11章 使用Kotlin 集成 SpringBoot开发Web服务端第11章 使用Kotlin集成SpringBoot开发Web服务端《Kotlin极简教程》正式上架:

我们在前面第2章 “ 2.3 Web RESTFul HelloWorld ” 一节中,已经介绍了使用 Kotlin 结合 SpringBoot 开发一个RES...

841
来自专栏Java技术分享

SSM三大框架整合详细总结(Spring+SpringMVC+MyBatis)

使用 SSM ( Spring 、 SpringMVC 和 Mybatis )已经很久了,项目在技术上已经没有什么难点了,基于现有的技术就可以实现想要的功能,当...

1.3K12
来自专栏JadePeng的技术博客

jenkins X实践系列(2) —— 基于jx的DevOps实践

jx是云原生CICD,devops的一个最佳实践之一,目前在快速的发展成熟中。最近调研了JX,这里为第2篇,使用已经安装好的jx来实践CICD,旨在让大家了解基...

6342
来自专栏码神联盟

重磅来袭,抱歉,来晚啦

来一波 、基本概念 1.1、spring Spring 是一个开源框架, Spring 是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Ro...

35911
来自专栏码神联盟

框架 | SpringBoot项目发布部署外部tomcat服务器步骤

1.7K2
来自专栏Hadoop实操

如何使用Sentry管理Hive外部表权限

使用如下命令在HDFS的根目录下创建Hive外部表的数据目录/extwarehouse

1.8K8
来自专栏别先生

struts2+hibernate+spring注解版框架搭建以及简单测试(方便脑补)

为了之后学习的日子里加深对框架的理解和使用,这里将搭建步奏简单写一下,目的主要是方便以后自己回来脑补; 1:File--->New--->Other---...

1928
来自专栏pangguoming

简单的Hibernate入门简介

其实Hibernate本身是个独立的框架,它不需要任何web server或application server的支持。然而,大多数的Hibernate入门介绍...

3679
来自专栏Java3y

Druid数据库连接池就是这么简单

前言 本章节主要讲解Druid数据库连接池,为什么要学Druid数据库连接池呢?? 我的知识储备数据库连接池有两种->C3P0,DBCP,可是现在看起来并不够用...

50811

扫码关注云+社区

领取腾讯云代金券