您的位置:澳门新葡8455最新网站 > 编程教学 > Spring Boot 之 Spring Data JPA(一)

Spring Boot 之 Spring Data JPA(一)

发布时间:2019-10-05 16:06编辑:编程教学浏览(96)

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

    上一次我们使用Spring Boot开发了一个简单的REST服务应用,那么传统网页应用怎么做呢?渲染HTML是Spring Boot可以完美胜任的,并且提供了多种模板引擎的默认配置支持,所以在模板引擎的支持下,我们可以很快的上手开发动态网站。

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

    Spring Boot提供了默认配置的模板引擎主要有以下几种:

    图片 1Paste_Image.png

    • Thymeleaf
    • FreeMarker
    • Velocity
    • Groovy
    • Mustache

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

    Spring Boot建议使用这些模板引擎,避免使用JSP,但JSP有天然的血缘关系,我们教程也是从最简便的地方入手,所以这里我们使用JSP模版。

    图片 2Paste_Image.png

    接下来我们新建一个工程,Starter Project就是Boot,Legacy Project 就是传统的Spring项目,这里我们选择Starter Project。

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

    图片 3右键新建工程

    # 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  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 settingsspring.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 settingsspring.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  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 settingsspring.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.
    

    由于JSP模版不能放到classpath下,所以这里Packaging选择War。然后其他地方根据项目情况填写。

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

    图片 4工程项目信息

    spring.datasource.url=jdbc:h2:file:d:/h2/data.db;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSEspring.datasource.driverClassName=org.h2.Driverspring.datasource.username=saspring.datasource.password=spring.jpa.database-platform= org.hibernate.dialect.H2Dialectspring.jpa.generate-ddl=truespring.jpa.hibernate.ddl-auto=create-dropspring.jpa.open-in-view=true spring.jpa.show-sql=falsespring.h2.console.enabled=false
    

    点击Finish结束,接下来就自动编译了,由于默认使用的是maven管理依赖,不出意外伟大的墙这个时候就跳出来了,我一般是用代理解决这个问题。

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

    编辑C:Usersusername.m2settings.xml文件:

    com +- example +- myproject +- Application.java | +- domain | +- Customer.java | +- CustomerRepository.java | +- service | +- CustomerService.java | +- web +- CustomerController.java
    
    <settings> <proxies> <proxy> <id>myProxy</id> <active>true</active> <protocol>http</protocol> <host>127.0.0.1</host> <port>1080</port> <!-- <username>XXXXX</username> <password>XXXXX</password> <nonProxyHosts>*.XXX.com|XXX.org</nonProxyHosts>--> </proxy> </proxies> </settings> 
    

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

    当IDE里面没有错误的时候,说明更新好了。

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

    和RESTController 一样,通过@Controller注解我们编写一个Controller类:

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

    @Controller@SpringBootApplicationpublic class SpringBootWebApplication { public static void main(String[] args) { SpringApplication.run(SpringBootWebApplication.class, args); }}
    
    @Entitypublic 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 { 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; } }
    

    科学的写法应该是针对业务领域,单独写一个Controller类,这里我为了简化代码把SpringBootWebApplication些微Controller类。

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

    我们现在application.propeties中准备点数据,当然这个数据你可以从数据库取也行:

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

    application.message=Hello JSP Template
    
    @Repositorypublic interface RecordsRepo extends JpaRepository<Records, Long> {}
    

    接下来我们针对请求路径"/"写个映射方法,并从配置文件中读取数据,返回到客户端:

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

    @Controller@SpringBootApplicationpublic class SpringBootWebApplication { @Value("${application.message:Hello World}") private String message; @Value("${application.message2:Hello World2}") private String message2; public static void main(String[] args) { SpringApplication.run(SpringBootWebApplication.class, args); } @RequestMapping public String welcome(Map<String, Object> model) { model.put("time", new Date; model.put("message", this.message); model.put("message2", this.message2); return "welcome"; }}
    

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

    在Controller类中,我们通过@Value注解获取配置文件中的application.message值。在映射方法中通过Map来传递Model,最后通过“welcome”视图来渲染。由于application.message2没有值,所以会使用默认值Hello World2。

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

    请求和模型都已经准备好了,我们接下来配置JSP模版,修改application.properties如下:

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

    spring.mvc.view.prefix=WEB-INF/jsp/spring.mvc.view.suffix=.jsp
    

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

    第一个表示模版存放位置,第二个是模版文件后缀名。

    4.4.1、Web页面操作测试

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

    @SpringBootApplication@RestControllerpublic class SpringBootJpaApplication { @Autowired RecordsService recSevc; public static void main(String[] args) { SpringApplication.run(SpringBootJpaApplication.class, args); } @RequestMapping 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; return rec; } @RequestMapping public Records updateRecords() { Records rec = recSevc.get; rec.setTitle("modified"); recSevc.save; return rec; } @RequestMapping public String deleteRecords() { Records rec = recSevc.get; recSevc.delete; return "deleted"; }}
    

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

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

    我们先启动服务:

    图片 5运行程序在项目名称上,右键,Run As,Java Application 或者 Spring Boot App。然后,我们在浏览器中输入] 试试看。同时,我们可以在浏览器中输入 看看数据库中数据的变化是否与预期一致:图片 6H2控制台

    由于前面返回welcome,所以通过welcome视图来渲染,我们在WEB-INF/jsp/目录下新建welcome.jsp文件来显示数据:

    4.4.2、JUnit单元测试

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

    @RunWith(SpringRunner.class)@SpringBootTestpublic 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; Long id = rec.getId(); assertThat(rec.getId.isNotNull(); rec.setTitle("modified"); rec = recSevc.save; assertThat(rec.getTitle.isEqualTo("modified"); assertThat(rec.getId.isEqualTo; List<Records> recs = recSevc.list(); int size = recs.size(); assertThat.isGreaterThan; rec = recSevc.get; assertThat(rec.getId.isEqualTo; recSevc.delete; rec = recSevc.get; assertThat.isNull(); }}
    

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

    图片 7启动执行测试用列

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

    图片 8JUnit窗口

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

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

    转载请注明:

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

    序Ionic 2 安装环境安装创建Ionic项目测试运行项目Ionic 2 项目结构./src/index.html./src/./src/app/app.htmlIonic 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.修改主页的模版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 Cloud3 生成证书和创建一个安全概要4 使用Ionic Package 命令总结Ionic 2中使用百度地图和Geolocation新建项目加入百度地图SDK库加载地图获取定位坐标转换地图定位激活百度地图导航总结在Ionic 2 Native中使用Cordova插件Ionic 和 Cordova 的误解使用Ionic Native使用没有包含在Ionic Native中的插件Ionic 2 中添加图表1. 照例新建一个项目2. 安装Chart.js3. 在模版中使用总结Ionic 2 中的创建一个闪视卡片组件1. 创建一个新的应用作为例子2. 什么是组件?3. 创建组件模版4. 创建组件类5. 创建 CSS 动画6. 添加组件到模版总结Ionic 2 中创建一个照片倾斜浏览组件1. 创建一个新的应用2. 实现照片倾斜浏览组件3. 使用照片倾斜浏览组件总结Ionic 2 中实现一个简单的进度条理解 自定义组件中的 Input 和 output1.创建一个新的应用2.创建组件修改src/components/progress-bar/progress-bar.ts如下:3.使用这个组件总结使用VS Code在Chrome中调试Ionic 2优化你的Ionic2应用打开Angular产品模式修改 为 使用 --prod 参数编译总结Ionic 2 开发遇到的问题及处理集Console.log 不输出编译Android报错:compileArmv7DebugJavaWithJavac一些更新命令错误:Error: listen EADDRINUSE 0.0.0.0:53703

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Spring Boot Web MVC Demo</title></head><body> <c:url value="/resources/text.txt" var="url" /> <spring:url value="/resources/text.txt" htmlEscape="true" var="springUrl" /> Spring URL: ${springUrl} at ${time} <br> JSTL URL: ${url} <br> Message: ${message} <br> Message2: ${message2}</body></html>
    

    如果你熟悉html和jsp的话,上面代码不难理解,model数据通过${}来获取展示,例如:message是${message}。最后,我们打开浏览器看看效果:

    图片 9网页输出效果

    转载请注明:

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

    序Ionic 2 安装环境安装创建Ionic项目测试运行项目Ionic 2 项目结构./src/index.html./src/./src/app/app.htmlIonic 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.修改主页的模版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 Cloud3 生成证书和创建一个安全概要4 使用Ionic Package 命令总结Ionic 2中使用百度地图和Geolocation新建项目加入百度地图SDK库加载地图获取定位坐标转换地图定位激活百度地图导航总结在Ionic 2 Native中使用Cordova插件Ionic 和 Cordova 的误解使用Ionic Native使用没有包含在Ionic Native中的插件Ionic 2 中添加图表1. 照例新建一个项目2. 安装Chart.js3. 在模版中使用总结Ionic 2 中的创建一个闪视卡片组件1. 创建一个新的应用作为例子2. 什么是组件?3. 创建组件模版4. 创建组件类5. 创建 CSS 动画6. 添加组件到模版总结Ionic 2 中创建一个照片倾斜浏览组件1. 创建一个新的应用2. 实现照片倾斜浏览组件3. 使用照片倾斜浏览组件总结Ionic 2 中实现一个简单的进度条理解 自定义组件中的 Input 和 output1.创建一个新的应用2.创建组件修改src/components/progress-bar/progress-bar.ts如下:3.使用这个组件总结使用VS Code在Chrome中调试Ionic 2优化你的Ionic2应用打开Angular产品模式修改 为 使用 --prod 参数编译总结Ionic 2 开发遇到的问题及处理集Console.log 不输出编译Android报错:compileArmv7DebugJavaWithJavac一些更新命令错误:Error: listen EADDRINUSE 0.0.0.0:53703

    本文由澳门新葡8455最新网站发布于编程教学,转载请注明出处:Spring Boot 之 Spring Data JPA(一)

    关键词: