函数式接口: 概念,有且仅有一个抽象方法的接口(Object类中的抽象方法不算),当然它还可以包含其他的方法(默认,静态,私有)。
@FunctionalInterface 注解 它可以检测该接口是不是函数式接口。
常用的函数式接口:
Supplier<T>接口包含一个无参的方法:T get()用来获取一个泛型参数指定类型的对像数据。这个接口被称为生产型接口,指定接口的泛型是什么类型那么接口中get()方法就会生产什么类型的数据。
Consumer接口中包含抽象方法void accept(T t),意为指定什么类型的数据就消费什么类型的数据。。
对应生产型接口,还有一个消费型接口。 Consumer接口,泛型指定什么类型,就可以使用accept方法消费什么类型的数据。至于怎么消费(使用),需要自定义(输出,计算。。。)
Consumer接口中的默认方法 andThen
作用需要两个Consumer接口,可以把两个Consumer接口组合在一起,在对数据进行消费
例如:Consumer<String> con1
Consumer<String> con2
String s="hello";
con1.accept(s);
con2.accept(s);
连接两个Consumer接口 在进行消费
con1.andThen(con2).accept(s);谁写在前面谁先消费。两种写法是等价的。
Predicate<T>接口,对某种数据类型进行判断,返回一个布尔值。
使用Predicate中的抽象方法 test(T t):用来对指定数据类型数据进行判断的方法。
Predicate接口的默认方法and(就是与),or(或)。negate(非)
调用and的时候的写法per1.and(per2).test(String str);
它相当于per1.test(String str)&&per2.test(String str);
or和nagate的用法和and类似。
per1.or(per2).test(String str);
!per.test(String str)等价于 per.negate.test(String str);
Function 转换元素<T,R> 把一个类型的数据,通过转换编程另外一个类型的数据。
Function中的莫认方法 andThen:用来进行组合操作。
需求:把String类型的数据转换成int类型的数据,然后+10后再转换成String
分析:转换了两次。第一次:我们使用Function<String,Integer>fun1
Integer i=fun1.apply(“123”)+10;
第二次:是把Integer类型转换为String类型
所以我们可以使用function<Integer,String>fun2
String s=fun2.apply(i)。
我们可以用andThen方法把两次转换组合在一起使用
String s=fun1.andThen(fun2).apply(“123”)
自定义函数模型拼接:
分析:第一步 将字符串截取年龄部分,得到字符串
第二步 将上一步得到字符串转换为int类型的数字
第三步 将上一步得到的int数字累加100,得到结果int数字。
Stream流是JAVA1.8之后才出现的,它关注的是做什么,而不是怎么做。
JAVA中的stream不会储存元素,只会按需进行计算。
stream操作有两个基本操作:
1、Pipelining:中间的操作都会返回流对象本身,这样就可以串联成一个管道。也就是它是可以链式编程的。
2、内部迭代。
两种获取Stream流的方式:
单列集合可以直接用 Collections.Stream(参数) 参数可以传Collection的集合
双列集合Map可以间接的用keySet和entrySet来获取流
还可以直接用Stream中的方法Static <T> Stream<T> of(T... values) 参数数可变参数,可以传一个数组。
Stream流中的一些常用方法:它的方法分为延迟方法和终结方法。延迟方法返回值类型任然是Stream接口自身类型的方法。终结方法,返回值类型不是Stream接口类型自身,它就不能在进行链式编程了。
forEach方法:它是一个终结方法,遍历之后就能在用Stream中其他方法了。它其实就是Stream流中遍历数据的方法。
filter方法(过滤):这不是一个终结方法,它可以将一个流转换为另外一个子集流。
这个方法的底层其实就是 predicate,用它的抽象方法 boolean test(T t);
注意: stream流是一个管道流,只能被消费一次。只能使用一次,用了之后数据就交给下一个了,就是数据流向下一个地方了。
map 映射:如果需要将流中的元素映射成另外一个流中,就是可以用到map(映射)方法。该接口需要一个Function函数式接口参数,可以将当前流中的T类型的数据转换为另外一种类型的数据。
R apply(T t);
long count(); 方法:是用来计数的方法,是用来统计Stream流中元素个数的方法。返回值是一个long类型的整数,这是一个终结方法,后面不能再调用Stream的方法。
常用方法Stream<T> limit(long maxSize):这是一个延迟方法。他是从头截取数据,截取的个数是我们传递的参数。最后它后返回一个新的流,所以在他后边可以调用Stream中的其他方法。
Stream<t> skip(long nu):是跳过的意思,传入的参数是多少就跳过多少个,获得后边的数据。
Static<T> Stream<T> concat(Stream<> a,Stream<> b):是拼接的意思。可以将两个流拼接为一个Stream流。
方法引用(::):
就是用来简化Lambda表达式的。
关于方法引用,lambda表达式的目的,打印参数传递的字符串,把参数s,传递给了System.out对象,调用out对象中的方法println对字符串进行了输出,注意:1、system。out对象已经存在 2、println方法也是已经存在的,就可以用方法引用。
类是已知的,方法也是已知的话,我们可以用方法引用的方式。如果这个方法是非静态方法,那么就要创建对象,然后用引用的方式来调用方法,如果方法是静态方法那么可以直接用 类名称::方法名称,不用再创建对象。
Junit单元测试:分为白盒测试和黑盒测试
白盒测试:就是需要写一些逻辑代码的测试,要关注程序的具体运行流程。
黑盒测试:就是什么都不写,不用给输入值,直接运行看是否输出期望值。
白盒测试的使用步骤:
1、定义一个测试类(测试用例):建议 测试类名:被测试的类名Test calculatorTest
包名:xxxxx.xx.x.test cn.itcast.test
2、定义测试方法:可以独立运行
建议:1、方法名:test的方法名 testAdd
2、 返回值 void
3、参数 空参
3、给方法加@Test
4、导入junit的依赖环境
一般我们不会打印输出,我们会用断言的操作。
断言 Assert.assertEquals(期望的值,实际的值)。这个方法就是判断期望值和实际值是否一致。
@Before方法:初始化方法。用于资源申请,所有测试方法在执行前都会先执行该方法,在前面加上注解 @Before就可以了
@After方法:释放资源,在所有测试方法执行完了之后都会执行该方法,不管前面的方法是否报错,就可以在方法上面加上注解@Before
反射:框架设计的灵魂
什么是框架呢:就是半成品软件,可以在框架的基础上进行软甲的开发,简化代码。
反射的概念:就是将类的各个组成部分封装成其他对象,这就是反射机制。反射封装的三个重要的对象:成员变量 Filed[]fields 构造方法 Constructor[] cons 成员方法 Method[]methods
反射的好处:
1、可以在程序的运行过程中操作对象。
2、可以解耦,提高程序的可扩展性。
反射:获取字节码class对象的三种方式。
1、Class.forName("全类名") 将字节码文件加载进内存返回class对象。参数传全类名,就是包名+类名。 这种方法多用于配置文件,将类名定义在配置文件中。读取文件,加载类
2、类名.Class:通过类名的属性class获取。 多用于参数传递
3、对象.getClass():getClass()在Object类中定义。 多用于对象的获取字节码的方式。
注意:同一个字节码文件(*.class)在一次程序运行中,只会被加载一次,无论我们是用的哪种方式获得的class的对象都是同一个。
class对象的功能:
获取的功能
1:获取成员变量们
Field[] getfields() 获取所有的成员变量。获取public修饰的成员变量
Field getField(String name) 返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。获取指定名称的public修饰的成员变量
Field getDeclaredField(String name)返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。 不考虑修饰符
Field[] getDeclaredFields() 返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。 不考虑修饰符
2、获取构造方法们
Constructor<T> getConstructor(Class<?>... parameterTypes) 返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。
Constructor<?>[] getConstructors() 返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。
Constructor<?>[] getDeclaredConstructors() 返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法。
3、获取成员方法们
Method getMethod(String name, Class<?>... parameterTypes)返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。
Method[] getMethods() 返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。
Method getDeclaredMethod(String name, Class<?>... parameterTypes) 返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。
Method[] getDeclaredMethods() 返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
4、获取类名
String getName()
类对象名称.getName()
当我们获取到Field成员变量之后的操作:1、获取值 获取到的成员变量对象.get(对象) 这个对象例如person对象
2、设置值 获取的的成员变量对象.set(对象) 同上
3、忽略权限修饰符的安全检查(这个是针对declared) 访问时用 SetAccessible(true):暴力反射。
获取到构造方法对象后:
创建对象: 构造方法对象名.newInstance 如果构造使用空参方法创建对象,可以简化写法 类对象名.newInstance
获取到方法对象之后:
执行方法: object invoke(对应类的对象的名称) 方法对象名称.invoke(p)
当我们获取所有方法的时候,不仅会获取到本类中的方法,还会获取到object类中的方法。
注解:
概念:说明程序的,给计算机看的。
概念描述:JDK1.5之后的新特性 2、说明程序 3、使用注解: @注解名称
作用分类:
@编写文档:通过代码里标识的注解生成文档(生成文档 doc文档)
@代码分析:通过代码标识的注解对代码进行分析(使用反射)
@编译检查:通过代码里标识的注解让编译器能够实现基本的编译检查(override)
1、 JDK中预定义的一些注解
@override :检测该注解的方法是否是继承自父类
@Deprecated:该注解标注的内容,表示已经过时
@SuppressWarnings("参数"):压制警告 就是不让编译器对使用者警告。 一般这个参数是传all。
2、 自定义注解
格式:
元注解
public @interface 注解名{
属性列表;
}
本质:
注解的本质就是一个接口,这个接口默认继承Annotation接口。
属性:接口中可以定义的成员方法。
要求
1、属性的返回值类型:
1、基本数据类型
2、String类型
3、枚举类型
4、注解类型
5、以上类型的数组
2、定义了属性,使用时要给属性赋值。
1、定义属性时,使用defualt关键字给属性默认初始化值,那么在使用时就可以不用赋值了。
2、如果只有一个属性需要赋值,属性名为 value 那么赋值时value可以省略。
3、数组赋值时,值用大括号包裹,如果数组中只有一个值则就可以省略大括号。
元注解:用于描述注解的注解
@Target:描述注解能够作用的位置
ElementType取值:type 可以作用于类上
METHOD 可以作用于方法上
FIELD 可以作用于成员变量上
@Retention:描述注解被保留的阶段
对应三个阶段:class 阶段,Runtiame 阶段,Source 阶段
@Retention()(RetentionPolicy.RUNTIME):当前被描述的注解,会保留到class字节码文件中,并被JVM读取到
@Documented:描述注解是否被抽取到api中
@Inherited:描述注解是否会被继承
3、 在程序使用(解析)注解
# 今日内容
1. 数据库的基本概念
2. MySQL数据库软件
1. 安装
2. 卸载
3. 配置
3. SQL
## 数据库的基本概念
1. 数据库的英文单词: DataBase 简称 : DB
2. 什么数据库?
* 用于存储和管理数据的仓库。
3. 数据库的特点:
1. 持久化存储数据的。其实数据库就是一个文件系统
2. 方便存储和管理数据
3. 使用了统一的方式操作数据库 -- SQL
4. 常见的数据库软件
* 参见《MySQL基础.pdf》
# MySQL数据库软件
1. 安装
* 参见《MySQL基础.pdf》
2. 卸载
1. 去mysql的安装目录找到my.ini文件
* 复制 datadir="C:/ProgramData/MySQL/MySQL Server 5.5/Data/"
2. 卸载MySQL
3. 删除C:/ProgramData目录下的MySQL文件夹。
3. 配置
* MySQL服务启动
1. 手动。
2. cmd--> services.msc 打开服务的窗口
3. 使用管理员打开cmd
* net start mysql : 启动mysql的服务
* net stop mysql:关闭mysql服务
* MySQL登录
1. mysql -uroot -p密码
2. mysql -hip -uroot -p连接目标的密码
3. mysql --host=ip --user=root --password=连接目标的密码
* MySQL退出
1. exit
2. quit
* MySQL目录结构
1. MySQL安装目录:basedir="D:/develop/MySQL/"
* 配置文件 my.ini
2. MySQL数据目录:datadir="C:/ProgramData/MySQL/MySQL Server 5.5/Data/"
* 几个概念
* 数据库:文件夹
* 表:文件
* 数据:数据
# SQL
1.什么是SQL?
Structured Query Language:结构化查询语言
其实就是定义了操作所有关系型数据库的规则。每一种数据库操作的方式存在不一样的地方,称为“方言”。
2.SQL通用语法
1. SQL 语句可以单行或多行书写,以分号结尾。
2. 可使用空格和缩进来增强语句的可读性。
3. MySQL 数据库的 SQL 语句不区分大小写,关键字建议使用大写。
4. 3 种注释
* 单行注释: -- 注释内容 或 # 注释内容(mysql 特有)
* 多行注释: /* 注释 */
3. SQL分类
1) DDL(Data Definition Language)数据定义语言
用来定义数据库对象:数据库,表,列等。关键字:create, drop,alter 等
2) DML(Data Manipulation Language)数据操作语言
用来对数据库中表的数据进行增删改。关键字:insert, delete, update 等
3) DQL(Data Query Language)数据查询语言
用来查询数据库中表的记录(数据)。关键字:select, where 等
4) DCL(Data Control Language)数据控制语言(了解)
用来定义数据库的访问权限和安全级别,及创建用户。关键字:GRANT, REVOKE 等
## DDL:操作数据库、表
1. 操作数据库:CRUD
1. C(Create):创建
* 创建数据库:
* create database 数据库名称;
* 创建数据库,判断不存在,再创建:
* create database if not exists 数据库名称;
* 创建数据库,并指定字符集
* create database 数据库名称 character set 字符集名;
* 练习: 创建db4数据库,判断是否存在,并制定字符集为gbk
* create database if not exists db4 character set gbk;
2. R(Retrieve):查询
* 查询所有数据库的名称:
* show databases;
* 查询某个数据库的字符集:查询某个数据库的创建语句
* show create database 数据库名称;
3. U(Update):修改
* 修改数据库的字符集
* alter database 数据库名称 character set 字符集名称;
4. D(Delete):删除
* 删除数据库
* drop database 数据库名称;
* 判断数据库存在,存在再删除
* drop database if exists 数据库名称;
5. 使用数据库
* 查询当前正在使用的数据库名称
* select database();
* 使用数据库
* use 数据库名称;
2. 操作表
1. C(Create):创建
1. 语法:
create table 表名(
列名1 数据类型1,
列名2 数据类型2,
....
列名n 数据类型n
);
* 注意:最后一列,不需要加逗号(,)
* 数据库类型:
1. int:整数类型
* age int,
2. double:小数类型
* score double(5,2)
3. date:日期,只包含年月日,yyyy-MM-dd
4. datetime:日期,包含年月日时分秒 yyyy-MM-dd HH:mm:ss
5. timestamp:时间错类型 包含年月日时分秒 yyyy-MM-dd HH:mm:ss
* 如果将来不给这个字段赋值,或赋值为null,则默认使用当前的系统时间,来自动赋值
6. varchar:字符串
* name varchar(20):姓名最大20个字符
* zhangsan 8个字符 张三 2个字符
* 创建表
create table student(
id int,
name varchar(32),
age int ,
score double(4,1),
birthday date,
insert_time timestamp
);
* 复制表:
* create table 表名 like 被复制的表名;
2. R(Retrieve):查询
* 查询某个数据库中所有的表名称
* show tables;
* 查询表结构
* desc 表名;
3. U(Update):修改
1. 修改表名
alter table 表名 rename to 新的表名;
2. 修改表的字符集
alter table 表名 character set 字符集名称;
3. 添加一列
alter table 表名 add 列名 数据类型;
4. 修改列名称 类型
alter table 表名 change 列名 新列名 新数据类型;
alter table 表名 modify 列名 新数据类型;
5. 删除列
alter table 表名 drop 列名;
4. D(Delete):删除
* drop table 表名;
* drop table if exists 表名 ;
* 客户端图形化工具:SQLYog
## DML:增删改表中数据
1. 添加数据:
* 语法:
* insert into 表名(列名1,列名2,...列名n) values(值1,值2,...值n);
* 注意:
1. 列名和值要一一对应。
2. 如果表名后,不定义列名,则默认给所有列添加值
insert into 表名 values(值1,值2,...值n);
3. 除了数字类型,其他类型需要使用引号(单双都可以)引起来
2. 删除数据:
* 语法:
* delete from 表名 [where 条件]
* 注意:
1. 如果不加条件,则删除表中所有记录。
2. 如果要删除所有记录
1. delete from 表名; -- 不推荐使用。有多少条记录就会执行多少次删除操作
2. TRUNCATE TABLE 表名; -- 推荐使用,效率更高 先删除表,然后再创建一张一样的表。
3. 修改数据:
* 语法:
* update 表名 set 列名1 = 值1, 列名2 = 值2,... [where 条件];
* 注意:
1. 如果不加任何条件,则会将表中所有记录全部修改。
## DQL:查询表中的记录
* select id,name from 表名;
1. 语法:
select
字段列表
from
表名列表
where
条件列表
group by
分组字段
having
分组之后的条件
order by
排序
limit
分页限定
2. 基础查询
1. 多个字段的查询
select 字段名1,字段名2... from 表名;
* 注意:
* 如果查询所有字段,则可以使用*来替代字段列表。
2. 去除重复:
* distinct
3. 计算列
* 一般可以使用四则运算计算一些列的值。(一般只会进行数值型的计算)
* ifnull(表达式1,表达式2):null参与的运算,计算结果都为null
* 表达式1:哪个字段需要判断是否为null
* 如果该字段为null后的替换值。
4. 起别名:
* as:as也可以省略
3. 条件查询
1. where子句后跟条件
2. 运算符
* > 、< 、<= 、>= 、= 、<> ,!=
* BETWEEN...AND
* IN( 集合)
* LIKE:模糊查询
* 占位符:
* _:单个任意字符
* %:多个任意字符
* IS NULL
* and 或 &&
* or 或 ||
* not 或 !
-- 查询年龄大于20岁
SELECT * FROM student WHERE age > 20;
SELECT * FROM student WHERE age >= 20;
-- 查询年龄等于20岁
SELECT * FROM student WHERE age = 20;
-- 查询年龄不等于20岁
SELECT * FROM student WHERE age != 20;
SELECT * FROM student WHERE age <> 20;
-- 查询年龄大于等于20 小于等于30
SELECT * FROM student WHERE age >= 20 && age <=30;
SELECT * FROM student WHERE age >= 20 AND age <=30;
SELECT * FROM student WHERE age BETWEEN 20 AND 30;
-- 查询年龄22岁,18岁,25岁的信息
SELECT * FROM student WHERE age = 22 OR age = 18 OR age = 25
SELECT * FROM student WHERE age IN (22,18,25);
-- 查询英语成绩为null
SELECT * FROM student WHERE english = NULL; -- 不对的。null值不能使用 = (!=) 判断
SELECT * FROM student WHERE english IS NULL;
-- 查询英语成绩不为null
SELECT * FROM student WHERE english IS NOT NULL;
-- 查询姓马的有哪些? like
SELECT * FROM student WHERE NAME LIKE '马%';
-- 查询姓名第二个字是化的人
SELECT * FROM student WHERE NAME LIKE "_化%";
-- 查询姓名是3个字的人
SELECT * FROM student WHERE NAME LIKE '___';
-- 查询姓名中包含德的人
SELECT * FROM student WHERE NAME LIKE '%德%';
having和where的区别:having是用在(group by)分组之后的,而where是用在分组之前的。 having后面可以艮聚合函数,而where后面不能跟聚合函数。
## DCL:操作用户权限。
|
|