《Spring Boot極簡教程》第8_章: Spring Boot集成Groovy混合Java開發(fā)

第8_章: Spring Boot集成Groovy混合Java開發(fā)

本章我們使用SpringBoot集成Groovy混合Java開發(fā)一個極簡的RestAPI。 數(shù)據(jù)庫使用mysql,ORM層使用mybatis,模板引擎使用freemarker,構(gòu)建工具使用Gradle。

關(guān)于Groovy語言,我們在上一章已經(jīng)簡單介紹了。本章就不再多說。

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

我們得到一個標(biāo)準(zhǔn)的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驅(qū)動

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

構(gòu)建腳本

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

我們可以看出,在構(gòu)建腳本里,dependencies里面依賴了spring-boot-gradle-plugin,其版本是我們使用的SpringBoot的版本。

SpringBoot Gradle 插件是SpringBoot針對 Gradle定制的工具, 可以幫助我們打包(jar,war),運(yùn)行Spring Boot 應(yīng)用,進(jìn)行依賴管理等。

具體實現(xiàn)可以看plugin的源碼工程:https://github.com/spring-projects/spring-boot/tree/master/spring-boot-tools

配置數(shù)據(jù)庫DataSource

創(chuàng)建application.yml文件,配置數(shù)據(jù)庫信息:

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

寫領(lǐng)域模型類

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開啟數(shù)據(jù)庫字段自動映射駝峰命名規(guī)則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>

對應(yīng)的,我們使用注解的方式

@Configuration
class MybatisConfig {
    @Bean
    @Primary
    MybatisProperties mybatisProperties() {
        MybatisProperties p = new MybatisProperties()
        org.apache.ibatis.session.Configuration config = new org.apache.ibatis.session.Configuration()
        // 開啟mybatis開啟數(shù)據(jù)庫字段自動映射駝峰命名規(guī)則java屬性
        config.mapUnderscoreToCamelCase = true
        p.configuration = config

        p

    }
}

其中,@Primary注解的功能:當(dāng)自動裝配Bean時當(dāng)出現(xiàn)多個Bean候選者時,被注解為@Primary的Bean將作為首選者,否則將拋出異常。

如果不標(biāo)記,會報如下錯誤:

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屬性讓數(shù)據(jù)庫產(chǎn)生auto_increment(自增長)列的值,然后將生成的值設(shè)置到輸入?yún)?shù)對象的屬性中。
    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>狀態(tài): ${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>

運(yùn)行測試

命令行運(yùn)行

gradle bootRun

啟動成功, 瀏覽器訪問:http://localhost:8009/bookPage
你將看到類似如下頁面:

訪問Rest API接口:http://localhost:8009/book?state=NORMAL
我們可以看到如下輸出:

[
  {
    "id": 1,
    "name": "極簡SpringBoot教程",
    "isbn": "88888888",
    "author": "陳光劍",
    "press": "電子工業(yè)出版社",
    "inDate": 1492299756000,
    "outDate": 1492299756000,
    "state": "NORMAL"
  }
]

小結(jié)

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容