前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring Boot 之 Spring Data JPA(一)1、新建工程2、配置数据库3、代码结构4、从数据到逻辑总结

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

作者头像
孙亖
发布2018-06-07 11:53:32
4.4K0
发布2018-06-07 11:53:32
举报
文章被收录于专栏:编程直播室编程直播室

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

1、新建工程

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

Paste_Image.png

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

Paste_Image.png

2、配置数据库

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

代码语言:javascript
复制
# 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.

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

代码语言:javascript
复制
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给出了一个建议:

代码语言:javascript
复制
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的使用。代码如下:

代码语言:javascript
复制
@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,这些功能大部分都为我们实现了,我们只需要扩展一个接口就行,不信看下面的代码:

代码语言:javascript
复制
@Repository
public interface RecordsRepo extends JpaRepository<Records, Long> {
}

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

4.3、业务逻辑的实现

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

代码语言:javascript
复制
@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实现几个用户功能,代码如下:

代码语言:javascript
复制
@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:

代码语言:javascript
复制
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单元测试

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

代码语言:javascript
复制
@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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017.05.07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、新建工程
  • 2、配置数据库
  • 3、代码结构
  • 4、从数据到逻辑
    • 4.1、实体对象Entity
      • 4.2、Repository的实现
        • 4.3、业务逻辑的实现
          • 4.4、检验成果
            • 4.4.1、Web页面操作测试
            • 4.4.2、JUnit单元测试
        • 总结
        相关产品与服务
        数据库
        云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档