面向对象编程之类

  1. //定义一个简单的类
  2. scala> :paste
  3. // Entering paste mode (ctrl-D to finish)
  4. //类默认public的
  5. class HelloWorld{
  6. private var name = "leo"
  7. def sayHello(){print("Hello,"+name)}
  8. def getName = name
  9. }
  10. // Exiting paste mode, now interpreting.
  11. defined class HelloWorld
  12. scala> var helloWorld = new HelloWorld
  13. helloWorld: HelloWorld = HelloWorld@74f143e1
  14. scala> helloWorld.sayHello()
  15. Hello,leo
  16. scala> print(helloWorld.getName) //也可以不加括号,如果定义方法时不带括号,则用方法时也不能带括号
  17. leo
  1. //getter与setter
  2. //定义不带private的var field,JVM会自动定义为private,并提供public的getter和setter方法
  3. //如果定义private 修饰field,则生成getter和setter也是private的
  4. //如果定义val filed,则只会生成getter方法
  5. //如果不希望生成setter和getter方法,则将field声明为private[this]

自定义getter与setter

  1. scala> :paste
  2. // Entering paste mode (ctrl-D to finish)
  3. class Student{
  4. private var myName = "leo"
  5. def name = "your name is" + myName
  6. def name_=(newValue:String){
  7. print("you cannot edit your name!!")
  8. }
  9. }
  10. // Exiting paste mode, now interpreting.
  11. defined class Student
  12. scala> val leo = new Student //()可有可无
  13. leo: Student = Student@4064c13a
  14. scala> print(leo.name)
  15. your name isleo
  16. scala> leo.name = "leo1" //相当于setter方法
  17. you cannot edit your name!!leo.name: String = your name isleo

仅暴露field的getter方法

  1. scala> :paste
  2. // Entering paste mode (ctrl-D to finish)
  3. class Student{
  4. private var myName = "leo" //private修饰,不暴露getter和setter方法,因此可以自定义
  5. def updateName(newName:String){
  6. if(newName == "leo1") myName = newName
  7. else print("not accpet this new name!!")
  8. }
  9. def name = "your name is "+myName
  10. }
  11. // Exiting paste mode, now interpreting.
  12. defined class Student
  13. scala> val s = new Student()
  14. s: Student = Student@6ff347a9
  15. scala> s.name
  16. res30: String = your name is leo
  17. scala> s.updateName("tom")
  18. not accpet this new name!!
  19. scala> s.updateName("leo1")
  20. scala> s.name
  21. res33: String = your name is leo1

private[this]的使用

  1. scala> :paste
  2. // Entering paste mode (ctrl-D to finish)
  3. class Student{
  4. private var myAge = 0
  5. def age_=(newValue:Int){
  6. if(newValue > 0) myAge = newValue
  7. else print("illegal age!")
  8. }
  9. def age = myAge
  10. def older(s:Student)={ //用private[this]修饰的话会报错
  11. myAge > s.myAge
  12. }
  13. }
  14. // Exiting paste mode, now interpreting.
  15. defined class Student
  16. scala> val s1 = new Student
  17. s1: Student = Student@1c437904
  18. scala> s1.age = 20
  19. s1.age: Int = 20
  20. scala> val s2 = new Student
  21. s2: Student = Student@400f0e8e
  22. scala> s2.age = 25
  23. s2.age: Int = 25
  24. scala> s1.older(s2)
  25. res34: Boolean = false

java风格的getter和setter

  1. // 在Scala 2.10.0之后已被废弃
  2. // 使用scala.beans.BeanProperty代替
  3. scala> import scala.beans.BeanProperty
  4. import scala.beans.BeanProperty
  5. scala> :paste
  6. // Entering paste mode (ctrl-D to finish)
  7. class Student{
  8. @BeanProperty var name:String = _
  9. }
  10. // Exiting paste mode, now interpreting.
  11. defined class Student
  12. scala> val s = new Student
  13. s: Student = Student@1166c9c5
  14. scala> s.setName("leo")
  15. scala> s.get
  16. getClass getName
  17. scala> s.getName
  18. res39: String = leo

辅助构造函数constructor

  1. scala> :paste
  2. // Entering paste mode (ctrl-D to finish)
  3. class Student{
  4. private var name = ""
  5. private var age = 0
  6. def this(name:String){
  7. this()
  8. this.name = name
  9. }
  10. def this(name:String,age:Int){
  11. this(name)
  12. this.age = age
  13. }
  14. }
  15. // Exiting paste mode, now interpreting.
  16. defined class Student
  17. scala> var s1 = new Student()
  18. s1: Student = Student@51c959a4
  19. scala> val s2 = new Student("leo")
  20. s2: Student = Student@51a18b21
  21. scala> val s3 = new Student("leo",30)
  22. s3: Student = Student@40ef0af8

主构造函数constructor

  1. //主constructor与类名放在一起,与java不同
  2. //类中没有定义在任何方法或者代码块中的代码,就是主constructor的代码
  3. scala> :paste
  4. // Entering paste mode (ctrl-D to finish)
  5. class Student(val name:String,val age:Int){
  6. println("your name is "+name +",your age is "+age)
  7. }
  8. // Exiting paste mode, now interpreting.
  9. defined class Student
  10. scala> val s = new Student
  11. <console>:12: error: not enough arguments for constructor Student: (name: String, age: Int)Student.
  12. Unspecified value parameters name, age.
  13. val s = new Student
  14. ^
  15. scala> val s = new Student("jom",23)
  16. your name is jom,your age is 23
  17. s: Student = Student@2d70f312
  18. //给默认值
  19. scala> :paste
  20. // Entering paste mode (ctrl-D to finish)
  21. class Student(val name:String="leo",val age:Int=30){ // 如果主constructor传入的参数什么修饰都没有,比如name:String ,那么如果类内部方法使用到了,则会声明为private[this] name;否则没有该field,就只能被constructor代码使用而已
  22. println(name+" "+age)
  23. }
  24. // Exiting paste mode, now interpreting.
  25. defined class Student
  26. scala> val s1 = new Student
  27. leo 30
  28. s1: Student = Student@cf10c92

内部类

  1. scala> import scala.collection.mutable.ArrayBuffer
  2. import scala.collection.mutable.ArrayBuffer
  3. scala> :paste
  4. // Entering paste mode (ctrl-D to finish)
  5. class Class{
  6. class Student(val name:String){}
  7. val students = new ArrayBuffer[Student]
  8. def getStudent(name:String)={
  9. new Student(name)
  10. }
  11. }
  12. // Exiting paste mode, now interpreting.
  13. defined class Class
  14. scala> val c1 = new Class
  15. c1: Class = Class@539bb233
  16. scala> val s1 = c1.getStudent("leo")
  17. s1: c1.Student = Class$Student@48b01607
  18. scala> c1.students += s1
  19. res0: c1.students.type = ArrayBuffer(Class$Student@48b01607)
  20. scala> val c2 = new Class
  21. c2: Class = Class@475fb7
  22. scala> val s2 = c2.getStudent("leo")
  23. s2: c2.Student = Class$Student@5f9f1886
  24. scala> c1.students += s2
  25. <console>:15: error: type mismatch;
  26. found : c2.Student
  27. required: c1.Student
  28. c1.students += s2
  29. ^

面向对象编程之对象

  1. object,相当于class的单个实例,通常在里面放一些静态的field或者method
  2. 第一次调用object的方法时,就会执行object的constructor,也就是object内部不在method中的代码;但是object不能定义接收参数的constructor
  3. 注意,object的constructor只会在第一次被调用时执行一次,以后再调用不会再次执行constructor
  4. object通常用于作为单例模式的实现,或者放class的静态成员,比如工具方法
  1. scala> :paste
  2. // Entering paste mode (ctrl-D to finish)
  3. object Person{
  4. private var eyeNum=2
  5. println("this Person object!")
  6. def getEyeNum = eyeNum
  7. }
  8. scala> Person.getEyeNum
  9. this Person object!
  10. res3: Int = 2

伴生对象

  1. 如果有一个class,还有一个与class同名的object,那么就称这个object是class的伴生对象,class是object的伴生类
  2. 伴生对象伴生类和伴生对象必须放在一个.scala文件之中
  3. 伴生类和伴生对象,最大的特点就在于,互相可以访问private field
  1. scala> :paste
  2. // Entering paste mode (ctrl-D to finish)
  3. class Person(val name:String,val age:Int){
  4. def sayHello = println("Hi,"+name+",I guess you are "+age+"years old!"+Person.eyeNum)
  5. }
  6. object Person{
  7. private val eyeNum = 2
  8. def getEyeNum = eyeNum
  9. }
  10. scala> val p = new Person("TOM",30)
  11. p: Person = Person@101f2ca2
  12. scala> p.sayHello
  13. Hi,TOM,I guess you are 30years old!2

让object继承抽象类

  1. object的功能其实和class类似,除了不能定义接收参数的constructor之外
  2. object也可以继承抽象类,并覆盖抽象类中的方法
  1. scala> :paste
  2. // Entering paste mode (ctrl-D to finish)
  3. abstract class Hello(val message:String){
  4. def sayHello(name:String):Unit
  5. }
  6. object HelloImpl extends Hello("hello"){
  7. override def sayHello(name:String)={
  8. println(message+","+name)
  9. }
  10. }
  11. scala> HelloImpl.sayHello("world")
  12. hello,world

apply方法

  1. object中非常重要的一个特殊方法,就是apply方法
  2. 通常在伴生对象中实现apply方法,并在其中实现构造伴生类的对象的功能
  3. 而创建伴生类的对象时,通常不会使用new Class的方式,而是使用Class()的方式,隐式地调用伴生对象的apply方法,这样会让对象创建更加简洁
  4. 比如,Array类的伴生对象的apply方法就实现了接收可变数量的参数,并创建一个Array对象的功能
  5. val a = Array(1,2,3,4,5)
  1. scala> :paste
  2. // Entering paste mode (ctrl-D to finish)
  3. class Person(val name: String)
  4. object Person{
  5. def apply(name:String)=new Person(name)
  6. }
  7. // Exiting paste mode, now interpreting.
  8. defined class Person
  9. defined object Person
  10. scala> val p1 = new Person("leo")
  11. p1: Person = Person@7698b7a4
  12. scala> val p2 = Person("leo")
  13. p2: Person = Person@374c40ba

main方法

  1. 方法入口
  2. scala中main方法定义为def main(args:Array[String]),而且必须定义在object中
  1. object HelloWorld{
  2. def main(args:Array[String]){
  3. println("Hello World!!")
  4. }
  5. }
  1. 除了自己实现main方法之外,还可以继承App Trait,然后将需要在main方法中运行的代码,直接作为object的constructor代码;而且用args可以接受传入的参数
  1. object HelloWorld extends App{
  2. if(args.length > 0) println("hello," + args(0))
  3. else println("Hello World!!")
  4. }
  1. 运行上述代码,需要放入.scala文件中,然后使用scalac编译,再用scala运行class文件 scala -Dscala.time HelloWorld
  2. App Trait的工作原理为:App Trait继承自DelayedInit Trait,scalac命令进行编译时,会把继承App Trait的object的constructor代码都放到DelayedInit Trait的delayedInit方法中执行

用object来实现枚举功能

  1. scala没有直接提供类似于java中的Enum这样的枚举特性,如果要实现枚举,则需要用object继承Enumeration类,并且调用Value方法来初始化枚举值
  1. object Season extends Enumeration{
  2. val SPRING,SUMMER,AUTUMN,WINTER = Value
  3. }
  4. scala> Season.SPRING
  5. res0: Season.Value = SPRING
  1. 还可以通过Value传入枚举值的id和name,通过id和toString可以获取,还可以通过id和name来查找枚举值
  1. scala> :paste
  2. // Entering paste mode (ctrl-D to finish)
  3. object Season extends Enumeration{
  4. val SPRING = Value(0,"spring")
  5. val SUMMER = Value(1,"summer")
  6. val AUTUMN = Value(2,"autumn")
  7. val WINTER = Value(3,"winter")
  8. }
  9. // Exiting paste mode, now interpreting.
  10. defined object Season
  11. scala> Season(0)
  12. res0: Season.Value = spring
  13. scala> Season.withName("spring")
  14. res1: Season.Value = spring
  15. scala> for(ele <- Season.values) println(ele)
  16. spring
  17. summer
  18. autumn
  19. winter

面向对象编程之继承

  1. 让子类继承父类,与java一样,也是使用extends关键字
  2. 继承就代表,子类可以从父类继承父类的field和method;然后子类可以在自己内部放入父类所没有,子类特有的field和method;使用继承可以有效复用代码
  3. 子类可以覆盖父类的filed和method;但是如果父类用final修饰,field和method用final修饰,则该类是无法被继承的,field和method是无法被覆盖的
  1. scala> :paste
  2. // Entering paste mode (ctrl-D to finish)
  3. class Person{
  4. private var name = "leo"
  5. def getName = name
  6. }
  7. class Student extends Person{
  8. private var score = "A"
  9. def getScore = score
  10. }
  11. // Exiting paste mode, now interpreting.
  12. defined class Person
  13. defined class Student
  14. scala> val s1 = new Student()
  15. s1: Student = Student@1530d0f2
  16. scala> s1.getScore
  17. res3: String = A
  18. scala> s1.getName
  19. res4: String = leo

override和super

  1. 如果子类要覆盖一个父类中的非抽象方法,则必须使用override关键字
  2. override关键字可以帮组我们尽早的发现代码里的错误,覆写方法错了就会报错
  3. 在子类覆盖父类方法之后,如果我们在子类中就是要调用父类的被覆盖的方法,那就可以使用super关键字,显式地指定要调用父类的方法
  1. scala> :paste
  2. // Entering paste mode (ctrl-D to finish)
  3. class Person{
  4. private var name="leo"
  5. def getName = name
  6. }
  7. class Student extends Person{
  8. private var score = "A"
  9. def getScore = score
  10. override def getName = "Hi,I'm "+ super.getName
  11. }
  12. // Exiting paste mode, now interpreting.
  13. defined class Person
  14. defined class Student
  15. scala> val st = new Student
  16. st: Student = Student@445c693
  17. scala> st.getName
  18. res5: String = Hi,I'm leo

isInstanceOf和asInstanceOf

  1. 如果我们创建了子类的对象,但是又将其赋予了父类类型的变量,则在后续的程序中,我们又需要将父类类型的变量转换为子类类型的变量
  2. 使用isInstanceOf判断对象是否是指定类的对象,如果是的话,则可以使用asInstanceOf将对象转换为指定类型
  3. 注意,如果对象是null,则isInstanceOf一定返回false,asInstanceOf一定返回null
  4. 注意,如果没有用isInstanceOf先判断对象是否为指定类的实例,就直接用asInstanceOf转换,则可能会抛出异常
  1. scala> :paste
  2. // Entering paste mode (ctrl-D to finish)
  3. class Person
  4. class Student extends Person
  5. val p:Person = new Student
  6. var s:Student = null
  7. if(p.isInstanceOf[Student]) s = p.asInstanceOf[Student]
  8. // Exiting paste mode, now interpreting.
  9. defined class Person
  10. defined class Student
  11. p: Person = Student@2d7e6c8c
  12. s: Student = Student@2d7e6c8c
  13. scala> s
  14. res9: Student = Student@2d7e6c8c

getClass和classOf

  1. isInstanceOf只能判断对象是否是指定类以及其子类的对象,而不能精确判断出,对象就是指定类的对象
  2. 如果要求精确地判断对象就是指定类的对象,那么就只能使用getClass和classOf了
  3. 对象.getClass可以精确获取对象的类,classOf[类]可以精确获取类,然后使用==操作符即可判断
  1. scala> :paste
  2. class Person
  3. class Student extends Person
  4. val p:Person = new Student
  5. p.isInstanceOf[Person]
  6. // Exiting paste mode, now interpreting.
  7. defined class Person
  8. defined class Student
  9. p: Person = Student@5b95557f
  10. res11: Boolean = true
  11. scala> p.getClass == classOf[Person]
  12. res12: Boolean = false
  13. scala> p.getClass == classOf[Student]

使用模式匹配进行类型判断

  1. 在实际开发中,比如spark的源码中,大量的地方使用模式匹配的方式来进行类型的判断
  2. 功能性上来说,与isInstanceOf一样,判断主要是该类以及该类的子类的对象即可,不是精准判断的
  1. scala> :paste
  2. // Entering paste mode (ctrl-D to finish)
  3. class Person
  4. class Student extends Person
  5. val p:Person = new Student
  6. p match{
  7. case per:Person => println("its Person object")
  8. case _ => println("unkonwn type")
  9. }
  10. // Exiting paste mode, now interpreting.
  11. its Person object
  12. defined class Person
  13. defined class Student
  14. p: Person = Student@7f4596d0

protected

  1. 跟java一样,使用protected关键字修饰的filed和method,在子类中就不需要super关键字,直接就可以访问field和method
  2. 还可以使用protected[this],则只能在当前子类对象中访问父类的field和method,无法通过其他子类对象访问父类的field和mehtod
  1. scala> :paste
  2. // Entering paste mode (ctrl-D to finish)
  3. class Person{
  4. protected var name:String="leo"
  5. protected[this] var hobby:String = "game"
  6. }
  7. class Student extends Person{
  8. def sayHello = println("Hello,"+name)
  9. def makeFriends(s:Student){
  10. println("my hobby is "+hobby + ",your hobby is " +s.hobby)
  11. }
  12. }
  13. // Exiting paste mode, now interpreting.
  14. <pastie>:20: error: value hobby is not a member of Student
  15. println("my hobby is "+hobby + ",your hobby is " +s.hobby)

调用父类的constructor

  1. 每个类可以有一个主constructor和任意多个辅助constructor,而每个辅助constructor的第一行都必须是调用其他辅助constructor或者是主constructor;因此子类的辅助constructor是一定不可能直接调用父类的constructor的
  2. 只能在子类的主constrctor中调用父类的constructor
  1. scala> :paste
  2. // Entering paste mode (ctrl-D to finish)
  3. class Person(val name:String,val age:Int)
  4. class Student(name:String,age:Int,var score:Double) extends Person(name,age){
  5. def this(name:String){
  6. this(name,0,0)
  7. }
  8. def this(age:Int){
  9. this("leo",age,0)
  10. }
  11. }
  12. // Exiting paste mode, now interpreting.
  13. defined class Person
  14. defined class Student

匿名内部类

  1. 在scala中匿名子类非常常见,相当于java匿名内部类
  2. 定义一个类没有名称的子类,并直接创建其对象,然后将对象的引用赋予一个变量,之后甚至可以将该匿名子类的对象传递给其他函数
  1. scala> :paste
  2. // Entering paste mode (ctrl-D to finish)
  3. class Person(protected val name:String){
  4. def sayHello = "Hello,I'm " + name
  5. }
  6. val p = new Person("leo"){
  7. override def sayHello = "Hi,I'm "+name
  8. }
  9. def greeting(p:Person{def sayHello:String}){
  10. println(p.sayHello)
  11. }
  12. // Exiting paste mode, now interpreting.
  13. defined class Person
  14. p: Person = $anon$1@628b9af5
  15. greeting: (p: Person{def sayHello: String})Unit
  16. scala> p.sayHello
  17. res5: String = Hi,I'm leo
  18. scala> greeting(p)
  19. Hi,I'm leo

抽象类

  1. 和java同样的原理
  1. scala> :paste
  2. // Entering paste mode (ctrl-D to finish)
  3. abstract class Person(val name:String){
  4. def sayHello:Unit
  5. }
  6. class Student(name:String) extends Person(name){
  7. def sayHello:Unit = println("Hello, "+name) //可以省略override
  8. }
  9. // Exiting paste mode, now interpreting.
  10. defined class Person
  11. defined class Student
  12. scala> val s = new Student("jike")
  13. s: Student = Student@49bcd90d
  14. scala> s.sayHello
  15. Hello, jike

抽象field

  1. 如果在父类中,定义了field,但是没有给出初始值,则此field为抽象field
  2. 抽象filed意味着,scala会根据自己的规则,为var或val类型的field生成对应的getter和setter方法,但是父类中没有该field的
  3. 子类必须覆盖field,以定义自己的具体field,并且覆盖抽象field,不需要使用override关键字
  1. abstract class Person{
  2. val name :String
  3. }
  4. class Student extends Person{
  5. val name :String = "leo"
  6. }
  7. scala> val s = new Student
  8. s: Student = Student@48c2391
  9. scala> s.name
  10. res9: String = leo

Spark基础-scala学习(二、面向对象)的更多相关文章

  1. Spark基础-scala学习(三、Trait)

    面向对象编程之Trait trait基础知识 将trait作为接口使用 在trait中定义具体方法 在trait中定义具体字段 在trait中定义抽象字段 trait高级知识 为实例对象混入trait ...

  2. Spark基础-scala学习(四、函数式编程)

    函数式编程 将函数赋值给变量 匿名函数 高阶函数 高级函数的类型推断 scala的常用高阶函数 闭包 sam转换 currying函数 return 将函数赋值给变量 scala中的函数是一等公民,可 ...

  3. Spark基础-scala学习(八、隐式转换与隐式参数)

    大纲 隐式转换 使用隐式转换加强现有类型 导入隐式转换函数 隐式转换的发生时机 隐式参数 隐式转换 要实现隐式转换,只要程序可见的范围内定义隐式转换函数即可.Scala会自动使用隐式转换函数.隐式转换 ...

  4. Spark基础-scala学习(七、类型参数)

    类型参数是什么 类似于java泛型,泛型类 泛型函数 上边界Bounds 下边界 View Bounds Context Bounds Manifest Context Bounds 协变和逆变 Ex ...

  5. Spark基础-scala学习(五、集合)

    集合 scala的集合体系结构 List LinkedList Set 集合的函数式编程 函数式编程综合案例:统计多个文本内的单词总数 scala的集合体系结构 scala中的集合体系主要包括:Ite ...

  6. Spark基础-scala学习(一、入门)

    Scala解析器的使用 REPL:Read(取值)-> Evaluation(求值)-> Print(打印)->Loop(循环).scala解析器也被称为REPL,会快速编译scal ...

  7. Spark之Scala学习

    1. Scala集合学习: http://blog.csdn.net/lyrebing/article/details/20362227 2. scala实现kmeans算法 http://www.t ...

  8. Scala学习(二)--- 控制结构和函数

    控制结构和函数 摘要: 本篇主要学习在Scala中使用条件表达式.循环和函数,你会看到Scala和其他编程语言之间一个根本性的差异.在Java或C++中,我们把表达式(比如3+4)和语句(比如if语句 ...

  9. Spark基础:(二)Spark RDD编程

    1.RDD基础 Spark中的RDD就是一个不可变的分布式对象集合.每个RDD都被分为多个分区,这些分区运行在分区的不同节点上. 用户可以通过两种方式创建RDD: (1)读取外部数据集====> ...

随机推荐

  1. 关于java工程打exe包的一些问题

    这两天在把一个Java project打包成exe文件时碰到了一些问题,现在把这些问题和解决办法记下来. 1.用java swing做前端时,背景图片无法显示 Solution:把jpg图片换成png ...

  2. java-包装类

    包装类存在的意义: 1.对于有些情况,我们不能使用基本数据类型,只能使用引用数据类型.这个时候使用包装类对基本数据类型进行类话来实现. 在jdk1.5前,我们必须手动将基本数据类型数据包装,1.5版本 ...

  3. mysql8 出现1521错误解决方法

    ALTER USER 'root'@'localhost' IDENTIFIED BY 'password' PASSWORD EXPIRE NEVER; #修改加密规则 ALTER USER 'ro ...

  4. composer require aliyuncs/oss-sdk-php

    composer require aliyuncs/oss-sdk-php composer install require_once __DIR__ . '/vendor/autoload.php' ...

  5. JS中的instanceof和typeof,以及特殊引用类型

    1.instanceof是用于测试对象类型,通常格式为:a instanceof b,返回true或falise,表示为对象a是否是类型b的实例. typeof则是用于测试基本类型,包括undefin ...

  6. linux下部署tomcat 上线jpress博客系统

    tomcat Tomcat服务器是一个免费的开放源代码的Web应用服务器,属于轻量级应用服务器. tomcat有三个端口 开始部署 安装tomcat 第一步:下载tomcat 安装包 tomcat官网 ...

  7. Spring Boot不同版本整合Redis的配置

    1. Spring Boot为1.4及其他低版本 1.1 POM.XML配置 <!--引入 spring-boot-starter-redis(1.4版本前)--> <depende ...

  8. fortran语言调用fortran写的dll

    环境:vs2013+IVF 2011 有时候想把fortran写的常用的函数编译为DLL,以供不同的fortran exe调用,这时候应该怎样做呢?[参考 彭国伦老师 fortran95 程序设计 书 ...

  9. golang使用 gzip压缩

    golang使用 gzip压缩 这个例子中使用gzip压缩格式,标准库还支持zlib, bz2, flate, lzw 压缩处理_三步: 1.创建压缩文件2.gzip write包装3.写入数据 ou ...

  10. mybatis批量更新报错badsql

    mybatis批量更新时语法写的都对,但是报错,需要在连接上面加上allowMultiQueries=true 示例:jdbc:MySQL://192.168.1.236:3306/test?useU ...