Code Monkey home page Code Monkey logo

gradlekotlinspringbootmybatissqlitedemo's Introduction

《Gradle+Kotlin结合Spring Boot+Mybatis+SQLite快速开发轻量级服务器应用》

标题想了很多,感觉很多的标题都合适,比如:

《Kotlin + Spring Boot会不会成为一种新的选择?》

《写给Android工程师的服务端开发架构》

《打造轻量级的Java服务器框架,无需部署Tomcat,也无需部署Mysql》

前言

我一直以来都是使用Maven+Java+Tomcat+Springmvc+Mybatis+Mysql来搭建小型服务器应用,这套框架很简单,也方便易用,最近我在想会不会有更好的解决方案,加上最近在学习了Kotlin语言开发Android,所以就有了这篇文章。

框架介绍

该架构使用Gradle+Kotlin+Spring Boot+Mybatis+SQLite来代替Maven+Java+Tomcat+Springmvc+Mybatis+Mysql,其中Gradle代替Maven,Kotlin代替Java,Spring Boot 代替 Tomcat,同时Spring Boot也带了Springmvc,SQLite代替Mysql。

Kotlin

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

Gradle

Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建工具。它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,抛弃了基于XML的各种繁琐配置。基于Groovy,build脚本使用Groovy编写。

Spring Boot

Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。通过这种方式,Spring Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。

  1. 创建独立的Spring应用程序
  2. 嵌入的Tomcat,无需部署WAR文件
  3. 简化Maven配置
  4. 自动配置Spring
  5. 提供生产就绪型功能,如指标,健康检查和外部配置
  6. 绝对没有代码生成和对XML没有要求配置
Mybatis

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

SQLite

SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统。不像常见的客户-服务器范例,SQLite引擎不是个程序与之通信的独立进程。整个数据库(定义、表、索引和数据本身)都在宿主主机上存储在一个单一的文件中。

  1. ACID事务
  2. 零配置 – 无需安装和管理配置
  3. 储存在单一磁盘文件中的一个完整的数据库
  4. 数据库文件可以在不同字节顺序的机器间自由的共享
  5. 支持数据库大小至2TB
  6. 足够小, 大致13万行C代码, 4.43M
  7. 比一些流行的数据库在大部分普通数据库操作要快
  8. 简单, 轻松的API

项目结构及运用环境

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


├── build.gradle
├── gradle
├── mydatabase.sqlite
├── settings.gradle
└── src
    ├── main
    │   ├── java
    │   ├── kotlin
    │   │   └── com
    │   │       └── thejoyrun
    │   │           └── webtest
    │   │               ├── MyApplication.kt
    │   │               ├── controller
    │   │               │   ├── TestApiController.kt
    │   │               │   └── TestController.kt
    │   │               ├── dao
    │   │               │   └── UserRepository.kt
    │   │               └── model
    │   │                   └── User.kt
    │   ├── resources
    │   │   ├── application.properties
    │   │   └── example.db
    │   └── webapp
    │       └── index.jsp
    └── test
        ├── java
        ├── kotlin
        └── resources

项目无需运行在Tomcat,项目的MyApplication.kt有main函数入口,只需要右击MyApplication.kt,选择run 'com.thejoyrun.webtest.MyApplicationKt'运行即可。 image

使用IntelliJ IDEA创建项目过程

创建Kotlin的web项目

流程1 image 流程2 image 流程3 image

配置build.gradle文件

增加Spring Boot、Mybatis、SQLite、JSP的依赖

group 'com.thejoyrun'
version '1.0-SNAPSHOT'
buildscript {
    ext.kotlin_version = '1.1.2'
    ext.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"
    }
}
apply plugin: 'java'
apply plugin: 'kotlin'
apply plugin: 'war'
sourceCompatibility = 1.8
repositories {
    mavenCentral()
}
dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.11'
    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")
    // SQLite
    compile 'org.xerial:sqlite-jdbc:3.21.0.1'
    // 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'
}
创建SQLite数据库文件

项目使用SQLite,所以需要一个SQLite文件,可以下载官方的SQLiteManager来创建一个文件,并创建数据表。或者使用以下代码直接生成一个数据库文件和创建数据表。

fun main(args: Array<String>) {
    //连接SQLite的JDBC
    Class.forName("org.sqlite.JDBC")
    //建立一个数据库名example.db的连接,如果不存在就在当前目录下创建之
    val conn = DriverManager.getConnection("jdbc:sqlite:src/main/resources/example.db")
    val stat = conn.createStatement()
    // //创建一个表,包含id、name两个字段
    stat.executeUpdate("create table user(id int,name varchar(20));")
    // 插入一行数据
    stat.executeUpdate("insert into user values(1,'Wiki1');")
    stat.executeUpdate("insert into user values(2,'Wiki2');")
    //查询所有数据
    val rs = stat.executeQuery("select * from user;")
    while (rs.next()) { //将查询到的数据打印出来
        print("id = " + rs.getString("id") + " ")
        println("name = " + rs.getString("name"))
    }
    rs.close()
    conn.close()
}
配置数据源

创建/src/main/resources/application.properties文件

spring.datasource.url=jdbc:sqlite::resource:example.db
#spring.datasource.url=jdbc:sqlite:/Users/Wiki/Documents/mydatabase.sqlite
spring.datasource.username=
spring.datasource.password=
spring.datasource.driver-class-name=org.sqlite.JDBC
创建User类
class User {
    var id: Int = 0
    var name:String? = null
}
创建dao类
@Repository
interface UserRepository {

    @Select("SELECT * FROM User WHERE ID = #{id}")
    fun findById(@Param("id") integer: Int?): User

    @Select("SELECT * FROM User")
    fun findAll(): List<User>

    @Insert("INSERT INTO User(id,name) VALUES(#{id}, #{name})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    fun insert(user: User)
}
创建controller类

http://localhost:8080/hello

@RestController
class TestApiController {
    @Autowired
    internal var userRepository: UserRepository? = null

    @GetMapping("/hello")
    fun hello(): Any {
        val users = userRepository!!.findAll()
        return users
    }
}

http://localhost:8080/test

@Controller
class TestController {
    @Autowired
    lateinit var userRepository: UserRepository

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

创建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>Title</title>
</head>
<body>
<table border="2">
    <tr>
        <th>名称</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>
创建应用入口 MyApplication

@MapperScan 用来配置扫描该包名以下的dao

@MapperScan("com.thejoyrun.webtest.dao")
@SpringBootApplication
open class MyApplication {}

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

右击该类运行项目,浏览器访问:

http://localhost:8080/hello

http://localhost:8080/test

Demo代码

https://github.com/taoweiji/GradleKotlinSpringBootMybatisSQLiteDemo

gradlekotlinspringbootmybatissqlitedemo's People

Contributors

taoweiji avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

gradlekotlinspringbootmybatissqlitedemo's Issues

无法访问 index.jsp

访问http://localhost:8080/test返回

Whitelabel Error Page

This application has no explicit mapping for /error, so you are seeing this as a fallback.
Sat Sep 26 16:37:43 CST 2020
There was an unexpected error (type=Internal Server Error, status=500).
Error resolving template "/index.jsp", template might not exist or might not be accessible by any of the configured Template Resolvers
org.thymeleaf.exceptions.TemplateInputException: Error resolving template "/index.jsp", template might not exist or might not be accessible by any of the configured Template Resolvers
	at org.thymeleaf.engine.TemplateManager.resolveTemplate(TemplateManager.java:870)
	at org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:607)
	at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098)
	at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1072)
	at org.thymeleaf.spring5.view.ThymeleafView.renderFragment(ThymeleafView.java:354)
	at org.thymeleaf.spring5.view.ThymeleafView.render(ThymeleafView.java:187)
	at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1325)
	at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1069)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1008)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.