8.1 Spring Boot集成Groovy混合Java开发

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 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
相关文章
|
8天前
|
人工智能 前端开发 Java
基于开源框架Spring AI Alibaba快速构建Java应用
本文旨在帮助开发者快速掌握并应用 Spring AI Alibaba,提升基于 Java 的大模型应用开发效率和安全性。
基于开源框架Spring AI Alibaba快速构建Java应用
|
16天前
|
前端开发 Java 数据库连接
Spring 框架:Java 开发者的春天
Spring 框架是一个功能强大的开源框架,主要用于简化 Java 企业级应用的开发,由被称为“Spring 之父”的 Rod Johnson 于 2002 年提出并创立,并由Pivotal团队维护。
37 1
Spring 框架:Java 开发者的春天
|
16天前
|
Java 数据库连接 开发者
Spring 框架:Java 开发者的春天
【10月更文挑战第27天】Spring 框架由 Rod Johnson 在 2002 年创建,旨在解决 Java 企业级开发中的复杂性问题。它通过控制反转(IOC)和面向切面的编程(AOP)等核心机制,提供了轻量级的容器和丰富的功能,支持 Web 开发、数据访问等领域,显著提高了开发效率和应用的可维护性。Spring 拥有强大的社区支持和丰富的生态系统,是 Java 开发不可或缺的工具。
|
16天前
|
JSON Java Maven
实现Java Spring Boot FCM推送教程
本指南介绍了如何在Spring Boot项目中集成Firebase云消息服务(FCM),包括创建项目、添加依赖、配置服务账户密钥、编写推送服务类以及发送消息等步骤,帮助开发者快速实现推送通知功能。
42 2
|
16天前
|
JSON Java 开发工具
Java服务端集成Google FCM推送的注意事项和实际经验
本文分享了作者在公司APP海外发布过程中,选择Google FCM进行消息推送的集成经验。文章详细解析了Java集成FCM推送的多种实现方式,包括HTTP请求和SDK集成,并指出了通知栏消息和透传消息的区别与应用场景。同时,作者还探讨了Firebase项目的创建、配置和服务端集成的注意事项,帮助读者解决文档混乱和选择困难的问题。
24 1
|
18天前
|
XML Java 数据格式
提升效率!Spring Boot 开发中的常见失误轻松规避
本文深入探讨了在 Spring Boot 开发中常见的失误,包括不当使用注解、不良异常处理、低效日志记录等,提供了有效的规避策略,帮助开发者提升代码质量和系统性能,构建更健壮、高效的应用程序。
|
20天前
|
存储 人工智能 Java
将 Spring AI 与 LLM 结合使用以生成 Java 测试
AIDocumentLibraryChat 项目通过 GitHub URL 为指定的 Java 类生成测试代码,支持 granite-code 和 deepseek-coder-v2 模型。项目包括控制器、服务和配置,能处理源代码解析、依赖加载及测试代码生成,旨在评估 LLM 对开发测试的支持能力。
31 1
|
22天前
|
Java BI 调度
Java Spring的定时任务的配置和使用
遵循上述步骤,你就可以在Spring应用中轻松地配置和使用定时任务,满足各种定时处理需求。
108 1
|
2天前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
7 0
|
4月前
|
监控 druid Java
spring boot 集成配置阿里 Druid监控配置
spring boot 集成配置阿里 Druid监控配置
278 6