scala 整合 springboot
新建spingboot项目
pom.xml
xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.lihaozhe</groupId>
<artifactId>scala-boot</artifactId>
<version>1.0</version>
<name>scala-boot</name>
<description>scala-boot</description>
<properties>
<jdk.version>21</jdk.version>
<!-- 公共配置 -->
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<maven.compiler.compilerVersion>21</maven.compiler.compilerVersion>
<maven.compiler.encoding>utf-8</maven.compiler.encoding>
<project.build.sourceEncoding>utf-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.test.failure.ignore>true</maven.test.failure.ignore>
<maven.test.skip>true</maven.test.skip>
<commons-dbutils.version>1.8.1</commons-dbutils.version>
<commons-io.version>2.14.0</commons-io.version>
<commons-lang3.version>3.13.0</commons-lang3.version>
<druid.version>1.2.20</druid.version>
<fastjson.version>2.0.41</fastjson.version>
<gson.version>2.10.1</gson.version>
<hutool.version>5.8.22</hutool.version>
<jackson.version>2.15.3</jackson.version>
<junit.version>5.10.0</junit.version>
<lombok.version>1.18.30</lombok.version>
<mysql.version>8.2.0</mysql.version>
<scala.version>2.13.12</scala.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.20</version>
</dependency>
<dependency>
<groupId>org.scala-tools.testing</groupId>
<artifactId>specs_2.10</artifactId>
<version>1.6.9</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.scalatest</groupId>
<artifactId>scalatest_2.13</artifactId>
<version>3.2.15</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<!-- 作用域 -->
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-engine -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!--jackson-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>
<!--java 小工具-->
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>java-testdata-generator</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.3.1.Final</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<!-- 该插件用于将Scala代码编译成class文件 -->
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>4.8.1</version>
<configuration>
<scalaCompatVersion>${scala.version}</scalaCompatVersion>
<scalaVersion>${scala.version}</scalaVersion>
</configuration>
<executions>
<execution>
<id>scala-compile-first</id>
<phase>process-resources</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
<execution>
<id>compile-scala</id>
<phase>compile</phase>
<goals>
<goal>add-source</goal>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile-scala</id>
<phase>test-compile</phase>
<goals>
<goal>add-source</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.5.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
创建数据库恢复数据
sql
create database knowledge;
use knowledge;
编写 pojo 类
scala
package cn.lihaozhe.pojo
import jakarta.persistence.{Column, Entity, GeneratedValue, GenerationType, Id, Table}
import scala.beans.BeanProperty
/**
* @author 李昊哲
* @version 1.0
*/
@Entity
@Table(name = "dujitang")
class Dujitang {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
@BeanProperty
var id: Long = _
@Column(name = "text")
@BeanProperty
var text: String = _
override def toString: String = s"$id\t$text"
}
scala
package cn.lihaozhe.pojo
import jakarta.persistence.{Column, Entity, GeneratedValue, GenerationType, Id, Table}
import scala.beans.BeanProperty
/**
* @author 李昊哲
* @version 1.0
*/
@Entity
@Table(name = "cy")
class Cy {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
@BeanProperty
var id: Long = _
@Column(name = "name")
@BeanProperty
var name: String = _
@Column(name = "spell")
@BeanProperty
var spell: String = _
@Column(name = "content")
@BeanProperty
var content: String = _
@Column(name = "derivation")
@BeanProperty
var derivation: String = _
@Column(name = "samples")
@BeanProperty
var samples: String = _
}
编写持久层
scala
package cn.lihaozhe.repository
import cn.lihaozhe.pojo.Dujitang
import org.springframework.data.jpa.repository.{JpaRepository, JpaSpecificationExecutor}
/**
* @author 李昊哲
* @version 1.0
*/
trait DujitangRepository extends JpaRepository[Dujitang, Long] with JpaSpecificationExecutor[Dujitang] {
}
scala
package cn.lihaozhe.repository
import cn.lihaozhe.pojo.Cy
import org.springframework.data.jpa.repository.{JpaRepository, JpaSpecificationExecutor}
/**
* @author 李昊哲
* @version 1.0
*/
trait CyRepository extends JpaRepository[Cy, Long] with JpaSpecificationExecutor[Cy] {
}
编写业务层
scala
package cn.lihaozhe.service
import cn.lihaozhe.pojo.Dujitang
/**
* @author 李昊哲
* @version 1.0
*/
trait DujitangService {
/**
* 随机生成一条鸡汤
*
* @return 鸡汤文案
*/
def random(): Dujitang
}
scala
package cn.lihaozhe.service
import cn.lihaozhe.pojo.Cy
import org.springframework.data.domain.Page
/**
* @author 李昊哲
* @version 1.0
*/
trait CyService {
/**
* 分页查找 成语
*
* @param word 成语关键字
* @param pageNum 查询页面号
* @param pageSize 每页记录数
* @return 成语列表
*/
def page(word: String, pageNum: Int, pageSize: Int): Page[Cy]
}
scala
package cn.lihaozhe.service.impl
import cn.lihaozhe.pojo.Dujitang
import cn.lihaozhe.repository.DujitangRepository
import cn.lihaozhe.service.DujitangService
import org.springframework.stereotype.Service
import scala.util.Random
/**
* @author 李昊哲
* @version 1.0
*/
@Service
class DujitangServiceImpl(dujitangRepository: DujitangRepository) extends DujitangService {
/**
* 随机生成一条鸡汤
*
* @return 鸡汤文案
*/
override def random(): Dujitang = {
val dujitangList = dujitangRepository.findAll()
val index = new Random().nextInt(dujitangList.size())
dujitangList.get(index)
}
}
scala
package cn.lihaozhe.service.impl
import cn.lihaozhe.pojo.Cy
import cn.lihaozhe.repository.CyRepository
import cn.lihaozhe.service.CyService
import jakarta.persistence.criteria.{CriteriaBuilder, CriteriaQuery, Predicate, Root}
import org.apache.commons.lang3.StringUtils
import org.springframework.data.domain.{Page, PageRequest, Sort}
import org.springframework.data.jpa.domain.Specification
import org.springframework.stereotype.Service
/**
* @author 李昊哲
* @version 1.0
*/
@Service
class CyServiceImpl(cyRepository: CyRepository) extends CyService {
/**
* 分页查找 成语
*
* @param word 成语关键字
* @param pageNum 查询页面号
* @param pageSize 每页记录数
* @return 成语列表
*/
override def page(word: String, pageNum: Int, pageSize: Int): Page[Cy] = {
if (StringUtils.isBlank(word)) {
cyRepository.findAll(PageRequest.of(pageNum - 1, pageSize, Sort.by(Sort.Direction.ASC, "id")))
} else {
val sb = new StringBuilder
sb.append("%")
sb.append(word)
sb.append("%")
cyRepository.findAll(new Specification[Cy] {
override def toPredicate(root: Root[Cy], query: CriteriaQuery[_], cb: CriteriaBuilder): Predicate = cb.like(root.get("name").as(classOf[String]), sb.toString())
}, PageRequest.of(pageNum - 1, pageSize, Sort.by(Sort.Direction.ASC, "id")))
}
}
}
编写数据接口
scala
package cn.lihaozhe.controller
import cn.lihaozhe.pojo.Dujitang
import cn.lihaozhe.service.DujitangService
import org.springframework.web.bind.annotation.{GetMapping, RequestMapping, RestController}
/**
* @author 李昊哲
* @version 1.0
*/
@RestController
@RequestMapping(value = Array("/dujitang"))
class DujitangController(dujitangService: DujitangService) {
@GetMapping(Array("/random"))
def random(): Dujitang = dujitangService.random()
}
scala
package cn.lihaozhe.controller
import cn.lihaozhe.service.CyService
import org.springframework.web.bind.annotation.{GetMapping, RequestMapping, RestController}
/**
* @author 李昊哲
* @version 1.0
*/
@RestController
@RequestMapping(Array("/cy"))
class CyController(cyService: CyService) {
@GetMapping(Array("/page"))
def page(word: String, pageNum: Int = 1, pageSize: Int = 5) = cyService.page(word, pageNum, pageSize)
}
application.yml
yaml
# 服务器配置
server:
port: 6633
servlet:
context-path: /
session:
timeout: 30m
cookie:
max-age: 3600
encoding:
charset: UTF-8
force: true
# spring配置
spring:
application:
name: scala-boot
mvc:
format:
date: yyyy-MM-dd
date-time: yyyy-MM-dd HH:mm:ss
path match:
matching-strategy: ant_path_matcher
servlet:
multipart:
enabled: true
max-file-size: 50MB
max-request-size: 200MB
jackson:
serialization:
FAIL_ON_EMPTY_BEANS: false
# json 序列化排除值为 null 的属性
default-property-inclusion: non_null
# 配置 Date 类的时间格式,如果不涉及可以不加
date-format: yyyy-MM-dd HH:mm:ss
# 配置 Date 类的时区,如果不涉及可以不加
time-zone: GMT+8
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql:///knowledge?useUnicode=true&characterEncoding=UTF8&useSSL=false&useServerPrepStmts=false&rewriteBatchedStatements=true&cachePrepStmts=true&allowMultiQueries=true&serverTimeZone=Aisa/Shanghai
username: root
password: lihaozhe
type: com.alibaba.druid.pool.DruidDataSource
druid:
# 下面为连接池的补充设置,应用到上面所有数据源中
# 初始化大小,最小,最大
initial-size: 5
min-idle: 5
max-active: 200
# 配置获取连接等待超时的时间
max-wait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
time-between-eviction-runs-millis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
min-evictable-idle-time-millis: 300000
validation-query: SELECT 1 FROM DUAL
test-while-idle: true
test-on-borrow: false
test-on-return: false
# 打开PSCache,并且指定每个连接上PSCache的大小
pool-prepared-statements: true
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
max-pool-prepared-statement-per-connection-size: 20
filters: stat,wall,slf4j
use-global-data-source-stat: true
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
# connect-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
stat-view-servlet:
login-username: admin
login-password: 123456
reset-enable: false
url-pattern: /druid/*
allow: 0.0.0.0
#deny:
enabled: true
web-stat-filter:
url-pattern: /*
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
jpa:
database: MySQL
database-platform: org.hibernate.dialect.MySQL8Dialect
show-sql: true
open-in-view: true
hibernate:
ddl-auto: update
# 自动创建数据建库表(hibernate.hbm2ddl.auto):
# create:程序运行时创建数据库表(如果有表,先删除表再创建)
# update:程序运行时创建数据库表(如果有表,不会创建表)
# none:不会创建数据库
lhz:
project:
title: 李昊哲-小课
slogan: 桃李不言下自成蹊
map: { "B": "https://space.bilibili.com/480308139","C": "https://blog.csdn.net/qq_24330181" }
list:
- https://space.bilibili.com/480308139
- https://blog.csdn.net/qq_24330181
lhzSite:
name: 李昊哲-小课
url: https://space.bilibili.com/480308139
siteList:
- name: 李昊哲-小课 B站
url: https://space.bilibili.com/480308139
- name: 李昊哲-小课 C站
url: https://blog.csdn.net/qq_24330181
启动 springboot 项目
浏览器测试