# java_Demo **Repository Path**: javafdx/java_Demo ## Basic Information - **Project Name**: java_Demo - **Description**: No description available - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2019-11-27 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # java_Demo #### 介绍 ####1.6 class类中包括:属性和行为 属性-就是成员变量 行为-成员方法 有main方法才能启动main ####1.7 栈-堆-方法区 方法区里边的成员方法变量,地址保存在堆中 new出的对象保存到堆中 main方法放到栈中 调用方法-进栈,压栈 执行完-出栈 ####1.8 shift + f6 --统一重命名 ####1.9--1.10 当一个对象作为参数,传递到方法当中时,实际上传递进去的是对象的地址值 ####1.11 当使用一个对象类型作为方法的返回值时,返回值其实就是对象的地址值 ####1.12 局部变量-成员变量 默认值不一样 局部-没有默认值-要想使用必须赋值-位于栈内存 成员-会有默认值-位于堆内存 参数也是局部变量--被调用会有值 ####1.13 封装性- 方法就是一种封装-关键字private也是一种封装 ####1.14 使用private进行修饰,那么本类中仍然可以随意访问, 但是,超出了本类范围之外就不能再直接访问了 间接访问--就是定义get、set方法 public void setAge(int num){ age=num; } public int getAge(){ return age; } ---为什么倒手间接赋值?--把关 可以在方法里处理数据-提高了代码的安全性 #### 1.15 对于基本类型当中的boolean值,Getter方法一定要写成isXxx的形式,而setXxx规则不变 public void setMale(boolean b) { male = b; } public boolean isMale() { return male; } 调用获取 Student stu = new Student (); stu.isMale() #### 1.16 当方法的局部变量和类的成员变量重名的时候,根据“就近原则”,优先使用局部变量 如果需要访问本类当中的成员变量,需要使用格式:this.成员变量 注意:通过谁调用的方法,谁就是this #### 1.17 构造方法是专门用来创建对象的方法,当我们通过关键字new来创建对象时,其实就是在调用构造方法 格式: public 类名称(参数类型 参数名称) { 方法体 } 注意事项: 1.构造方法的名称必须和所在的类名称完全一样,就连大小写也要一样 2.构造方法不要写返回值类型,连void都不写 3.构造方法不能return一个具体的返回值 4.如果没有编写任何构造方法,那么编译器将会默认赠送一个构造方法,没有参数,方法体什么事情都不做 public Student() {} 5.一旦编写了至少一个构造方法,那么编译器将不再赠送 6.构造方法也是可以进行重载的, 重载,方法名称相同,参数列表不同 #### 1.18 一个标准的类通常要拥有下面四个组成部分 1.所有的成员变量都要使用private关键字修饰 2.为每一个成员变量编写一对儿Getter/Setter方法 3.编写一个无参数的构造方法 4.编写一个全参数的构造方法 这样标准的类也叫作Java Bean ----自动生成get、set---快捷键Alt+Insert 自动生成无参构造--Constructor 生成全参构造--Constructor都选中 #### 1.3.1.1 #### 1.3.1.2 demo01 键盘输入类 Scanner 引用类型使用步骤:导包-创建-使用 1.导包 import 包路径.类名称 如果需要使用的目标类,和当前类位于同一个包下,则可以省略导包语句不写 只有java.lang包下的内容不需要写,其他的包类名都需要import语句,例如String 2.创建 类名称 对象名 = new 类名称() 3.使用 对象名.成员方法名() 其实都是存储的字符串,只不过nextint 把字符串转化为int 练习 demo2demo3 #### 1.3.6 匿名对象就是只有右边的对象,没有左边的名字和赋值运算符 new 类名称(); 使用建议:如果确定有一个对象只需要使用一次,就可以用匿名对象 每次使用都会创建一个新的地址空间 匿名对象可做参数,或者返回值 #### 1.3.8 Random类用来生成随机的数字 Random rm = new Random() int num = rm.nextInt(); 左闭右开区间随机生成 int rum = rm.nextInt(10);生成0到10,不包含10 #### 1.3.10 demo4 自动生成0到n #### 1.4.12 对象数组-ArrayList集合 生成无参构造 快捷键alt + insert ---constructor---select None 生成全参构造--全选属性 生成get,set 数组--局限例子:定义一个数组,一旦创建,程序运行期间长度不可发生改变 ####objrct类--超类 toString方法 对象.toString,直接打印这个对象的属性,就是重写了这个方法,否则打印的就是他的地址值 可以再实体类中快捷键创建toString ------------------ equals方法-可以比较两个字符串是否相等,返回true ,false 也可以比较对象, 基本数据类型比较的是值,引用类型比较的是对象的地址值 比较两个对象的地址值,false,大多数不一样,没有意义 重写:比较两个对象的属性 objects.equals(s1,s2)s1,s2可以为null -------------------------- 1.3第二节date类 java.util.Date 1000毫秒==1秒 --毫秒值的概念和作用 // 获取系统时间到1970年 System.out.println(System.currentTimeMillis()); ------------------- DateFormat类--格式化日期 ,解析类 使用它的子类SimpleDateFormat() 'yyyy-MM-dd'中间的-可以随便改,字母不能改,规定 "yyyy年MM月dd日 HH时mm分ss秒" 英文转中文--format(时间) 文本字符串转日期--parse()但是要处理异常 ------------------------ 公司学习进度 system类-无需导包直接使用 -------------------------- 包装类 基本类型 ----- 对应的包装类 byte---Byte // 首字母大写 short---Short int---Integer // 特殊 char---Character // 特殊 long---Long float---Float double---Double boolean---Boolean ---------------------------------- 装箱: 构造方法 Interger in2 = new Interger("1"); 静态方法 Interger in3 = Interger.valueOf("1") 注意:不能把一个不是数字的转化为数字个还是 会报错 例如: Interger in4 = Interger.valueOf("a") 报错:NumberFormatException 拆箱: int i = in2.intValue() 自动拆箱,装箱 JDK1.5之后出现的特性 装箱Interger in = 1; // 相当于Interger in = new Interger(1) 拆箱in = in+2 // 相当于in.intValue() + 2 例如: ArrayList list = new ArrayList<>(); list.add(1) // 自动装箱 int a = list.get(0) // 自动拆箱--list.get(0).intValue(); 基本类型和字符串类型相互转换 1.基本类型 + "" 最简单的方法 2.String s2 = Interger.toString(100) 字符串转基本类型 parse*** int i = Interger.parseInt(s1) ---------------------- 04 集合 -------------- ####集合 1.4.4 数据结构- 栈(先进后出), 队列(先进先出), 数组(查询快,增删慢), 链表(查询慢,增删快),地址不是连续的-单向链,双向链表 红黑树 -------------------- 1.4.5 List集合-继承collection 有序的集合,有索引,允许重复 --------------------- 软件结构-BS CS 浏览器-服务器 客户端-服务器 网络编程的三要素 协议,ip地址 端口号 协议:计算机网络通信必须遵守的规则:UDP,TCP IP地址分类:ipv4,ipv6 ipconfig 查看本机ip ping 用来测试可不可以跟其他计算机网络通信 端口号 是一个逻辑端口,我们无法直接看到,可以使用一些 软件查看端口号 当我们使用网络软件一打开,那么操作系统就会为网络软件分配一个随机的端口号 或者要指定的端口号 端口号由两个字节组成,0-65535之间 注意:1024之前的端口号我们不能使用,已经被系统分配给已知的网络软件了 不可重复 ---------- TCP通信程序 面向连接的通信,客户端和服务器端必须经过3次握手,建立逻辑连接,才能通信(安全) 通信的步骤: 服务器端启动-客户端请求-建立逻辑连接- 这个连接中包含一个IO 对象,是字节流对象 服务器是没有IO流的,服务器可以获取到请求的客户端对象Socket 使用每个客户端Socket中提供的IO流和客户端进行交互 服务器使用客户端的字节流读取客户端发送的数据 服务器使用客户端的字节输出流给客户端回写数据 -------------------------------- 客户端:java.net.Socket 向服务端发出连接请求,服务端响应请求,两者建立连接开始通信 服务端:java.net.ServerSocket 开启一个服务,并等待客户端的连接 ------------------- ####测试 2.1.1.2 黑盒测试--输入到输出,不管逻辑,瞎几把点-不需要写代码,给输入值,看程序是否能输出期望的值 白盒测试--考虑逻辑,流程--需要写代码的,关注程序具体的执行流程 Junit单元测试时属于白盒测试的一种 2.1.1.3 Junit使用 独立运行@Test import org.junit.Test; 断言--Assert.assertEquals(预期的值,result) 和结构做比对 2.1.1.4 @Before 初始化方法- @After --------------- ####反射 2.1.2.5 反射:框架设计的灵魂 框架:半成品软件,可以在框架的基础上进行软件开发,简化编码 反射:将类的各个组成部分封装为其他对象,这就是反射机制 可以在程序的运行过程中,操作这些对象 2.1.2.6 获取class对象的方式 1.clsaa.forName("全类名"):将字节码文件加载进内存,返回.class对象 多用于配置文件,将类名定义在配置文件中。读取文件,加载类 2.类名.class:通过类名的属性class获取 多用于参数的传递 3.对象.getClass():getClass()方法在Object类中定义着 多用于对象的获取字节码的方式 结论:同一个字节码文件(*.class)在一次程序运行过程中,只会加载一次,不会通过哪一种获取 的Class对象都是同一个 2.1.2.7 Class对象功能: 获取功能: 1.获取成员变量们[] Field[] getFields[] Field getField(String name) Field[] getDeclaredFields() Field getDeclaredField(String name) 2.获取构造方法们 Constructor[] getConstructors() 3.获取成员方法们 Method[] getMethods() 4.获取类名 String getName() -------------------------------- Filed d = personClass.getDeclaredField("d") 忽略访问权限修饰符的安全检查 d.setAccessible(true) 暴力反射 Object value2 = d.get(p) 2.1.2.9 构造方法名与类名一样 每个构造方法传递的参数不一样 获取Person的Class对象 构造器Constructor constructor = personClass.getConstructor(String.class,int.class) Constructor构造方法 创建对象 Object person = constructor.newInstance("张三",23) 可以使用空参数构造方法创建对象 2.1.2.10 获取指定名称的方法 Method eat_method = personClass.getMethod("eat") Person p = new Person() 执行方法 eat_method.invoke(p) 2.1.2.11 案例: 需求:实现1.配置文件 2.反射 步骤:1.将需要创建的对象的全类名和需要执行的方法定义在配置文件中 2.在程序中加载读配置文件 3.使用反射技术来加载类文件进行内存 4.创建对象 5.执行方法 ####注解 2.1.2.12 JDK1.5之后 文档注释 -生成文档doc javadoc 文件.java 编译检查 -override 代码分析 -使用反射 1.jdk中预定义的一些注解 @Override 检查被注解标注的方法是否是继承自父类(接口)的 @Deprecated 该注解标注的内容,表示已过时 @SuppressWarnings 压制警告 @SuppressWarnings("all") 2.自定义注解 格式: 元注解 public @interface MyAnno{} 使用 @MyAnno 本质:注解本质上就是一个接口,该接口默认继承Annotation接口 2.1.2.15 属性:接口中的抽象方法 1.属性的返回值类型 基本数据类型 String 枚举 注解 以上类型的数组 class void类型不行 2.定义了属性,在使用时需要结合属性赋值 2.1.2.16 元注解:用于注解的注解 @Target:描述注解能够作用的位置 @Target(value={ElementType.TYPE}) public @interface MyAnno3{} TYPE表示该MyAnno3注解只能作用于类上 METHOD表示作用于方法上 FIELD 可以作用于成员变量上 @Retention:描述注解被保留的阶段 @Documented:描述注解是否被抽取到api文档中 @Inherited:描述注解是否被子类继承 3.在程序中使用(解析)注解 ----------------------------- ###MySQL 数据库DataBase 1.持久化存储数据,其实数据库就是一个文件系统 2.方便存储和管理数据 3.使用了统一的方式操作数据库--sql mysql -uroot -proot 卸载 必须卸载干净 找到安装目录中的my.ini 配置文件 datadir="c:/ProgramData/MySQL/MySQL Server 5.5/Data/" 卸载软件后 上述路径存放着数据文件,也要删除干净 查看服务---cmd右键以管理员身份打开cmd, cmd ---services.msc 停止数据库---net stop mysql 启动--net start mysql mysql是服务名称,不一定一样 登录 mysql -uroot -proot 或者mysql -uroot -p回车输入密码 远程连接数据库-hip mysql -h127.0.0.1 -uroot -p回车 退出exit 或者quit 2.2.7.22 DML-增删改表中数据 DQL-查询表中的记录‘select * from 表名; 1.语法: select 字段列名 from 表名列表 where 条件列表 group by 分组字段 having 分组之后的条件 order by 排序 limit 分页限定 2.基础查询 == 查询 姓名 和 年龄 SELECT NAME,AGE FROM student; == 去除重复的结果集 SELECT DISTINCT address FROM student; == 计算math和english分数之和 SELECT NAME,math,english,math + english FROM student; -- 如果有null 参与的运算,计算结果都为null SELECT NAME,math,english,math + IFNULL(english,0) FROM student; == 起别名 SELECT NAME,math,english,math + IFNULL(english,0) AS 总分 FROM student; SELECT NAME,math 数学,english 英语,math + IFNULL(english,0) 总分 FROM student; 3.条件查询 2.2.7.24 == 查询年龄大于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岁,19岁,25岁的信息(或者关系) or || SELECT * FROM student WHERE age = 22 OR age = 19 OR age = 25; SELECT * FROM student WHERE age IN (22,19,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; 4.LIKE模糊查询 _:单个字符 %:多个字符 == 查询姓马的有哪些 SELECT * FROM student WHERE NAME LIKE '马%'; 5.DQL查询语句 排序查询 语法:order by 排序字段1 排序方式1, 排序字段2 排序方式2... --排序方式,默认升序ASC 降序DESC 聚合函数, 将一列数据作为一个整体,进行纵向的计算 count:计算个数 --排除null值 SELECT COUNT(NAME) FROM student; SELECT COUNT(IFNULL(english,0)) FROM student; max:计算最大值 SELECT MAX(math) FROM student; min:计算最小值 sum:计算和 avg:计算平均值 分组查询 == 按照性别分组,分别查询男,女同学的平均分 SELECT sex,AVG(math) FROM student GROUP BY sex; == 按照性别分组,分别查询男,女同学的平均分,人数 SELECT sex,AVG(math),COUNT(id) FROM student GROUP BY sex; == 按照性别分组,分别查询男女同学平均分,人数,要求,分数低于70分的人,不参与分组 SELECT sex,AVG(math),COUNT(id) FROM student WHERE math > 70 GROUP BY sex; == 按照性别分组,分别查询男女同学平均分,人数,要求,分数低于70分的人,不参与分组,分组之后,人数要大于2个人 SELECT sex,AVG(math),COUNT(id) FROM student WHERE math > 70 GROUP BY sex HAVING COUNT(id) > 2; 注意:1.where和having的区别 where在分组之前进行限定,如果不满足条件,则不参与分组 having在分组之后进行限定,如果不满足结果,则不会被查询出来 where后不可以跟聚合函数,having可以进行聚合函数的判断 - 2.2.7.29 分页查询 limit(0,3)开始索引,每页显示条数 公式:开始索引 = (当前页码 - 1)* 每页显示的条数 - 2.2.8.1 约束,多表之间的关系,范式,数据库的备份和还原 1.主键约束:primary key 2.非空约束:not null 3.唯一约束:unique 4.外键约束:foreign key NAME VARCHAR(20) NOT NULL -- name为非空 phone_number VARCHAR(20) UNIQUE -- 添加了唯一约束-手机号都不一样 3-4 id int primary key , -- 给id添加主键约束-非空且唯一,一张表只能有一个字段为主键 主键就是表中记录的唯一标识 5auto_increment自动增长 6外键约束:foreign key 7级联操作:ON UPDATE CASCADE 2.2.9.1 多表之间的关系 一对一:一对一关系实现,可以在任意一方添加唯一外键指向另一方主键 多对一/一对多:部门和员工 一个部门有多个员工,一个员工只能对应一个部门 在多的一方建立外键,指向一的一的一方的主键 多对多:学会和课程 一个学生可以选择很多课程,一个课程也可以被很多学生选择 借助中间表-第三张表 多对多关系实现需要借助第三张中间表,中间表至少包含量两个字段,这两个字段 作为第三张表多的外键,分别指向两张表的主键 2.2.10.1 数据库设计范式 第一范式(1NF): 第二范式(2NF): 第三范式(3NF): 2.2.11.1 数据库还原和备份 1.命令行:备份 mysqldump -u用户名 -p密码 数据库名称 > 保存的路径 还原 登录数据库-创建数据库-使用数据库-执行文件 source文件路径 2.图形化工具 2.2.12.1 1.多表查询 笛卡尔积:有两个集合A,B,取这两个集合的所有组成情况 要完成多表查询,需要消除无用的数据 内连接查询 隐式内连接 -- 查询所有员工信息和对应的部门信息 SELECT * FROM emp,dept WHERE emp.'dept_id' = dept.'id'; -- 查询员工表的名称,性别,部门名称 SELECT emp.name,emp.gender,dept.name FROM emp,dept WHERE emp.'dept_id' = dept.'id'; SELECT t1.name, -- 员工表的姓名 t1.gender, -- 员工表的性别 t2.name -- 部门表的名称 FROM emp t1, dept t2 WHERE t1.'dept_id' = t2.'id'; 显式内连接 语法:select 字段列表 from 表名1 inner join 表名2 on 条件 SELECT * FROM emp INNER JOIN dept ON emp.'dept_id' = dept.'id'; SELECT * FROM emp JOIN dept ON emp.'dept_id' = dept.'id'; 外连接查询 1.左外连接: 语法:select 字段列表 from 表1 left [outer] join 表2 on 条件; -- 查询所有员工信息,如果员工有部门,则查询部门名称,没有部门,则不显示部门名称 SELECT t1.*,t2.'name' FROM emp t1,dept t2 WHERE t1.'dept_id' = t2.'id'; ------- 查询的是左表所有的数据以及其交集部分 SELECT t1.*,t2.'name' FROM emp t1 LEFT JOIN dept t2 ON t1.'dept_id' = t2.'id'; 1.右外连接: 2.2.13.1 子查询- 查询中嵌套查询,称嵌套查询为子查询 -- 查询工资最高的员工信息 -- 1.查询最高的工资是多少 9000 SELECT MAX(salary) FROM emp; -- 2.查询员工信息,并且工资等于9000的 SELECT * FROM emp WHERE emp.'salary' = 9000; -- 一条sql就完成这个操作 SELECT * FROM emp WHERE emp.'salary' = (SELECT MAX(salary) FROM emp); 1.子查询的结果是单行单列的;--运算符:> >= < <= = 2.子查询的结果是多行单列的; 3.子查询的结果是多行多列的; -- 查询财务部和市场部所有的员工信息 SELECT id FROM dept WHERE NAME = '财务部' OR NAME = '市场部'; SELECT * FROM emp WHERE dept_id = 3 OR dept = 2; SELECT * FROM emp WHERE dept_id IN (3,2); -- 多行单列的 使用运算符 IN SELECT * FROM emp WHERE dept_id IN (SELECT id FROM dept WHERE NAME = '财务部' OR NAME = '市场部'); -- 多行多列 子查询可以作为一张虚拟表 --查询员工入职日期是2011-11-11日之后的员工信息和部门信息 SELECT * FROM emp WHERE emp.'join_date' > '2011-11-11'; SELECT * FROM dept t1,(SELECT * FROM emp WHERE emp.'join_date' > '2011-11-11') t2 WHERE t1.id = t2.dept_id -- 用普通的内连接实现 SELECT * FROM emp t1,dept t2 WHERE t1.'dept_id' = t2.'id' AND t1.'join_data' > '2011-11-11'; 2.2.14.8 多表查询练习 3.查询员工姓名,工资,工资等级 分析:1.员工姓名,工资emp 工资等级 salarygrade SELECT t1.ename, t1.'salary', t2.* FROM emp t1,salarygrade t2 WHERE t1.'salary' BETWEEN t2.'losalary' AND t2.'hisalary'; 4.查询员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级 分析:1.分别对应四张表 2.条件 emp.job_id = job.id and emp.dept_id = dept.id and emp.salary BETWEEN SELECT t1.'ename', t1.'salary', t2.'jname', t2.'description', t3.'dname', t3.'loc', t4.'grade' FROM emp t1,job t2,dept t3,salarygrade t4 WHERE t1.'job_id' = t2.'id' AND t1.'dept_id' = t3.'id' AND t1.'salary' BETWEEN t4.'losalary' AND t4.'hisalary'; 5.查询出部门编号,部门名称,部门位置,部门人数 分析:1.dept 表 emp表 2.使用分组查询,按照emp.dept_id完成分组,查询count(id) 3.使用子查询将第二步的查询结果和dept表进行关联查询 SELECT dept_id,COUNT(id) FROM emp GROUP BY dept_id ------------- SELECT t1.'id',t1.'dname',t1.'loc',t2.total FROM dept t1, (SELECT dept_id,COUNT(id) total FROM emp GROUP BY dept_id) t2 WHERE t1.'id' = t2.dept_id; 6.查询所有员工的姓名及其直接上级的名称,没有领导的员工也需要查询 分析:1.姓名 emp ,直接上级的姓名 emp emp表的id和mgr是自关联 2.条件emp.id = emp.mgr 3.查询左表的所有数据,和交集数据-使用左外连接查询 SELECT t1.ename, t1.mgr, t2.'id', t2.ename FROM emp t1,emp t2 WHERE t1.mgr = t1.'id' ---------------- SELECT t1.ename, t1.mgr, t2.'id', t2.'ename' FROM emp t1 LEFT JOIN emp t2 ON t1.'mgr' = t2.'id'; 2.2.15.11 2.事务 * 如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么成功,要么同时失败 *操作:1.开始事务:start transaction 2.回滚:rollback; 3.提交:commit -- 开启事务 START TRANSACTION; -- 张三账户 -500 UPDATE account SET balance = balance - 500 WHERE NAME = 'zhangsan'; -- 李四账户 +500 PDATE account SET balance = balance + 500 WHERE NAME = 'lisi'; -- 发现执行没有问题,提交事务 COMMIT; -- 发现问题,回滚事务 ROLLBACK; 事务提交的两种方式: 自动提交: mysql就是自动提交 手动提交:需要先开启事务,在提交 修改事务的默认提交方式: 查看事务的默认提交方式:SELECT @@autocommit; -- 1代表自动提交 0代表手动提交 修改默认提交方式:set @@autocommit = 0; 事务的四大特性: 原子性 持久性 隔离性 一致性 13 事务的隔离级别 -脏读,不可重复度,幻读,串行化 3.DCL-控制权限,用户管理 回顾-DDL-操作数据库和表 DML-增删改表中的数据 DQL-查询表中的数据 DCL-管理用户,授权 --- DBA-数据库管理员 -- 1.切换到mysql数据库 -- 2.查询user表 -- 创建用户 CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码'; CREATE USER 'zhangsan'@'%' IDENTIFIED BY '123'; 通配符:% 表示可以在任意主机使用用户登录数据库 -- 删除用户 DROP USER '用户名'@'主机名'; -- 修改用户密码 UPDATE USER SET PASSWORD = PASSWORD('新密码') WHERE USER = '用户名'; SET PASSWORD FOR '用户名'@'主机' = PASSWORD('新密码') ***mysql中忘记了root用户的密码 1.cmd-->net stop mysql 停止mysql服务 需要管理员运行改cmd 2.使用无验证方式启动mysql服务:mysql --skip-grant-tables 3.打开新的cmd窗口,直接输入mysql命令,敲回车。就可以登陆成功 4.use mysql 5.update user set password = password('你的新密码') where user = 'root'; 6.关闭两个窗口 7.打开任务管理器,手动结束mysql.exe的进程 8.启动mysql服务 9.使用新密码登录 ------查询权限 SHOW GRANTS FOR '用户名'@'主机名'; -- 授予权限 GRANT 权限列表 ON 数据库名.表名 TO '用户名'@'主机名'; GRANT SELECT ON db3.account TO 'list'@'%'; 只能查询 -- 给所有权限-对任意库对任意表 GRANT ALL ON *.* TO 'zhangsan'@'localhost'; -- 撤销权限 REVOKE 权限列表 on 数据库名.表名 from '用户名'@'主机名' ; ####JDBC 步骤:1.导入驱动jar包 2.注册驱动 3.获取数据库连接对象Connection 4.定义sql 5.获取执行sql语句的对象Statement 6.执行sql,接收返回结果 7.处理结果 8.释放资源 ------- 添加jar后右键将libs文件ADD as Library 2-04 DriverManager:驱动管理对象 注册连接 获取数据库连接 Connection:数据库连接对象 获取执行sql的对象 管理事务-开始事务setAutoCommit(false)-提交事务commit()-回滚事务rollback() Statement:执行sql对象 执行sql--2.int executeUpdate(String sql) --执行DML(insert,update,delete)语句,DDL(create,alter.drop针对表和数据库) --返回的count影响行数,大于0则执行成功 2-07 3.ResultSet executeQuery(String sql):执行DQL(select)语句 ResultSet:结果集对象 4-11封装查询结果 String sql = "select * from account"; ResultSet rs = stmt.executeQuery(sql); 让游标向下移动一行 rs.next(); 获取数据 int id = rs.getInt(1);+ String name = rs.getString("name"); double babance = ra.getDouble(3); 4-12 --------------- while(rs.next()){ 循环判断结果集是否有下一行 } 5-15 登录练习 6-7 SQL注入问题:有一些sql的特殊关键字参与字符串的拼接,会造成安全性问题 PreparedStatement:执行sql的对象 预编译的sql:参数使用?作为占位符 7-17 JDBC控制事务 1.事务:一个包含多个步骤的业务操作,如果这个业务操作被事务管理,则这多个步骤,要么同时成功,要么同时失败 2.操作 开启事务--提交事务--回滚事务 3.使用Connection对象来管理事务 *开启事务:setAutoCommit(boolean autoCommit): 调用该方法设置参数为false,即开启事务 *提交事务:commit() *回滚事务:rollback() 8-1数据库连接池 Spring JDBC Template 概念:其实就是一个容器(集合),存放数据库连接的容器 当系统初始化后,容器中会申请一些连接对象,当用户来访问数据库时, 从容器中获取连接对象没用户访问完后之后,会将连接对象归还给容器 1.节约资源2.用户访问高效 8-3 数据厂商来实现 1.老技术 c3p0:数据库连接池技术 2.Druid:数据库连接池实现技术,有阿里巴巴提供的 9-11 ####XML -可扩展标记语言 1.xml标签都是自定义的,html标签是预定义的 2.xml的语法严格,html语法松散 3.xml是存储数据的,html是展示数据的 配置文件,在网络中传输 1-4 ####JSP 指令--用于配置JSP页面,导入资源文件 格式:<%@ 指令名称 属性名1=属性值 属性2=属性值2...%> 1.page 配置JSP页面的 2.include : 页面包含的,导入页面的资源文件 3.taglib:导入资源 2-12-1-6 ####Tomcat 配置 部署项目的方式 1.直接将项目放到webapps目录下即可 /hello:项目的访问路径-->虚拟目录 简化部署:将项目打成一个war包,再将war包部署到webapps目录下 war包会自动解压缩 2.配置conf/server.xml 文件 在标签体中配置 docBase:项目存放的路径 path:虚拟目录 3.在conf\Catalina\localhost创建任意名称的xml文件,在文件中编写 虚拟目录:xml文件的名称 IDEA集成tomcat run->edit config->Tomcat Server->local 成功会出现两个jar包 创建web-javaEE项目 java Enterprise企业版 javaEE7勾选Web Application Versions:3.1对应javaEE7 配置热部署 On'Updata'action : Update resources ---- (Update class resources这个选项是步数java代码,由于修改的次数多,不建议选择 On fram deactvation: Update resources #####Servlet和HTTP请求协议 1-11 ####maven 1.依赖管理 多个项目共用仓库中的jar包,减少了项目的体积 maven解压后 需要配置环境变量 新建用户变量 MAVEN_HOME D:\maven\apache-maven-3.6.1 编辑系统变量Path %MAVEN_HOME%\bin 检测mvn -v IDEA 集成maven settings-->maven-->选择maven目录和目录下的settiings.xml文件 Local repository:默认选择maven指定的本地仓库路径 Runner-->vmoptions:-DarchetypeCatalog=internal 创建maven项目 1.创建java工程-->勾选Create fromarchetype选择骨架--(推荐不使用骨架) org.apache...archetype-quickstart 填写GroupId组织名称 Artifactid项目名称 版本号 允许自动导入Enable-auto-Import (手动补齐)创建资源目录 在java文件下创建resources-->右键-->mark Directory as-->Resources Root 2.不使用骨架创建maven工程 maven-->不勾选Create fromarchetype-->next 3.使用骨架创建maven的web工程 选择..-webapp 补全java目录--- main-->java-->mark Directory->Source Root 导入jar包 打开pom.xml文件 手动输入-不知道的去搜索 provided解决与tomcat中的包冲突,只在编写代码时有用,作用域 #####redis 数据库软件 是一款高性能的NOSQL系列的非关系型数据库 ###### Mybatis 2-3解决持久层的框架 无需写dao 的实现类(但是支持写dao实现类) 第一种是配置.xml文件,第二种是在dao接口的方法上注解@Select,并制定sql语句 3-2 5-1 #####Spring ###SpringMVC 5-1三层架构MVC 浏览器-服务器 B/S 架构 服务器三层框架: 表现层:SpringMVC 业务层:Spring框架 持久层:MyBatis ---------------------------------- 请求参数 浏览器请求<------->表现层<--------->业务层<-------->持久层 响应结果 MVC 设计模型 M model模型(javabean对象,2.封装数据) V view视图(JSP,3.显示结果给用户html) C controller控制器(servlet接受请求,1.先到达控制器) --------------------------------------- 5-2 其他框架Strutsl(现在一般不用),Struts2 SpringMVC已经超过Struts2,成为最优秀的MVC框架 (共同点:1.都是表现层框架,都是基于MVC模型编写的,2.底层都离不开原始的ServletAPI,3.处理请求的机制都是一个核心的控制器) (SpringMVC是基于方法设计的(单例);Strust2是基于类(多例),每次执行都会创建一个动作类;SpringMVC快些,省去了频繁创建对象的过程) 通过一套注解,让一个简单的Java类成为处理请求的控制器,而无须实现任何接口。 清晰的角色划分: 前端控制器, 请求到处理器映射, 处理器适配器, 视图解析器,(jsp跳转到那个页面) 处理器或页面控制器, 验证器, 命令对象,(请求参数绑定到的对象就叫命令对象POJO) 表单对象(提供表单提示和提交到的对象就叫表单对象) 5-3入门程序 Maven-->创建骨架项目Create from archetype-->webapp 5-4 环境搭建 5-5代码编写 前端控制器 1.@Controller控制器类 (需要扫描注解) 2.@RequestMapping映射路径--- @RequestMapping(path="/hello") 3.return "success" 的时候 跳转到webinf文件下 pages--success页面;配置视图解析器(在文件springmvc.xml) 文件路径 文件后缀 4. 5.前端index.jsp页面请求 入门程序 6.配置服务器启动 Tomcat Server--配置本地的tomcat服务 5-6流程总结 1.启动服务器,加载一些配置文件 *加载web.xml----DispatcherServlet对象创建 *springmvc.xml文件被加载classpath:springmvc.xml *扫描类HelloController创建成对象 2.发送请求,后台处理请求 * DispatcherServlet拦截请求 视图解析器对象,转发success.jsp 5-7 用户请求---前端控制器--处理器映射器--处理器--处理器器适配器--视图解析器-- 这个配置就是默认配置了 :处理器映射器--处理器器适配器--视图解析器 5-8 RequestMapping注解的作用 可在对象上加@RequestMapping(path="/user") 在对象中的方法上加 @RequestMapping(path="/testRequestMapping") 那么请求 RequestMapping注解 5-9 RequestMapping注解属性 1.path可换位value代替,将path删掉也可以,用于请求的url路径 2.method属性。用于限制请求方法(RequestMethod枚举类)必须是post请求,才会接受,否则报405 @RequestMapping(value="/user",method={RequestMethod.POST}) 3.params:用于指定限制请求参数的条件 ,要求请求参数的key和value必须和 配置的一模一样 @RequestMapping(value="/testRequestMapping",params={"username"}) 请求: RequestMapping注解 4.headers:用于指定限制请求消息头的条件(发送的请求中必须包含请求头) @RequestMapping(value="/testRequestMapping",params = {"username=heihei"},headers = {"Accept"}) ######参数绑定及自定义类型转换 5-2-1 请求参数绑定(请求的参数直接映射到方法中的参数) @RequestMapping("/testParam") public String testParam(String username,String password){} 5-2-2 ----请求参数绑定实体类 @RequestMapping("/saveAccount") public String saveAccount(Account account){} ----实体类还有引用类型 Account实体类中包含User类 private User user; 用户姓名:
用户年龄:
5-2-3 ----配置解决中文乱码的过滤器 (前端传递参数中包含中文,后端接收乱码问题) 在web.xml中配置 characterEncodingFilter org.springframework.web.filter.CharacterEncodingFilter encoding UTF-8 characterEncodingFilter /* 原理:拦截请求,转换为UTF-8格式 5-2-4 请求参数绑定集合类型 实体类中声明连个私有属性(List,Map) private List list; private Map map; 表单: <%--把数据封装Account类中,类中存在list和map的集合
姓名:
密码:
金额:
用户姓名:
用户年龄:
用户姓名:
用户年龄:
控制台打印: Account{username='付东旭', password='123', money=12356.0, list=[User{uname='熊大', age=20, date=null}], map={one=User{uname='熊二', age=15, date=null}}} 5-2-5 特殊情况:自定义类型转换器异常情况 (一般:基本的常用类型,框架已经自动的将接收的String类型转换为对应的类型了) 但是: 有的日期格式:'2020/1/1'可以转换--打印的是标准格式 其他'2020-1-1'需要处理 定义:private Date date; 5-2-6 自定义类型转换器代码编写 1. 字符串转日期的工具类Converter public class StringToDateConverter implements Converter{ DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); // 把字符串转换日期 return df.parse(source); } 2.在springmvc.xml中注册 工具类的路径 生效: User{uname='呜啊', age=12, date=Wed Dec 30 00:00:00 CST 2020} ####常用注解---接收请求参数 5-3-1 RequestParam注解 解决请求参数和后端方法param字段不一致,不匹配问题 @RequestMapping("/testRequestParam") public String testRequestParam(@RequestParam(name="name") String username){} ---- 请求 :RequestParam 5-3-2 RequestBody注解 用于获取请求体的内容(直接使用得到的是key=value&key=value...)结构的数据 用于post请求,get请求不用 @RequestMapping("/testRequestBody") public String testRequestBody(@RequestBody String body){} 5-3-3 PathVaribale注解 用于绑定url中的占位符,delete请求 请求url中/delete/{id} .这个id就是url占位符 (REST风格) @RequestMapping(value="/testPathVariable/{sid}") public String testPathVariable(@PathVariable(name="sid") String id){} 请求: testPathVariable 5-3-4 5-3-5 RequestHeader(用处不大) 用于获取请求消息头 @RequestMapping(value="/testRequestHeader") public String testRequestHeader(@RequestHeader(value="Accept") String header, HttpServletRequest request,HttpServletResponse response) throws IOException {} 5-3-6 CookieValue 用于把指定cookie名称的值传入控制器方法参数 @RequestMapping(value="/testCookieValue") public String testCookieValue(@CookieValue(value="JSESSIONID") String cookieValue){} 5-3-7 ModelAttribute 可做用于方法上,也可以在参数上 (出现在方法上,表示当前方法会在控制器的方法执行之前,先执行。可以修饰没有返回值的方法 ,也可以修饰有具体返回值的方法)出现在参数上,获取指定的数据给参数赋值 @ModelAttribute public void showUser(){} 会优先于其他方法执行 用于场景: 提前接收字段,去数据库将原有的数据查询出来并给bean赋值 @ModelAttribute public void showUser(String uname, Map map){ System.out.println("showUser执行了..."); // 通过用户查询数据库(模拟) User user = new User(); user.setUname(uname); user.setAge(20); user.setDate(new Date()); map.put("abc",user); } 5-3-8 SessionAttribute 用于多次执行控制器方法间的参数共享 (会话期间) @RequestMapping(value="/testSessionAttributes") public String testSessionAttributes(Model model){ System.out.println("testSessionAttributes..."); // 底层会存储到request域对象中 model.addAttribute("msg","美美"); return "success"; } 在对象上:@SessionAttributes(value={"msg"}) // 把msg=美美存入到session域对中 前端:开启EL <%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %> ${sessionScope} ####SpringMvc返回值类型及相应数据类型 5-4-1 5-4-2 响应之返回值是String类型 前端请求: testString 后端处理: @RequestMapping("/testString") public String testString(Model model){ System.out.println("testString方法执行了..."); // 模拟从数据库中查询出User对象 User user = new User(); user.setUsername("美美"); user.setPassword("123"); user.setAge(30); // model对象 model.addAttribute("user",user); return "success"; } 前端接收: ${user.username} 5-4-3 响应之返回值是Void类型 跳转页面: @RequestMapping("/testVoid") public void testVoid(HttpServletRequest request, HttpServletResponse response) throws Exception { System.out.println("testVoid方法执行了..."); // 编写请求转发的程序 // request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,response); } 重定向(两次请求(不理解),第一次请求发出去,地址会变,等于又重新发送了一次请求) response.sendRedirect(request.getContextPath()+"/index.jsp"); 直接向前端返回一个字符串 // 设置中文乱码 response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); // 直接会进行响应 response.getWriter().print("你好"); 5-4-4 响应之返回值是ModelAndView类型 // 创建ModelAndView对象 ModelAndView mv = new ModelAndView(); System.out.println("testModelAndView方法执行了..."); // 模拟从数据库中查询出User对象 User user = new User(); user.setUsername("小凤"); user.setPassword("456"); user.setAge(30); // 把user对象存储到mv对象中,也会把user对象存入到request对象 mv.addObject("user",user); // 跳转到哪个页面 mv.setViewName("success"); return mv; 前端: ${user.username} ${user.password} 5-4-5 响应之使用forward和redirect进行页面跳珠 转发:(关键字的方式:forward): // 请求的转发 // return "forward:/WEB-INF/pages/success.jsp"; 重定向: return "redirect:/index.jsp";(不用加路径) 5-4-6 ResponseBody响应json数据(过滤静态资源) 1.DispatcherServlet会拦截到所有的资源,导致一个问题就是静态资源(img,css,js)也会被拦截到 从而不能被使用。解决问题就是需要配置静态资源不进行拦截,在springmvc.xml配置文件添加 5-4-7 响应json数据之发送ajax的请求 前端: // 页面加载,绑定单击事件 $(function(){ $("#btn").click(function(){ // alert("hello btn"); // 发送ajax请求 $.ajax({ // 编写json格式,设置属性和值 url:"user/testAjax", contentType:"application/json;charset=UTF-8", data:'{"username":"hehe","password":"123","age":30}', dataType:"json", type:"post", success:function(data){ // data服务器端响应的json的数据,进行解析 alert(data); alert(data.username); alert(data.password); alert(data.age); } }); }); }); 后端接收: /** * 模拟异步请求响应 */ @RequestMapping("/testAjax") public @ResponseBody User testAjax(@RequestBody User user){ // RequestBody获取请求体的内容 System.out.println("testAjax方法执行了..."); // 客户端发送ajax的请求,传的是json字符串,后端把json字符串封装到user对象中 System.out.println(user); // 做响应,模拟查询数据库 user.setUsername("haha"); user.setAge(40); // 做响应 return user; } 5-4-8 接收请求--封装到javabean中 (见4-8) 原理:springmvc默认用 MappingJacksonHttpMessageConverter对json数据进行转换 需要加入jackson的包(把字符串转换对象,或把对象转化为字符串) 步骤:向pom.xml引入依赖 com.fasterxml.jackson.core jackson-databind 2.9.0 com.fasterxml.jackson.core jackson-core 2.9.0 com.fasterxml.jackson.core jackson-annotations 2.9.0 2.@ResponseBody User (响应时,向前端返回对象转字符串) #######文件上传 5-5-1 文件上传之原理分析和搭建环境 要求:1.form表单的enctype取值必须是multipart/form-data (默认值是:application/x-www-form-urlencode) enctype是表单请求正文的类型 2.method属性取值必须是Post 3.提供一个文件选择域