8.1 Spring Boot集成Groovy混合Java开发

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 8.1 Spring Boot集成Groovy混合Java开发本章节我们使用SpringBoot集成Groovy混合Java开发一个极简的RestAPI。

8.1 Spring Boot集成Groovy混合Java开发

本章节我们使用SpringBoot集成Groovy混合Java开发一个极简的RestAPI。 数据库使用mysql,ORM层使用mybatis,模板引擎使用freemarker,构建工具使用Gradle。

关于Groovy语言,我们在上一章已经简单介绍了。本章就不再多说。

新建Gradle工程,配置build.gradle依赖

我们得到一个标准的gradle工程,目录如下:

由于我们勾选了Groovy支持,gradle依赖如下:

group 'com.easy.springboot'
version '1.0-SNAPSHOT'

apply plugin: 'groovy'
apply plugin: 'java'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.codehaus.groovy:groovy-all:2.3.11'
    testCompile group: 'junit', name: 'junit', version: '4.11'
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

添加SpringBoot依赖

boot-plugin

apply plugin: 'org.springframework.boot'

freemarker-starter

    compile('org.springframework.boot:spring-boot-starter-web')
    compile('org.springframework.boot:spring-boot-starter-freemarker')

mybatis-spring-boot-starter

compile('org.mybatis.spring.boot:mybatis-spring-boot-starter:1.1.1')

mysql jdbc驱动

compile('mysql:mysql-connector-java:6.0.5')

构建脚本

buildscript {
    ext {
        springBootVersion = '1.5.2.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

我们可以看出,在构建脚本里,dependencies里面依赖了spring-boot-gradle-plugin,其版本是我们使用的SpringBoot的版本。

SpringBoot Gradle 插件是SpringBoot针对 Gradle定制的工具, 可以帮助我们打包(jar,war),运行Spring Boot 应用,进行依赖管理等。

具体实现可以看plugin的源码工程:https://github.com/spring-projects/spring-boot/tree/master/spring-boot-tools

配置数据库DataSource

创建application.yml文件,配置数据库信息:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/bms?serverTimezone=UTC&useSSL=false
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver

写领域模型类

package com.esay.springboot.bms.domain
/**
 * Created by jack on 2017/4/15.
 */
class Book {
    Long id;
    String name;
    String isbn;
    String author;
    String press;
//    Date in_date;
//    Date out_date;
    Date inDate;
    Date outDate;
    String state;
}

我们以前使用mybatis开启数据库字段自动映射驼峰命名规则java属性,是通过下面的xml配置:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
 <settings>
  <setting name="mapUnderscoreToCamelCase" value="true"/>
 </settings>
</configuration>

对应的,我们使用注解的方式

@Configuration
class MybatisConfig {
    @Bean
    @Primary
    MybatisProperties mybatisProperties() {
        MybatisProperties p = new MybatisProperties()
        org.apache.ibatis.session.Configuration config = new org.apache.ibatis.session.Configuration()
        // 开启mybatis开启数据库字段自动映射驼峰命名规则java属性
        config.mapUnderscoreToCamelCase = true
        p.configuration = config

        p

    }
}

其中,@Primary注解的功能:当自动装配Bean时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者,否则将抛出异常。

如果不标记,会报如下错误:

Field properties in org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration required a single bean, but 2 were found:
 - mybatisProperties: defined by method 'mybatisProperties' in class path resource [com/esay/springboot/bms/config/MybatisConfig.class]
 - mybatis-org.mybatis.spring.boot.autoconfigure.MybatisProperties: defined in null


 Action:

 Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

通过这个错误日志,我们可以更直观的看出@Primary注解的功能。

Mapper层代码

package com.esay.springboot.bms.mapper;

import java.util.List;

import com.esay.springboot.bms.domain.Book;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

/**
 * Created by jack on 2017/4/15.
 */
@Mapper
public interface BookMapper {
    @Select("select * from book where state = #{state}")
    List<Book> findByState(@Param("state") String state);

    @Select("select * from book")
    List<Book> findAll();

    @Insert({
        "insert into book",
        "set name = #{b.name},",
        "author = #{b.author},",
        "isbn = #{b.isbn},",
        "inDate = #{b.inDate},",
        "outDate = #{b.outDate},",
        "press = #{b.press},",
        "state = #{b.state}"
    })
    @Options(useGeneratedKeys = true, keyProperty = "id")
        //使用@Options注解的userGeneratedKeys 和keyProperty属性让数据库产生auto_increment(自增长)列的值,然后将生成的值设置到输入参数对象的属性中。
    Book insert(@Param("b") Book book) throws RuntimeException;

}

写控制器Controller层

package com.esay.springboot.bms.controller

import com.alibaba.fastjson.JSON
import com.alibaba.fastjson.serializer.SerializerFeature
import com.esay.springboot.bms.domain.Book
import com.esay.springboot.bms.service.BookService
import groovy.json.JsonOutput
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Controller
import org.springframework.ui.Model
import org.springframework.util.StringUtils
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.ResponseBody

/**
 * Created by jack on 2017/4/15.
 */
@Controller
class BookController {

    @Autowired
    BookService bookService;

    @GetMapping("/book")
    @ResponseBody
    List<Book> findByState(@RequestParam(value = "state", required = false) String state) {
        if (StringUtils.isEmpty(state)) {
            List<Book> all = bookService.findAll()
            println(JSON.toJSONString(all,SerializerFeature.PrettyFormat,SerializerFeature.WriteMapNullValue))
//            println(new JsonOutput().toJson(all))
            bookService.findAll()
        } else {
            bookService.findByState(state)
        }
    }

    @GetMapping("/bookPage")
    String findAll(Model model) {
        List<Book> books = bookService.findAll()
        model.addAttribute("books", books)
        "book/list"
    }


}

写视图View层

<!DOCTYPE html>
<html lang="zh">
<body>
<br>
<div>
<#list books as book>
    <p></p>
    <li>书名: ${book.name}</li>
    <li>作者: ${book.author}</li>
    <li>出版社: ${book.press}</li>
    <li>借出时间: ${book.outDate?string('yyyy/MM/dd HH:mm:ss')}</li>
    <li>还书时间: ${book.inDate?string('yyyy/MM/dd HH:mm:ss')}</li>
    <li>状态: ${book.state}</li>
</#list>
</div>
</body>

</html>

Freemarker日期格式化使用:

    <li>借出时间: ${book.outDate?string('yyyy/MM/dd HH:mm:ss')}</li>
    <li>还书时间: ${book.inDate?string('yyyy/MM/dd HH:mm:ss')}</li>

运行测试

命令行运行

gradle bootRun

启动成功, 浏览器访问:http://localhost:8009/bookPage
你将看到类似如下页面:

访问Rest API接口:http://localhost:8009/book?state=NORMAL
我们可以看到如下输出:

[
  {
    "id": 1,
    "name": "极简SpringBoot教程",
    "isbn": "88888888",
    "author": "陈光剑",
    "press": "电子工业出版社",
    "inDate": 1492299756000,
    "outDate": 1492299756000,
    "state": "NORMAL"
  }
]

小结

本章工程源代码:https://github.com/EasySpringBoot/bms

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
3天前
|
数据采集 Java 数据挖掘
Java IO异常处理:在Web爬虫开发中的实践
Java IO异常处理:在Web爬虫开发中的实践
|
5天前
|
数据采集 存储 前端开发
Java爬虫开发:Jsoup库在图片URL提取中的实战应用
Java爬虫开发:Jsoup库在图片URL提取中的实战应用
|
7天前
|
图形学 iOS开发 Android开发
从Unity开发到移动平台制胜攻略:全面解析iOS与Android应用发布流程,助你轻松掌握跨平台发布技巧,打造爆款手游不是梦——性能优化、广告集成与内购设置全包含
【8月更文挑战第31天】本书详细介绍了如何在Unity中设置项目以适应移动设备,涵盖性能优化、集成广告及内购功能等关键步骤。通过具体示例和代码片段,指导读者完成iOS和Android应用的打包与发布,确保应用顺利上线并获得成功。无论是性能调整还是平台特定的操作,本书均提供了全面的解决方案。
50 0
|
7天前
|
C# Windows 开发者
当WPF遇见OpenGL:一场关于如何在Windows Presentation Foundation中融入高性能跨平台图形处理技术的精彩碰撞——详解集成步骤与实战代码示例
【8月更文挑战第31天】本文详细介绍了如何在Windows Presentation Foundation (WPF) 中集成OpenGL,以实现高性能的跨平台图形处理。通过具体示例代码,展示了使用SharpGL库在WPF应用中创建并渲染OpenGL图形的过程,包括开发环境搭建、OpenGL渲染窗口创建及控件集成等关键步骤,帮助开发者更好地理解和应用OpenGL技术。
34 0
|
7天前
|
开发者 存储 API
Xamarin 云服务集成竟然如此强大,简化后端开发不再是梦,数据存储、用户认证、推送通知全搞定!
【8月更文挑战第31天】Xamarin 是一款强大的跨平台移动应用开发工具,通过与云服务集成,显著简化了后端开发。开发者无需自行搭建服务器,即可利用云服务提供的数据存储、用户认证、推送通知等功能,大幅减少数据库设计、服务器配置及 API 开发的时间成本。借助 Azure Mobile Apps 等云服务,Xamarin 可轻松实现数据存取操作,同时增强应用安全性与用户参与度,使开发者更专注于业务逻辑和用户体验,提升开发效率并降低成本。这种方式在快速发展的移动应用领域极具价值。
31 0
|
7天前
|
数据库 开发者 Java
颠覆传统开发:Hibernate与Spring Boot的集成,让你的开发效率飞跃式提升!
【8月更文挑战第31天】在 Java 开发中,Spring Boot 和 Hibernate 已成为许多开发者的首选技术栈。Spring Boot 简化了配置和部署过程,而 Hibernate 则是一个强大的 ORM 框架,用于管理数据库交互。将两者结合使用,可以极大提升开发效率并构建高性能的现代 Java 应用。本文将通过代码示例展示如何在 Spring Boot 项目中集成 Hibernate,并实现基本的数据库操作,包括添加依赖、配置数据源、创建实体类和仓库接口,以及在服务层和控制器中处理 HTTP 请求。这种组合不仅简化了配置,还提供了一套强大的工具来快速开发现代 Java 应用程序。
16 0
|
7天前
|
前端开发 Java UED
JSF遇上Material Design:一场视觉革命,如何让传统Java Web应用焕发新生?
【8月更文挑战第31天】在当前的Web开发领域,用户体验和界面美观性至关重要。Google推出的Material Design凭借其独特的动画、鲜艳的颜色和简洁的布局广受好评。将其应用于JavaServer Faces(JSF)项目,能显著提升应用的现代感和用户交互体验。本文介绍如何通过PrimeFaces等组件库在JSF应用中实现Material Design风格,包括添加依赖、使用组件及响应式布局等步骤,为用户提供美观且功能丰富的界面。
14 0
|
Java 应用服务中间件
SpringBoot集成使用jsp(超详细)
SpringBoot集成使用jsp(超详细)
SpringBoot集成使用jsp(超详细)
|
18天前
|
SQL 前端开发 NoSQL
SpringBoot+Vue 实现图片验证码功能需求
这篇文章介绍了如何在SpringBoot+Vue项目中实现图片验证码功能,包括后端生成与校验验证码的方法以及前端展示验证码的实现步骤。
SpringBoot+Vue 实现图片验证码功能需求
|
17天前
|
JavaScript
SpringBoot+Vue+ElementUI 实现视频播放 轮播图效果
这篇文章介绍了如何在SpringBoot+Vue+ElementUI项目中使用vue-awesome-swiper插件实现视频播放轮播图效果,包括安装插件、引入项目和使用案例的步骤。
SpringBoot+Vue+ElementUI 实现视频播放 轮播图效果
下一篇
DDNS