kotlin-spring-data-jpa 开发脚手架

1. 基本常用类:

注解 自定义kotlin注解
自定义日志切面注解@Log,获取当前用户注解@CurrentUser
使用annotation关键词

@Target(AnnotationTarget.FUNCTION) // 可用在方法的参数上
@Retention()
annotation class CurrentUser(
    /**
     * 当前用户在session对象中的key
     */
    val value: String = SystemConstants.CURRENT_USER
)

常量类
object 关键词声明一个单例对象,const 关键字用来修饰常量,且只能修饰 val

object RequestPath {
  //base path
  const val BASE_PATH: String = "/api"

  //model path
  //用户
  const val USER: String = "/user"
  //登陆
  const val LOGIN: String = "/login"
}

枚举
enum关键词

enum class OrderType(private val code: Short, private val description: String) {
 
 BID(0, "aaa"),
 ASK(1, "bbb");
 
 fun code() = code
 
 fun description() = description
}

2. 表单参数校验

使用hibernate-validator进行参数校验,只需要引入spring-boot-starter-web依赖即可,其子依赖含有


    org.hibernate
    hibernate-validator


    com.fasterxml.jackson.core
    jackson-databind

实体类添加注解:

        @field:NotNull(message = "账号不能为空")
    @Column(name = "account")
    val account: String? = null,

    @Column(name = "pwd")
    val pwd: String? = null,

    @Column(name = "salt")
    val salt: String? = null,

    @Column(name = "first_name")
    val firstName: String? = null,

    @Column(name = "last_name")
    val lastName: String? = null,

    @field:Email(message = "邮箱格式不正确")
    @Column(name = "email")
    val email: String? = null,

    @field:Max(11, message = "手机号应该是11位")
    @field:Min(11, message = "手机号是11位")
    @field:Pattern(regexp = "^1(3|4|5|7|8|9)\\d{9}$", message = "手机号码格式错误")
    @Column(name = "mobile")
    val mobile: String? = null

这里@field:Email注解前面不加上field使用不生效
@field:Pattern使用正则匹配
message是验证失败提示信息
搭配全局异常处理,处理参数校验失败异常MethodArgumentNotValidException

//参数校验失败异常
  @ExceptionHandler(value = [(MethodArgumentNotValidException::class)])
  @Throws(MethodArgumentNotValidException::class)
  fun violationErrorHandler(req: HttpServletRequest, e: MethodArgumentNotValidException): RespBody<*> {
    e.printStackTrace()
    return ResultUtils.badRequest(e.bindingResult.allErrors.get(0).defaultMessage as String)
  }

示例:
参数为空校验,邮箱格式,手机号校验:(校验顺序不确定)

表单提交:
{
  "pwd": "string",
  "salt": "string",
  "firstName": "string",
  "lastName": "string",
  "email": "aaaa.com",
  "mobile": "stringstrin",
  "url": "string"
}
返回:
{"code":400,"msg":"Bad Request","data":"账号不能为空"}
或
{"code":400,"msg":"Bad Request","data":"手机号应该是11位"}
或
{"code":400,"msg":"Bad Request","data":"邮箱格式不正确"}

3. 一些通用封装

baseController,baseService,BaseRepository

//在BaseRepository上添加@NoRepositoryBean标注,这样Spring Data Jpa在启动时就不会去实例化BaseRepository这个接口
@NoRepositoryBean
interface BaseRepository : JpaSpecificationExecutor, JpaRepository

4. 使用specification-arg-resolver条件查询

    override fun addArgumentResolvers(argumentResolvers: MutableList) {
    argumentResolvers.add(currentUserMethodArgumentResolver())
    argumentResolvers.add(specificationArgumentResolver())
    super.addArgumentResolvers(argumentResolvers)
  }

  //currentuser 参数解析
  @Bean
  fun currentUserMethodArgumentResolver(): CurrentUserMethodArgumentResolver {
    return CurrentUserMethodArgumentResolver()
  }

  //specification 参数解析
  @Bean
  fun specificationArgumentResolver(): SpecificationArgumentResolver {
    return SpecificationArgumentResolver()
  }
//-------------
    @GetMapping()
  @Log//日志注解
  @ApiImplicitParams(
      ApiImplicitParam(name = "account", paramType = "query", dataType = "string"),
      ApiImplicitParam(name = "email", paramType = "query", dataType = "string")
  )
  fun all(
      @And(
          Spec(path = "account", spec = Like::class),
          Spec(path = "email", spec = Like::class)
      )
      @ApiIgnore specification: Specification?,
      @ApiIgnore pageParams: PageParams?
  ): RespBody<*> {
    return if (pageParams?.currentPage == null) ResultUtils.success(
        userDomain.all(specification)
    )
    else ResultUtils.success(
        userDomain.page(specification, PageRequest.of(pageParams.currentPage, pageParams.pageSize))
    )
  }
  
  //关联查询
  @RequestMapping("/customers")
    fun findByOrderedOrFavouriteItem(
        @Joins(
            Join(path = "orders", alias = "o"),
            Join(path = "favourites", alias = "f")
        )
        @And(
            Spec(path = "account", spec = Like::class),
            Spec(path = "email", spec = Like::class)
        )
        @ApiIgnore specification: Specification?): RespBody<*> {
  
      return ResultUtils.success(userServiceImpl.findAll(specification))
    }
    

5. 拦截器

//注册拦截器
override fun addInterceptors(registry: InterceptorRegistry) {
    // addPathPatterns 添加路径
    // excludePathPatterns 排除路径
    registry.addInterceptor(BaseInterceptor()).addPathPatterns("/**")
    super.addInterceptors(registry)
  }
  //拦截器
class BaseInterceptor : HandlerInterceptor {
  @Throws(Exception::class)
  override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, any: Any): Boolean {
    println("拦截器MyInterceptor------->1、请求之前调用,也就是Controller方法调用之前。")
    //测试使用
    //获取Spring beans
    SpringUtils.getBean(UserServiceImpl::class.java).let {
      val usr = request.session.getAttribute(SystemConstants.CURRENT_USER)
      if (null == usr) {
        it.getOne(1).also {
          request.session.setAttribute(SystemConstants.CURRENT_USER, it)
        }
      }
    }
    return true//返回true则继续向下执行,返回false则取消当前请求
  }

}

6. 配置文件

spring:
  application:
    name: auth
  datasource:
    url: jdbc:mysql://ip:3306/cheap_car?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull
    username: root
    password: pwd
  jpa:
    database: MYSQL
    hibernate:
      ddl-auto: update
    show-sql: true
    database-platform: org.hibernate.dialect.MySQL5Dialect

#####
swagger:
  title: kotlin dev  
  description: 
  contact:
    url: https://github.com/athc
    email: [email protected]
    #扫描包路径
  base-package: org.athc.auth.controller
  #添加的path
  base-path: /**
  #排除path
  exclude-path: /error

see more: https://gitee.com/athe/ath_unimodule

你可能感兴趣的:(kotlin-spring-data-jpa 开发脚手架)