Scala

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 + yval f3: Int => Int = x => x + 22val 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 = printlnfunction2("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 = nameprivate var uage: Int = ageprivate 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 = driverthis.url = urlthis.user = userthis.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) connval 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) connval 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) connval 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) connval 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) connval 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) connval 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) connval 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 = driverthis.url = urlthis.user = userthis.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()}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/109819.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【算法设计与分析qwl】伪码——顺序检索,插入排序

伪代码&#xff1a; 例子&#xff1a; 改进的顺序检索 Search(L,x)输入&#xff1a;数组L[1...n]&#xff0c;元素从小到大排序&#xff0c;数x输出&#xff1a;若x在L中&#xff0c;输出x位置下标 j ,否则输出0 j <- 1 while j<n and x>L[j] do j <- j1 if x<…

【安全】网络安全态势感知

一、态势感知简介 如果你对网络安全入门感兴趣&#xff0c;那么你需要的话可以点击这里&#x1f449;【入门&进阶全套282G学习资源包免费分享&#xff01;】 1.概念 态势感知是一种基于环境的、动态、整体地洞悉安全风险的能力&#xff0c;是以 安全大数据 为基础&#…

Nginx配置微服务避免actuator暴露

微服务一般在扫漏洞的情况下&#xff0c;需要屏蔽actuator健康检查 # 避免actuator暴露 if ($request_uri ~ "/actuator") { return 403; }

Linux块设备缓存Bcache使用

1 Bcache简介 Bcache是Linux内核块层cache&#xff0c;它使用SSD来作为HDD硬盘的cache&#xff0c;从而起到加速作用。Bcache内核模块仅在Linux 3.10及以上版本支持&#xff0c;因此使用Bcache&#xff0c;需要将内核升级到3.10及以上版本&#xff0c;并在内核配置项中打开Bca…

Tortoise SVN 察看本地缓存密码

1、打开设置&#xff08;Settings&#xff09; 2、查看保存的数据 3、打开鉴权数据 4、查看密码 CTRLSHIFT双击表格&#xff0c;就会出现一列密码列 &#xff08;我的是Mac PD虚拟Win11&#xff0c;CTRLSHIFTOPTION双击表格&#xff09; 原文见这里&#xff1a; Recover SVN …

2022年03月 Python(二级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python编程(1~6级)全部真题・点这里 C/C++编程(1~8级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 关于Python中的列表,下列描述错误的是?( ) A:列表是Python中内置可变序列,是若干元素的有序集合; B:列表中的每一个数据称为“元素”; C:在…

qt-C++笔记之按行读取文件并切换复选框打印复选框拼接出的字符串

qt-C笔记之按行读取文件并切换复选框打印复选框拼接出的字符串 code review! 文章目录 qt-C笔记之按行读取文件并切换复选框打印复选框拼接出的字符串1.运行2.文件结构3.main.cc4.main.pro5.a.txt6.b.txt 1.运行 2.文件结构 3.main.cc 代码 #include <QApplication> #…

【Arduino+ESP32+腾讯云+sg90】强制门户+腾讯云控制开关灯

作者有话说 博主对于Arduino开发并没有基础&#xff0c;但是为了实现更加方便的配网&#xff0c;这几天一直在尝试用ESP32-12F&#xff08;因为手头刚好有一个&#xff0c;其他的也可以&#xff09;来做远程开关灯&#xff01;不知道大家是否注意到&#xff0c;上一篇利用STM32…

iOS——JSONModel的使用与JSONModel的嵌套

什么是JSONModel JSONModel是一个解析JSON数据的开源库&#xff0c;可以将JSON数据直接解析成自定义的model 使用 JSONModel 非常简单,只需要将你的 model 类继承自 JSONModel ,而同时 model 中的属性名又恰巧可以和 JSON 数据中的 key 名字一样的话,那么非常恭喜你,你的工作…

“滑动窗口”算法专项训练

目录 题目链接&#xff1a;长度最小的子数组 题目描述 思路分析&#xff1a;滑动窗口(利用单调性&#xff0c;使用"同向双指针来优化) 细节处理 画图解析 代码 题目链接&#xff1a;最大连续1的个数 III 题目描述 思路分析&#xff1a;滑动窗口(同向双指针) 细节…

基于openHarmony实现本地UDP通信

知识补充 简介 套接字(Socket)&#xff0c;就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端&#xff0c;提供了应用层进程利用网络协议交换数据的机制。从所处的地位来讲&#xff0c;套接字上联应用进程&#xff0c;下联…

数据挖掘(5)分类数据挖掘:基于距离的分类方法

一、分类挖掘的基本流程 最常用的就是客户评估 1.1分类器概念 1.2分类方法 基于距离的分类方法决策树分类方法贝叶斯分类方法 1.3分类的基本流程 步骤 建立分类模型 通过分类算法对训练集训练&#xff0c;得到有指导的学习、有监督的学习预定义的类&#xff1a;类标号属性确定…

【软考】6.2 网络安全技术

《网络安全技术》 防火墙 一道大门&#xff0c;隔离内网和外网主要分隔外网的威胁&#xff0c;对内网的直接攻击无能为力 入侵检测系统&#xff08;IDS&#xff09; 位于防火墙后的第二道屏障监听设备&#xff1a;监控当前系统 / 用户行为&#xff0c;无需网络流量即可工作尽…

6.7 案例分析与实现

思维导图&#xff1a; 6.7 案例分析与实现 #### 案例6.2: 六度空间理论 【案例分析】 - **背景介绍**&#xff1a; 六度空间理论提及在任意两人之间最多仅有6个人的连接。尽管这一理论被广泛提及并得到了某种程度的验证&#xff0c;但从科学角度看&#xff0c;它仍然只是一…

214. Devu和鲜花

214. Devu和鲜花 - AcWing题库 如果每个盒子里的花的数量是无限的&#xff0c;用隔板法可以得出答案是 现在每个盒子中区的花数要满足n个条件 我们可以求答案的补集&#xff0c;用全部方案数减去补集方案数 每一个不符合条件的要求为&#xff0c;设为Bi 补集方案数为就成了…

7.MidBook项目经验之阿里OSS,微信支付(退款),定时任务,图表数据处理

1.阿里云实名认证 阿里云对象存储oss,标准高频率访问, 低频访问存储,归档存储(根本不经常访问) 冗余存储(备份) 读写权限(所有人还是自己访问) Component public class ConstantOssPropertiesUtils implements InitializingBean {不用注入,由spring创建bean使用流 MultipartFil…

【Mac】时间机器频繁提示磁盘没有正常推出

问题描述 有一次在进行时间机器备份的时候总是提示“磁盘没有正常推出”&#xff0c;并且好几次直接导致系统重启… 估计是 MacOS 系统 bug 解决 看了 Vex 一个帖子之后设置了一个硬盘是否休眠就好了&#xff0c;不要勾选让硬盘处于休眠就可以了&#xff0c;在电池选项界面中…

MySQL 8.0 OCP认证精讲视频、环境和题库之五 事务、缓存

redo log buffer&#xff1a; 缓存与事务有关的redo log ,用来对mysql进行crash恢复&#xff0c;不可禁用&#xff1b; 日志缓冲区是存储要写入磁盘上日志文件的数据的内存区域。日志缓冲区大小由innodb_Log_buffer_size变量定义。 默认大小为16MB。日志缓冲区的内容会定…

QTday02(常用类、UI界面下的开发、信号与槽)

今日任务 1. 使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 将登录按钮使用qt5版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admin"&#x…

v-model表单数据双向绑定-表单提交示例

示例如下&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>v-model表单数据双向绑定<…