Java-Python-Django社区Spring-BootSpring Boot

【Demo】Gradle + Kotlin + Spring B

2018-07-23  本文已影响0人  苍云横渡

原文地址:https://www.cloudcrossing.xyz/post/48/

最近在学习 Spring Boot 和 Kotlin,今天花了一点时间写了个小demo当作练手

以及感谢导师一直以来的帮助:)

1 框架介绍

这个Demo也可以说是一个轻量级服务器应用,其架构使用 Gradle + Kotlin + Spring Boot + Mybatis + MySQL。其中:

Gradle

Gradle 是一个基于 Apache Ant 和 Apache Maven 概念的项目自动化构建开源工具。它使用一种基于 Groovy 的特定领域语言 (DSL) 来声明项目设置,抛弃了基于 XML 的各种繁琐配置。支持maven, Ivy仓库,支持传递性依赖管理

Kotlin

Kotlin 是一个用于现代多平台应用的静态编程语言,由 JetBrains 开发。Kotlin 可以编译成 Java 字节码,也可以编译成 JavaScript,方便在没有 JVM 的设备上运行。Kotlin 已正式成为 Android 官方支持开发语言

Spring Boot

Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Spring Boot 致力于在蓬勃发展的快速应用开发领域 (rapid application development) 成为领导者。其主要特点有:

Mybatis

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集

MySQL

MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件

RESTful

一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。即 URL定位资源,用HTTP动词(GET,POST,DELETE,DETC)描述操作——@Ivony


2 项目结构及开发环境

Demo使用的是 IntelliJ IDEA 开发运行,该项目的文件结构大致如下:

├── build.gradle
├── gradle
├── gradlew.bat
├── settings.gradle
└── src
    ├── main
         ├── java
         ├── kotlin
         │   └── com
         │       └── cloud
         │           ├── MyApplication.kt
         │           ├── controller
         │           │   ├── UserController.kt
         │           │   └── TestController.kt
         │           ├── dao
         │           │   └── UserRepository.kt
         │           └── model
         │               └── User.kt
         ├── resources
         │   ├── application.yml
         └── webapp
             └── index.jsp

项目无需运行在 Tomcat,因为Spring Boot 自带了一个 Tomcat。main 函数入口在 MyApplication.kt 中,只需要双击该文件,然后点击 main 函数 左边的绿色右箭头,点击 Run 既可以运行项目


3 使用 IntelliJ IDEA 创建项目

3.1 创建 Kotlin 的 web 项目

第一步

第二步

第三步

最后 Finish 即可

3.2 配置 build.gradle

增加 Spring Boot、Mybatis、MySQL、JSP、pagehelper 的依赖

其中,pagehelper 是 MyBatis 分页插件,支持任何复杂的单表、多表分页

buildscript {
    ext {
        kotlin_version = '1.1.2'
        springBootVersion = '2.0.1.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        // Kotlin
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        // Spring-boot
        classpath "org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion"
    }
}

plugins {
    id 'java'
    id 'org.jetbrains.kotlin.jvm' version '1.2.51'
    id 'war'
}

group 'com.cloud'
version '1.0-SNAPSHOT'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
    testCompile group: 'junit', name: 'junit', version: '4.11'
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

compileKotlin {
    kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
    kotlinOptions.jvmTarget = "1.8"
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
    testCompile group: 'junit', name: 'junit', version: '4.12'
    // Kotlin
    compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
    compile("org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version")
    compile("org.jetbrains.kotlin:kotlin-reflect:$kotlin_version")
    // Spring-boot
    compile("org.springframework.boot:spring-boot-starter-web:$springBootVersion")
    // Mybatis
    compile 'org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.2'
    // 支持jsp
    compile 'org.apache.tomcat.embed:tomcat-embed-jasper:9.0.7'
    // jsp的jstl表达式
    compile 'javax.servlet:jstl:1.2'
    // mysql
    compile('mysql:mysql-connector-java:5.1.13')
    // pagehelper
    compile group: 'com.github.pagehelper', name: 'pagehelper', version: '4.1.0'
}

3.3 创建数据库表并配置 application.yml

首先在本地创建一个 MySQL 数据库,然后新建一个 user 表,列属性为 id int,name varchar(20)

然后配置 application.yml

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/KotlinDemo
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver

3.4 创建 User 类

package com.cloud.model

class User {
    var id: Int = 0
    var name:String? = null
}

3.5 创建应用入口 MyApplication

package com.cloud

import com.github.pagehelper.PageHelper
import org.mybatis.spring.annotation.MapperScan
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.context.annotation.Bean
import java.util.*

@MapperScan("com.cloud.dao")
@SpringBootApplication
open class MyApplication()

fun main(args: Array<String>) {
    SpringApplication.run(MyApplication::class.java, *args)

    @Bean
    fun pageHelper() : PageHelper {
        System.out.println("=========MyBatisConfiguration.pageHelper()");
        val pageHelper = PageHelper();
        val p = Properties();
        p.setProperty("offsetAsPageNum", "true");
        p.setProperty("rowBoundsWithCount", "true");
        p.setProperty("reasonable", "true");
        pageHelper.setProperties(p);
        return pageHelper;
    }
}

3.6 创建 UserController 类

我习惯是先写控制类,然后再写 Dao 接口

PS:由于逻辑比较简单,所以省略了 Service 层,也将 SQL语句 直接以注解的形式绑定在 Dao 层

package com.cloud.controller

import com.cloud.dao.UserDao
import org.apache.ibatis.annotations.Param
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.bind.annotation.*

@RestController
class UserController {

    @Autowired
    lateinit var userDao: UserDao

    @GetMapping("/all")
    fun getAllUser() : Any {
        val users = userDao.getAllUser()
        return users
    }

    @PostMapping("/user")
    fun createUser(@Param("id") id : Int, @Param("name")name : String) : Any {
        userDao.createUser(id, name)
        return getAllUser()
    }

    @DeleteMapping("user")
    fun deleteUserById(@Param("id") id : Int) : Any {
        userDao.deleteUserById(id)
        return getAllUser()
    }

    @PutMapping("/user")
    fun updateUserById(@Param("id") id : Int, @Param("name")name : String) : Any {
        userDao.updateUserById(id, name)
        return getAllUser()
    }

    @GetMapping("/user")
    fun getUserById(id : Int) : Any {
        val user = userDao.getUserById(id)
        return user
    }

    @GetMapping("/list")
    fun getUserList(@Param("currentPage") currentPage : Int, @Param("pageSize") pageSize : Int) : Any {
        val currentPageNew = (currentPage - 1) * pageSize
        val users = userDao.getUserList(currentPageNew, pageSize)
        return users
    }

}

@RestController 注解相当于 @Controller与@ResponseBody这两个注解的作用

Spring4.3 中引进了 @GetMapping、@PostMapping、@PutMapping、@DeleteMapping 等,来帮助简化常用的 HTTP 方法的映射,并更好地表达被注解方法的语义

在 Mybatis 用注解来简化 xml 配置的时候, @Param 注解的作用是给参数命名,参数命名后就能根据名字得到参数值,正确的将参数传入 sql 语句中

这里,我们在创建一个测试控制类 TestController 类,用来演示将数据返回到 jsp 页面上

package com.cloud.controller

import com.cloud.dao.UserDao
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.RequestMapping
import javax.servlet.http.HttpServletRequest

@Controller
class TestController {

    @Autowired
    lateinit var userDao: UserDao

    @RequestMapping("/test")
    fun index(request: HttpServletRequest): String {
        val users = userDao.getAllUser()
        request.setAttribute("users",users)
        return "/index.jsp"
    }
}

3.7 创建 UserDao 类

package com.cloud.dao

import com.cloud.model.User
import org.apache.ibatis.annotations.*
import org.springframework.stereotype.Repository

@Repository
interface UserDao {

    @Select("select * from user")
    fun getAllUser(): List<User>

    @Select("select * from user where id = #{id}")
    fun getUserById(@Param("id") id : Int?): User

    @Insert("insert into user(id, name) values(#{id}, #{name})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    fun createUser(@Param("id") id : Int, @Param("name") name : String)

    @Delete("delete from user where id = #{id}")
    fun deleteUserById(@Param("id") id: Int)

    @Update("update user set name=#{name} where id=#{id}")
    fun updateUserById(@Param("id") id : Int, @Param("name") name : String)

    @Select("select * from user limit #{currentPage}, #{pageSize}")
    fun getUserList(@Param("currentPage") currentPage : Int, @Param("pageSize") pageSize : Int): List<User>

}

在最后一个分页查询中 getUserList() 中,我们可以看到其查询语句为:select * from user limit #{currentPage}, #{pageSize}

但是注意,这里的 currentPage 不是 url 中传入的 currentPage,其是经过处理的,我们可以在控制类中看到,实际上这里的 currentPage = (currentPage - 1) * pageSize

3.8 测试接口

创建index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<html>
<head>
  <title>Demo</title>
</head>
<body>
<table border="2">
  <tr>
    <th>ID</th>
    <th>名称</th>
  </tr>
  <c:forEach items="${users}" var="item" varStatus="status">
    <tr>
      <td>${item.id}</td>
      <td>${item.name}</td>
    </tr>
  </c:forEach>
</table>
</body>
</html>

在测试接口中,我们用到一个软件叫做 Postman。这是一款功能强大的网页调试与发送网页HTTP请求,它可以发送几乎所有类型的HTTP请求。界面及其使用如下:

测试 TestController 类

GET http://localhost:8080/test

测试 UserController 类

GET http://localhost:8080/all

GET http://localhost:8080/list?currentPage=2&pageSize=3

其他的方法自行测试,默认增加、删除、修改之后跳转到 getAllUser()


代码上传到了 https://github.com/laiyuancai/KotlinSpringBootDemo

上一篇 下一篇

猜你喜欢

热点阅读