Scala

目录

1.scala安装

2.scala入门

3.变量和数据类型

4. 流程控制

5.集合

6.函数

7.模式匹配

8.隐式转换

9. 面向对象

10. 泛型

11.Scala连接Mysql数据库


1.scala安装

下载scala安装包,默认下一步,完成后cmd验证

Idea安装scala插件

在项目上,点击右键-> Add Framework Support... ->选择Scala->点击OK

更改环境,项目结构->项目/模块->

2.scala入门

概述

Scala将面向对象和函数式编程结合成一种简洁的高级语言。Scala的静态类型有助于避免复杂应用程序中的错误,它的JVM和JavaScript运行时让你可以轻松地访问庞大的库生态系统来构建高性能系统。

3.变量和数据类型

4. 流程控制

分支控制if-else

范围数据循环(To Until)  循环步长by

 

循环中断

Scala内置控制结构特地去掉了break和continue,是为了更好的适应函数式编程,推荐使用函数式的风格解决break和continue的功能,而不是一个关键字。Scala中使用breakable控制结构来实现break和continue功能。

循环守卫

(1)循环守卫,即循环保护式(也称条件判断式,守卫)。保护式为true则进入循环体内部,为false则跳过,类似于continue。

循环返回值yield(不推荐使用)

将遍历过程中处理的结果返回到一个新Vector集合中,使用yield关键字。

5.集合

集合简介

       1)Scala的集合有三大类:序列Seq、集Set、映射Map,所有的集合都扩展自Iterable特质。

2)对于几乎所有的集合类,Scala都同时提供了可变不可变的版本,分别位于以下两个包。

不可变集合:scala.collection.immutable

可变集合:  scala.collection.mutable

       3)Scala不可变集合,就是指该集合对象不可修改,每次修改就会返回一个新对象,而不会对原对象进行修改。类似于java中的String对象

4)可变集合,就是这个集合可以直接对原对象进行修改,而不会返回新的对象。类似于java中StringBuilder对象

建议:在操作集合的时候,不可变用符号,可变用方法

不可变集合继承图

1)Set、Map是Java中也有的集合

2)Seq是Java没有的,我们发现List归属到Seq了,因此这里的List就和Java不是同一个概念了

3)我们前面的for循环有一个 1 to 3,就是IndexedSeq下的Range

4)String也是属于IndexedSeq

5)我们发现经典的数据结构比如Queue和Stack被归属到LinearSeq(线性序列)

6)大家注意Scala中的Map体系有一个SortedMap,说明Scala的Map可以支持排序

7)IndexedSeq和LinearSeq的区别:

(1)IndexedSeq是通过索引来查找和定位,因此速度快,比如String就是一个索引集合,通过索引即可定位

(2)LinearSeq是线型的,即有头尾的概念,这种数据结构一般是通过遍历来查找

可变集合继承图

数组

Scala 数组、集合函数大全

Scala 数组、集合函数大全-CSDN博客

mkString()

1.添加类函数

++  合并集合,并返回一个新的数组,新数组包含左右两个集合的内容

++:  这个方法同上一个方法类似,两个加号后面多了一个冒号,但是不同的是右边操纵数的类型决定着返回结果的类型

+:  在数组前面添加一个元素,并返回新的数组对象

:+  在数组后面添加一个元素,并返回新的数组对象

2.生成类函数

clone 创建一个副本

collect 在序列中查找第一个符合偏函数定义的元素,并执行偏函数计算

combinations 表示组合,这个排列组合会选出所有包含字符不一样的组合,但不考虑顺序,对于 “abc”、“cba”,视为相同组合,参数 n 表示序列长度,就是几个字符为一组

copyToArray(arr, start)  将当前数组元素复制到另一个数组中,从 start 位置开始复制

copyToBuffer  将数组中的元素复制到 Buffer 中

permutations 表示排列,这个排列组合会选出所有排列顺序不同的字符组合, permutations 与 combinations 不同的是,相同的组合考虑排列,对于 “abc”、“cba”,视为不同的组合

3.删除类函数

drop 将当前数组中前 n 个元素去除,返回一个新数组

dropWhile  去除当前数组中符合条件的元素,返回剩余的数组,这个需要一个条件,就是从当前数组的第一个元素起,就要满足条件,直到碰到第一个不满足条件的元素结束(即使后面还有符合条件的元素),否则返回整个数组

4.查找类函数

find 查找第一个符合条件的元素,返回 Option

filter 查找第符合条件的元素,返回array数组

lastIndexOf(elem)  返回元素 elem 在序列中最后一次出现的索引

lastIndexOfSlice(that)  检测当前序列中是否包含序列 that,并返回最后一次出现该序列的索引

IndexOfSlice(that)  检测当前序列中是否包含序列 that,并返回第一次出现该序列的索引

lastIndexWhere§  返回当前序列中最后一个满足条件 p 的元素的索引

lastOption  返回序列的最后一个元素的 Option 类型对象,如果序列为空,则返回 None

segmentLength  从序列的 from (包含)开始向后查找,返回满足条件 p 的连续元素的长度,不满足条件直接退出,返回长度(可以为0)

5.统计类函数

count  统计符合条件的元素个数

max  返回序列中最大的元素

maxBy  返回序列中符合条件的第一个元素

product  返回所有元素乘积的值

sum  序列求和,元素需为 Numeric[T] 类型

6.修改类函数

updated  将序列中 i 索引处的元素更新为 x,并返回替换后的数组

update  将序列中 i 索引处的元素更新为 x,原地操作

patch  批量替换,从原序列的 from 处开始,后面的 replaced 个元素,将被替换成序列 that

7.判断类函数

contains  判断序列中是否包含指定对象,返回boolean

containsSlice  判断当前序列中是否包含另一个序列

endsWith  判断当前序列是否以某个序列结尾

exists  判断当前数组是否包含符合条件的元素

isDefinedAt  判断序列中是否存在指定索引

isEmpty  判断序列是否为空

nonEmpty  判断序列是否不为空

isTraversableAgain  判断序列是否可以反复遍历,该方法是 GenTraversableOnce 中的方法,对于 Traversables 一般返回 true,对于 Iterators 返回 false,除非被复写

forall  检测序列中的元素是否都满足条件 p,如果序列为空,则返回 true

sameElements  判断两个序列是否顺序和对应位置上的元素都一样

startsWith(that)  判断序列是否以某个序列开始

startsWith(that, offset)  判断序列从指定偏移处是否以某个序列开始

hasDefiniteSize  检测序列是否存在有限的长度,对应 Stream 这样的流数据则返回 false

corresponds  判断两个序列的长度以及对应位置元素是否符合某个条件。如果两个序列具有相同的元素数量并且

8.获取集合元素

apply  获取指定索引处的元素

charAt  获取 index 索引处的字符,这个方法会执行一个隐式的转换,将 Array[T] 转换为 ArrayCharSequence,只有当 T 为 Char 类型时,这个转换才会发生

foreach  遍历序列中的元素,进行 f 操作

head  返回序列的第一个元素,如果序列为空,将引发错误

headOption  返回序列的第一个元素的 Option 类型对象,如果序列为空,则返回 None

init  返回当前序列中不包含最后一个元素的序列

inits  对集合中的元素进行 init 迭代操作,该操作的返回值中, 第一个值是当前序列的副本,最后一个值为空,每一步都进行 init 操作,上一步的结果作为下一步的操作对象

tail  返回当前序列中不包含第一个元素的序列

tails  同 inits,每一步都进行 tail 操作

take  返回当前序列中,前 n 个元素组成的序列

takeRight  返回当前序列中,从右边开始,后 n 个元素组成的序列

takeWhile  返回当前序列中,从第一个元素开始,满足条件的连续元素组成的序列

view  返回当前序列中从 from 到 until 之间的序列,不包括 until 处的元素

9.集合操作类函数

filter  取得当前数组中符合条件的元素,组成新的数组返回

filterNot  取得当前数组中不符合条件的元素,组成新的数组返回

withFilter  根据条件 p 过滤元素,如果后续的操作需要使用到map/flatMap/withFilter,推荐使用,这样可以减少filter产生的中间collection,使得执行更加高效

reverse  反转序列

reverseIterator  生成反向迭代器

partition  按条件将序列拆分成两个数组,满足条件的放到第一个数组,其余的放到第二个数组,返回的是包含这两个数组的元组

groupBy  按条件分组,条件由 f 匹配,返回值是 Map 类型,每个 key 对应一个数组

grouped  按指定数量分组,每组有 size 个元素,返回一个迭代器

sortBy  按指定的排序规则对序列排序

sorted  使用默认升序排序

slice  返回当前序列中索引从 from 到 until 之间的序列,不包括 until 处的元素

sliding(size)  滑动,从第一个元素开始,每个元素和它后面的 size - 1 个元素组成一个数组,最终组成一个新的集合返回,当剩余元素个数不够 size 时,则结束

span  将序列拆分成两个数组,从第一个元素开始,直到第一个不满足条件的元素为止,其中的元素放到第一个数组,其余的放到第二个数组,返回的是包含这两个数组的元组

subsequence  返回 start 和 end 间的字符序列,不包含 end 处的元素

10.转换类函数

flatMap  对当前序列的每个元素进行操作,结果放入新序列返回,参数要求是 GenTraversableOnce 及其子类,即返回可迭代的集合

flatten  扁平化,将二维数组的所有元素组合在一起,形成一个一维数组返回(没有参数可传,不可操作)

iterator  生成当前序列的迭代器

map  对序列中的元素进行 f 操作,返回生成的新序列,并且能够对结构进行调整

reverseMap  同 map,方向相反

seq  产生一个引用当前序列的 sequential 视图

unzip  将含有两个二元组的数组,每个元组的第一个元素组成一个数组,第二个元素组成一个数组,返回包含这两个数组的元组

unzip3  将含有三个三元组的数组,每个元组的第一个元素组成一个数组,第二个元素组成一个数组,第三个元素组成一个数组,返回包含这三个数组的元组

zipWithIndex  序列中的每个元素和它的索引组成一个元组数组

11.工具类函数

addString(b)  将数组中的元素逐个添加到 StringBuilder 中

distinct  去除当前集合中重复的元素,只保留一个

indices  返回当前序列索引集合

padTo  填充序列,如果当前序列长度小于 len,那么新产生的序列长度是 len,多出的几个位值填充 elem,如果当前序列大于等于 len ,则返回当前序列,并不会截取当前序列

prefixLength  给定一个条件 p,返回一个前置数列的长度,这个数列中的元素都满足 p

lengthCompare  比较序列的长度和参数 len,返回:序列的长度 length- 参数len

stringPrefix  返回 toString 结果的前缀

12.集合内与集合间计算函数

/:  对数组中所有的元素从左向右遍历,进行相同的迭代操作,foldLeft 的简写,如果是两个集合,则会将 B 先进行累加聚合(foldLeft、foldRight  :\  、fold)

reduce  不需要初始值,在集合内部进行聚合运算

reduceLeft  同 foldLeft,从左向右计算,不需要初始值

reduceRight  同 foldRight,从右向左计算,不需要初始值

reduceLeftOption  同 reduceLeft,返回 Option

scan  同 fold,scan 会把每一步的计算结果放到一个新的集合中返回,而 fold 返回的是最后的结果

aggregate  聚合计算,aggregate 是柯里化方法,参数是两个方法

   

diff  计算当前数组与另一个数组的差集,即将当前数组中没有在另一个数组中出现的元素返回

intersect  取两个集合的交集

union  合并两个序列,同操作符 ++

zip  将两个序列对应位置上的元素组成一个元组数组,要求两个序列长度相同

zipAll  同 zip ,但是允许两个序列长度不同,不足的自动填充,如果当前序列短,不足的元素填充为 thisElem,如果 that 序列短,填充为 thatElem

def zipAll[B](that: collection.Iterable[B], thisElem: A, thatElem: B): Array[(A, B)]

元组

元组也是可以理解为一个容器,可以存放各种相同或不同类型的数据。说的简单点,就是将多个无关的数据封装为一个整体,称为元组。

注意:元组中最大只能有22个元素。

 

Seq集合(List)

(1)List默认为不可变集合

(2)创建一个List(数据有顺序,可重复)

(3)遍历List

(4)List增加数据

(5)集合间合并:将一个整体拆成一个一个的个体,称为扁平化

(6)取指定数据

(7)空集合Nil

可变ListBuffer

1)说明

(1)创建一个可变集合ListBuffer

(2)向集合中添加数据

(3)删除元素

(4)查看修改元素

Set集合

默认情况下,Scala使用的是不可变集合,如果你想使用可变集合,需要引用 scala.collection.mutable.Set 包

不可变Set

1)说明

(1)Set默认是不可变集合

(2)数据无序不可重复

(3)默认使用hash set

可变mutable.Set

1)说明

(1)创建可变集合mutable.Set

(2)集合添加元素

(3)删除数据

Map集合

Scala中的Map和Java类似,也是一个散列表,它存储的内容也是键值对(key-value)映射

不可变Map

1)说明

(1)创建不可变集合Map

(2)循环打印

(3)读取数据

可以使用自定义模式匹配实现获取值

可变Map

1)说明

(1)创建可变集合

(2)向集合增加数据

(3)修改数据

(4)删除数据

6.函数

函数

递归:一个函数/方法在函数/方法体内又调用了本身,我们称之为递归调用

1. 调用自身

2. 跳出条件

3. 填入的参数必须有规律

4. 递归必须声明函数返回值类型

*指定未知长度的参数

匿名函数

1)说明

没有名字的函数就是匿名函数。

(x:Int)=>{函数体}

x:表示输入参数类型;Int:表示输入参数类型;函数体:表示具体代码逻辑

传递匿名函数至简原则:

1)参数的类型可以省略,会根据形参进行自动的推导

2)类型省略之后,发现只有一个参数,则圆括号可以省略;其他情况:没有参数和参数超过1的永远不能省略圆括号。

3)匿名函数如果只有一行,则大括号也可以省略

4)如果参数只出现一次,则参数省略且后面参数可以用_代替

def main(args: Array[String]): Unit = {

    val f0: (Int, Int) => Int = (x: Int, y: Int) => x + y


    //    (1)参数的类型可以省略,会根据形参进行自动的推导

    val f1: (Int, Int) => Int = (x, y) => x + y


    //    (2)类型省略之后,发现只有一个参数,则圆括号可以省略;

    //    其他情况:没有参数和参数超过1的永远不能省略圆括号。

    val f2: (Int, Int) => Int = (x, y) => x + y

    val f3: Int => Int = x => x + 22


    val f4: () => Int = () => 10



    //    (3)匿名函数如果只有一行,则大括号也可以省略

    val f5: (Int, Int) => Int = (x, y) => {

      println("匿名函数")

      x + y

    }


    //    (4)如果参数只出现一次,则参数省略且后面参数可以用_代替

    val f6: (Int, Int) => Int = _ + _



    // 化简为_的条件

    // 1. 传入的参数类型可以推断 所以可以省略

    val f7: (Int, Int) => Int = (x, y) => y - x


    // 2. 参数必须只使用一次  使用的顺序必要和定义的顺序一样

    val f8: (Int, Int) => Int = -_ + _



    // 如果化简为匿名函数  只剩下一个_  则不可以化简

    val function: String => String = _ + ""

    val str: String = function("linhai")

    val function1: String => String = a => a



    // 如果化简的下划线在函数里面  也会报错

//    val function1: String => Unit = println(_ + "hi")


    val function2: String => Unit = println

    function2("linhai")

   

}

函数高阶用法

1)函数可以作为值进行传递

2)函数可以作为参数进行传递

3)函数可以作为函数返回值返回

函数柯里化&闭包

闭包:函数式编程的标配

1)说明

闭包:如果一个函数,访问到了它的外部(局部)变量的值,那么这个函数和他所处的环境,称为闭包

函数柯里化:把一个参数列表的多个参数,变成多个参数列表。

collect必须传偏函数

map方法遍历数组元素(偏函数非必须)

filter过滤

部分函数

7.模式匹配

模式匹配

Scala中的模式匹配类似于Java中的switch语法

match模式匹配

  

模式守卫

如果想要表达匹配某个范围的数据,就需要在模式匹配中增加条件守卫。

样例类  匹配

数组匹配

8.隐式转换

隐式解析机制

1)说明

(1)首先会在当前代码作用域下查找隐式实体(隐式方法、隐式类、隐式对象)。(一般是这种情况)

(2)如果第一条规则查找隐式实体失败,会继续在隐式参数的类型的作用域里查找。类型的作用域是指与该类型相关联的全部伴生对象以及该类型所在包的包对象

隐式参数

普通方法或者函数中的参数可以通过implicit关键字声明为隐式参数,调用该方法时,就可以传入该参数,编译器会在相应的作用域寻找符合条件的隐式值。

1)说明

(1)同一个作用域中,相同类型的隐式值只能有一个

(2)编译器按照隐式参数的类型去寻找对应类型的隐式值,与隐式值的名称无关。

(3)传参优先于隐式参数优先于默认参数

隐式函数

1)说明

       隐式转换可以在不需改任何代码的情况下,扩展某个类的功能。

隐式类

在Scala2.10后提供了隐式类,可以使用implicit声明类,隐式类的非常强大,同样可以扩展类的功能,在集合中隐式类会发挥重要的作用。

1)隐式类说明

(1)其所带的构造参数有且只能有一个

(2)隐式类必须被定义在“类”或“伴生对象”或“包对象”里,即隐式类不能是顶级的

9. 面向对象

类和对象

//伴生类
class Oop1(name: String, age: Int) { //主构造函数
  println("----------伴生类oop1 one-----------")
 
  private var uname: String = name
  private var uage: Int = age
  private var uaddress: String = "jsnj"

  //无参构造函数
  def this() {
    this("zs", 5) //this调用主构造函数
    println("----------oop 无参构造方法----------")
  }

  //单参构造函数
  def this(name: String) {
    this(name, 5)
    println("----------oop 单参构造方法----------")
  }

  //三参构造函数
  def this(name: String, age: Int, address: String) {
    this(name, age)
    this.uaddress = "jsnj"
    println("----------oop 三参构造方法----------")
  }


  def showInfo(): Unit = {
    println("name: " + uname + " age: " + uage + " address: " + uaddress)
    Oop1.showInfo()//直接调用伴生对象中的成员方法
  }

  println("----------伴生类oop1 two-----------")

}

//伴生对象
object Oop1 {

  println("----------伴生对象oop1 one-----------")

  private val country: String = "China"

  def apply(name: String, age: Int): Oop1 = new Oop1(name, age)

  def apply(name: String): Oop1 = new Oop1(name)

  def apply(): Oop1 = new Oop1()

  def showInfo(): Unit = {
    println("------------oop object-------------")
  }

  def main(args: Array[String]): Unit = {
    println("----------执行main方法 start-----------")
    val oop1Object = new Oop1()
    val oop1Object2 = Oop1()  //apply方法,简易创建对象
    val oop1Object3 = Oop1("zs")
    val oop1Object4 = Oop1("zs", 5)
    val oop1Object5 = new Oop1("wangwu")

    oop1Object.showInfo()
    oop1Object5.showInfo()

    Oop1.country    //成员变量
    Oop1.showInfo() //成员方法

    println("----------执行main方法 stop-----------")
  }
  println("----------伴生对象oop1 two-----------")
}

构造器

和Java一样,Scala构造对象也需要调用构造方法,并且可以有任意多个构造方法。

Scala类的构造器包括:主构造器和辅助构造器

1)基本语法

class 类名(形参列表) {  // 主构造器

   // 类体

   def  this(形参列表) {  // 辅助构造器

   }

   def  this(形参列表) {  //辅助构造器可以有多个...

   }

}

说明:

1)辅助构造器,函数的名称this,可以有多个,编译器通过参数的个数及类型来区分。

2)辅助构造方法不能直接构建对象,必须直接或者间接调用主构造方法。

3)构造器调用其他另外的构造器,要求被调用构造器必须提前声明。

2)案例实操

(1)如果主构造器无参数,小括号可省略,构建对象时调用的构造方法的小括号也可以省略。

apply

样例类

继承

特质(Trait)

Scala语言中,采用特质trait(特征)来代替接口的概念,也就是说,多个类具有相同的特质(特征)时,就可以将这个特质(特征)独立出来,采用关键字trait声明。

Scala中的trait中即可以有抽象属性和方法,也可以有具体的属性和方法一个类可以混入(mixin)多个特质。这种感觉类似于Java中的抽象类。

Scala引入trait特征,第一可以替代Java的接口,第二个也是对单继承机制的一种补充。

 

10. 泛型

协变和逆变

1)语法

class MyList[+T]{ //协变

}

class MyList[-T]{ //逆变

}

class MyList[T] //不变

2)说明

协变:Son是Father的子类,则MyList[Son] 也作为MyList[Father]的“子类”

逆变:Son是Father的子类,则MyList[Son]作为MyList[Father]的“父类”

不变:Son是Father的子类,则MyList[Father]与MyList[Son]“无父子关系”

泛型上下限

1)语法

Class PersonList[T <: Person]{ //泛型上限

}

Class PersonList[T >: Person]{ //泛型下限

}

2)说明

         泛型的上下限的作用是对传入的泛型进行限定。

上下文限定

1)语法

def f[A : B](a: A) = println(a) //等同于def f[A](a:A)(implicit arg:B[A])=println(a)

2)说明

上下文限定是将泛型和隐式转换的结合产物,以下两者功能相同,使用上下文限定[A : Ordering]之后,方法内无法使用隐式参数名调用隐式参数,需要通过implicitly[Ordering[A]]获取隐式变量,如果此时无法查找到对应类型的隐式变量,会发生出错误。

implicit val x = 1

val y = implicitly[Int]

val z = implicitly[Double]

11.Scala连接Mysql数据库

1.pom依赖

<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>8.0.29</version>
</dependency>

2.普通连接

连接、增删改查API

import java.sql.{Connection, DriverManager, PreparedStatement, ResultSet}

class MysqlDemo {
  var driver = "com.mysql.cj.jdbc.Driver"
  var url = "jdbc:mysql://192.168.142.129:3306"
  var user = "root"
  var pwd = "123456"

  var connection: Connection = _

  def this(driver: String, url: String, user: String, pwd: String) {
    this()
    this.driver = driver
    this.url = url
    this.user = user
    this.pwd = pwd
  }

  def conn: Connection = {
    Class.forName(driver)
    connection = DriverManager.getConnection(url, user, pwd)
    connection
  }

  def insert(): Int = {
    val insertSql = "INSERT INTO kb23.student VALUES(2,'lisi',22)"
    if (connection == null) conn
    val i = connection.createStatement().executeUpdate(insertSql)
    i
  }

  def insert(id: Int, name: String, age: Int): Int = {
    var insertSql = "INSERT INTO kb23.student VALUES(?,?,?)"
    if (connection == null) conn
    val pstm: PreparedStatement = connection.prepareStatement(insertSql)
    pstm.setInt(1, id)
    pstm.setString(2, name)
    pstm.setInt(3, age)
    val i = pstm.executeUpdate()
    i
  }

  def update(id: Int, name: String): Int = {
    var updateSql = "UPDATE kb23.student SET name = ? WHERE id = ?"
    if (connection == null) conn
    val pstm: PreparedStatement = connection.prepareStatement(updateSql)
    pstm.setString(1, name)
    pstm.setInt(2, id)
    val i = pstm.executeUpdate()
    i
  }

  def select():Unit = {
    val selectSql = "SELECT * FROM kb23.student"
    if (connection == null) conn
    val stuSet: ResultSet = connection.createStatement().executeQuery(selectSql)
    while (stuSet.next()){
      val id = stuSet.getInt("id")
      val name = stuSet.getString("name")
      val age = stuSet.getInt("age")
      println("学号:%d 姓名:%s 年龄: %d".format(id,name,age))
    }
  }

  def select(name:String): Unit = {
    val selectSql = "SELECT * FROM kb23.student where name like concat('%',?,'%')"
    if (connection == null) conn
    val pstm: PreparedStatement = connection.prepareStatement(selectSql)
    pstm.setString(1, name)
    val stuSet = pstm.executeQuery()
    while (stuSet.next()) {
      val id = stuSet.getInt("id")
      val name = stuSet.getString("name")
      val age = stuSet.getInt("age")
      println("学号:%d 姓名:%s 年龄: %d".format(id, name, age))
    }
  }
}

object MysqlDemo {
  def main(args: Array[String]): Unit = {
    val demo = new MysqlDemo()
    //val conn = demo.conn
    //println(conn)

    //val i = demo.insert()
    //val i = demo.insert(3, "wangwu", 23)
    //println(i)

    //val i = demo.update(3, "hhh")
    //println(i)

    //demo.select()

    demo.select("z")
  }
}

3.通过工具object操作

(1)object Utils(具体连接、增删改查)

import java.sql.{Connection, DriverManager, PreparedStatement, ResultSet}

object MysqlUtils {
  implicit class Mysqlop(mysqlDemo2: MysqlDemo2){
    private var connection: Connection = _

    private def conn: Unit = {
      Class.forName(mysqlDemo2.driver)
      connection =
        DriverManager.getConnection(mysqlDemo2.url, mysqlDemo2.user, mysqlDemo2.pwd)
    }

    def insert(id: Int, name: String, age: Int): Int = {
      var insertSql = "INSERT INTO kb23.student VALUES(?,?,?)"
      if (connection == null) conn
      val pstm: PreparedStatement = connection.prepareStatement(insertSql)
      pstm.setInt(1, id)
      pstm.setString(2, name)
      pstm.setInt(3, age)
      val i = pstm.executeUpdate()
      i
    }
  }

  implicit class MysqlSelect(mysqlDemo2: MysqlDemo2) {
    private var connection: Connection = _

    private def conn: Unit = {
      Class.forName(mysqlDemo2.driver)
      connection =
        DriverManager.getConnection(mysqlDemo2.url, mysqlDemo2.user, mysqlDemo2.pwd)
    }

    def select(): Unit = {
      val selectSql = "SELECT * FROM kb23.student"
      if (connection == null) conn
      val stuSet: ResultSet = connection.createStatement().executeQuery(selectSql)
      while (stuSet.next()) {
        val id = stuSet.getInt("id")
        val name = stuSet.getString("name")
        val age = stuSet.getInt("age")
        println("学号:%d 姓名:%s 年龄: %d".format(id, name, age))
      }
    }
  }

  implicit class MysqlUpdate(mysqlDemo2: MysqlDemo2) {
    private var connection: Connection = _
    def connect(): Unit = {
      Class.forName(mysqlDemo2.driver)
      connection = DriverManager.getConnection(mysqlDemo2.url,mysqlDemo2.user,mysqlDemo2.pwd)
    }

    def update(id: Int, name: String): Int = {
      var updateSql = "UPDATE kb23.student SET name = ? WHERE id = ?"
      val pstm: PreparedStatement = connection.prepareStatement(updateSql)
      pstm.setString(1, name)
      pstm.setInt(2, id)
      val i = pstm.executeUpdate()
      i
    }
  }
}

(2)常量、main方法

class MysqlDemo2 {
  var driver = "com.mysql.cj.jdbc.Driver"
  var url = "jdbc:mysql://192.168.142.129:3306"
  var user = "root"
  var pwd = "123456"

  def this(driver: String, url: String, user: String, pwd: String) {
    this()
    this.driver = driver
    this.url = url
    this.user = user
    this.pwd = pwd
  }
}

object MysqlDemo2 {
  def main(args: Array[String]): Unit = {

    import nj.zb.kb23.mysqlstu.MysqlUtils._

    val demo = new MysqlDemo2()
    val i = demo.insert(4, "zhaoliu", 18)
    println(i)
    demo.select()
  }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值