通常Scala是这么定义实体类或领域对象的
case class A(a: Int, b: String)
但是这个类在Mybatis中是无效的,因为Mybatis通过反射无参构造来生成对象。
1.一种方法是为样例类定义副构造函数
case class A(a: Int, b: String) { def this()= { this(0, null) } }
以上如果还需要get/set方法,还应该增加@BeanProperty注解在字段上
2.第二种是不再使用样例类
// 主构造是需2个参数的,这种定义如果对象有很多字段,但是数据只返回部分,则反射仍然失败 // 如果对象需要Java的get/set方法,还需要未每个字段添加@BeanProperty注解 class A(val a: Int, val b: String) { //所以还是需要提供一个无参构造用于反射构造一个对象 def this()= { this(0, null) } } class A { //生成Java的get/set方法 @BeanProperty var a: Int @BeanProperty var b: String //定义副构造,因为此时主构造就是无参的 def this(a: Int, b: String)= { this.a=a this.b=b } }Spring获取字段失败?
因为case class没有Java的get/set方法,字段需要加@BeanProperty注解
改进的兼容方式scala2.13 导入库
implementation 'io.github.jxnu-liguobin:scala-macro-tools_2.13:0.3.2'
增加gradle编译参数
tasks.withType(ScalaCompile) { scalaCompileOptions.additionalParameters = ["-Ymacro-annotations"] }
使用宏注解@JavaCompatible在case class定义上
@JavaCompatible case class AddInfo( id: Int, uid: Int, content: String, from: Int, from_group: Int, `type`: Int, remark: String, href: String, read: Int, time: String, user: User //使用@JavaCompatible注解时,嵌套对象User不能定义在同一个object中。(很多Scala喜欢将领域对象都放在一个文件中,但是宏处理不了这种情况,会出现找不到或编译器的循环依赖错误) )
@JavaCompatible说明:
- 为case class生成默认的无参构造函数
- 为case class生成所有字段的get/set方法(这是通过在编译期间为所有字段增加@BeanProperty来实现的)
- 该注解强制在case class上才能使用,编译期类型安全,如果有不支持的类型,编译不会通过
- 该注解还会校验case class的字段是否已经有@BeanProperty,不会重复放置
- 如果case class已经存在无参构造,则编译不通过
- 该注解支持case class的柯里化,但是柯里化参数块中的b参数需要指定为val或var(如:case class A(a: Int)(val b: String)),否则由于编译器将其视为private[this],注解会忽略这种字段。(应该改成编译期报错,这种一般是service用于隐式参数,不应该这样用)
我们的文档在 https://bitlap.org/lab/smt/java-compatible
我们源码实现 https://github.com/jxnu-liguobin/scala-macro-tools
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)