# ath_unimodule **Repository Path**: athe/ath_unimodule ## Basic Information - **Project Name**: ath_unimodule - **Description**: kotlin-spring-data-jpa 开发脚手架 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2018-07-31 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # kotlin-spring-data-jpa 开发脚手架 *多模块基础架构:https://github.com/athc/ath-cloud* ###1. 基本常用类: **注解** 自定义kotlin注解 自定义日志切面注解@Log,获取当前用户注解@CurrentUser 使用`annotation`关键词 ```kotlin @Target(AnnotationTarget.FUNCTION) // 可用在方法的参数上 @Retention() annotation class CurrentUser( /** * 当前用户在session对象中的key */ val value: String = SystemConstants.CURRENT_USER ) ``` **常量类** object 关键词声明一个单例对象,const 关键字用来修饰常量,且只能修饰 val ```kotlin object RequestPath { //base path const val BASE_PATH: String = "/api" //model path //用户 const val USER: String = "/user" //登陆 const val LOGIN: String = "/login" } ``` **枚举** `enum`关键词 ```kotlin 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`依赖即可,其子依赖含有 ```xml org.hibernate hibernate-validator com.fasterxml.jackson.core jackson-databind ``` 实体类添加注解: ```kotlin @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 ```kotlin //参数校验失败异常 @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) } ``` 示例: 参数为空校验,邮箱格式,手机号校验:(校验顺序不确定) ```json 表单提交: { "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]() ```kotlin //在BaseRepository上添加@NoRepositoryBean标注,这样Spring Data Jpa在启动时就不会去实例化BaseRepository这个接口 @NoRepositoryBean interface BaseRepository : JpaSpecificationExecutor, JpaRepository ``` ###4. 使用[`specification-arg-resolver`](https://github.com/tkaczmarzyk/specification-arg-resolver)条件查询 ```kotlin 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. 拦截器 ```kotlin //注册拦截器 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. 配置文件 ```yaml 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: dujf54732@gmail.com #扫描包路径 base-package: org.athc.auth.controller #添加的path base-path: /** #排除path exclude-path: /error ``` *多模块基础架构:https://github.com/athc/ath-cloud*