千家信息网

Spring Boot和Kotlin无缝整合与完美交融的示例分析

发表于:2024-11-19 作者:千家信息网编辑
千家信息网最后更新 2024年11月19日,这篇文章主要介绍了Spring Boot和Kotlin无缝整合与完美交融的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。环境依
千家信息网最后更新 2024年11月19日Spring Boot和Kotlin无缝整合与完美交融的示例分析

这篇文章主要介绍了Spring Boot和Kotlin无缝整合与完美交融的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

环境依赖

修改 POM 文件,添加 spring boot 依赖。

 org.springframework.boot spring-boot-starter-parent 2.0.2.RELEASE   org.springframework.boot spring-boot-starter   org.springframework.boot spring-boot-starter-web   org.springframework.boot spring-boot-starter-jdbc 

紧接着,我们需要添加 mysql 依赖。

 mysql mysql-connector-java 5.1.35 com.alibaba druid 1.0.14

最后,添加 Kotlin 依赖。

 org.jetbrains.kotlin kotlin-stdlib-jdk8 org.jetbrains.kotlin kotlin-reflect org.jetbrains.kotlin kotlin-stdlib

注意的是,在 Kotlin 中,data class 默认没有无参构造方法,并且 data class 默认为 final 类型,不可以被继承。注意的是,如果我们使用 Spring + Kotlin 的模式,那么使用 @autowared 就可能遇到这个问题。因此,我们可以添加 NoArg 为标注的类生成无参构造方法。使用 AllOpen 为被标注的类去掉 final,允许被继承。

 kotlin-maven-plugin org.jetbrains.kotlin ${kotlin.version}   compile  compile    test-compile  test-compile      org.jetbrains.kotlin kotlin-maven-noarg ${kotlin.version}   org.jetbrains.kotlin kotlin-maven-allopen ${kotlin.version}  

至此,我们 Maven 的依赖环境大致配置完毕。完整的源码,可以参见文末 GitHub 仓库。

数据源

方案一 使用 Spring Boot 默认配置

使用 Spring Boot 默认配置,不需要在创建 dataSource 和 jdbcTemplate 的 Bean。

在 src/main/resources/application.properties 中配置数据源信息。

spring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3307/springboot_dbspring.datasource.username=rootspring.datasource.password=root

方案二 手动创建

在 src/main/resources/config/source.properties 中配置数据源信息。

# mysqlsource.driverClassName = com.mysql.jdbc.Driversource.url = jdbc:mysql://localhost:3306/springboot_dbsource.username = rootsource.password = root

这里, 创建 dataSource 和jdbcTemplate。

@Configuration@EnableTransactionManagement@PropertySource(value = *arrayOf("classpath:config/source.properties"))open class BeanConfig {  @Autowired private lateinit var env: Environment  @Bean open fun dataSource(): DataSource { val dataSource = DruidDataSource() dataSource.driverClassName = env!!.getProperty("source.driverClassName").trim() dataSource.url = env.getProperty("source.url").trim() dataSource.username = env.getProperty("source.username").trim() dataSource.password = env.getProperty("source.password").trim() return dataSource }  @Bean open fun jdbcTemplate(): JdbcTemplate { val jdbcTemplate = JdbcTemplate() jdbcTemplate.dataSource = dataSource() return jdbcTemplate }}

脚本初始化

先初始化需要用到的 SQL 脚本。

CREATE DATABASE /*!32312 IF NOT EXISTS*/`springboot_db` /*!40100 DEFAULT CHARACTER SET utf8 */; USE `springboot_db`; DROP TABLE IF EXISTS `t_author`; CREATE TABLE `t_author` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户ID', `real_name` varchar(32) NOT NULL COMMENT '用户名称', `nick_name` varchar(32) NOT NULL COMMENT '用户匿名', PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

使用 JdbcTemplate 操作

实体对象

class Author { var id: Long? = null var realName: String? = null var nickName: String? = null}

DAO相关

interface AuthorDao { fun add(author: Author): Int fun update(author: Author): Int fun delete(id: Long): Int fun findAuthor(id: Long): Author? fun findAuthorList(): List}

我们来定义实现类,通过 JdbcTemplate 定义的数据访问操作。

@Repositoryopen class AuthorDaoImpl : AuthorDao {  @Autowired private lateinit var jdbcTemplate: JdbcTemplate  override fun add(author: Author): Int { return jdbcTemplate.update("insert into t_author(real_name, nick_name) values(?, ?)", author.realName, author.nickName) }  override fun update(author: Author): Int { return jdbcTemplate.update("update t_author set real_name = ?, nick_name = ? where id = ?", *arrayOf(author.realName, author.nickName, author.id)) }  override fun delete(id: Long): Int { return jdbcTemplate.update("delete from t_author where id = ?", id) }  override fun findAuthor(id: Long): Author? { val list = jdbcTemplate.query("select * from t_author where id = ?", arrayOf(id), BeanPropertyRowMapper(Author::class.java)) return list?.get(0); }  override fun findAuthorList(): List { return jdbcTemplate.query("select * from t_author", arrayOf(), BeanPropertyRowMapper(Author::class.java)) }}

Service相关

interface AuthorService { fun add(author: Author): Int fun update(author: Author): Int fun delete(id: Long): Int fun findAuthor(id: Long): Author? fun findAuthorList(): List}

我们来定义实现类,Service 层调用 Dao 层的方法,这个是典型的套路。

@Service("authorService")open class AuthorServiceImpl : AuthorService {  @Autowired private lateinit var authorDao: AuthorDao  override fun update(author: Author): Int { return this.authorDao.update(author) }  override fun add(author: Author): Int { return this.authorDao.add(author) }  override fun delete(id: Long): Int { return this.authorDao.delete(id) }  override fun findAuthor(id: Long): Author? { return this.authorDao.findAuthor(id) }  override fun findAuthorList(): List { return this.authorDao.findAuthorList() }}

Controller相关

为了展现效果,我们先定义一组简单的 RESTful API 接口进行测试。

@RestController@RequestMapping(value = "/authors")class AuthorController {  @Autowired private lateinit var authorService: AuthorService  /** * 查询用户列表 */ @RequestMapping(method = [RequestMethod.GET]) fun getAuthorList(request: HttpServletRequest): Map { val authorList = this.authorService.findAuthorList() val param = HashMap() param["total"] = authorList.size param["rows"] = authorList return param }  /** * 查询用户信息 */ @RequestMapping(value = "/{userId:\\d+}", method = [RequestMethod.GET]) fun getAuthor(@PathVariable userId: Long, request: HttpServletRequest): Author { return authorService.findAuthor(userId) ?: throw RuntimeException("查询错误") }  /** * 新增方法 */ @RequestMapping(method = [RequestMethod.POST]) fun add(@RequestBody jsonObject: JSONObject) { val userId = jsonObject.getString("user_id") val realName = jsonObject.getString("real_name") val nickName = jsonObject.getString("nick_name")  val author = Author() author.id = java.lang.Long.valueOf(userId) author.realName = realName author.nickName = nickName try { this.authorService.add(author) } catch (e: Exception) { throw RuntimeException("新增错误") } }  /** * 更新方法 */ @RequestMapping(value = "/{userId:\\d+}", method = [RequestMethod.PUT]) fun update(@PathVariable userId: Long, @RequestBody jsonObject: JSONObject) { var author = this.authorService.findAuthor(userId) val realName = jsonObject.getString("real_name") val nickName = jsonObject.getString("nick_name") try { if (author != null) { author.realName = realName author.nickName = nickName this.authorService.update(author) } } catch (e: Exception) { throw RuntimeException("更新错误") }  }  /** * 删除方法 */ @RequestMapping(value = "/{userId:\\d+}", method = [RequestMethod.DELETE]) fun delete(@PathVariable userId: Long) { try { this.authorService.delete(userId) } catch (e: Exception) { throw RuntimeException("删除错误") } }}

最后,我们通过 SpringKotlinApplication 运行程序。

@SpringBootApplication(scanBasePackages = ["com.lianggzone.demo.kotlin"])open class SpringKotlinApplication{ fun main(args: Array) { SpringApplication.run(SpringKotlinApplication::class.java, *args) }}

关于测试

这里,笔者推荐 IDEA 的 Editor REST Client。IDEA 的 Editor REST Client 在 IntelliJ IDEA 2017.3 版本就开始支持,在 2018.1 版本添加了很多的特性。事实上,它是 IntelliJ IDEA 的 HTTP Client 插件。参见笔者之前的另一篇文章: 快速测试 API 接口的新技能

### 查询用户列表GET http://localhost:8080/authorsAccept : application/jsonContent-Type : application/json;charset=UTF-8 ### 查询用户信息GET http://localhost:8080/authors/15Accept : application/jsonContent-Type : application/json;charset=UTF-8 ### 新增方法POST http://localhost:8080/authorsContent-Type: application/json { "user_id": "21", "real_name": "梁桂钊", "nick_name": "梁桂钊"} ### 更新方法PUT http://localhost:8080/authors/21Content-Type: application/json { "real_name" : "lianggzone", "nick_name": "lianggzone"} ### 删除方法DELETE http://localhost:8080/authors/21Accept : application/jsonContent-Type : application/json;charset=UTF-8

感谢你能够认真阅读完这篇文章,希望小编分享的"Spring Boot和Kotlin无缝整合与完美交融的示例分析"这篇文章对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,更多相关知识等着你来学习!

0