1.类的加载 :
当程序使用某个类的时候,如果该类还未被加载到内存中,
则系统会通过加载,链接,初始化三步 来实现对这个类的初始化。
步骤 :
** 加载 :
将class文件读入内存,并为之创建一个Class对象
任何类被使用时系统都会创建一个Class对象
** 连接 :
①验证 是否正确的内部结构,并和其他类协调一致
②准备 负责为类的静态成员分配内存,并设置默认初始化值
③解析 将类的二进制数据中的符号引用替换为直接引用
** 初始化 :默认初始化,显示初始化,为栈分配空间
2.类的加载时机 :
* 创建类的实例
* 访问类的静态变量或为类的静态变量赋值
* 调用类的静态方法
* 初始化某个类的子类(初始化子类先去初始化父类)
* 直接使用java.exe命令运行某个类
* 使用反射的方式来强制创建某个类或接口对应的Class对象
类加载器 :
负责将class文件加载到内存中,并为之生成对应的Class对象
3.类加载器的组成 :
Bootstrap ClassLoader 根类加载器 - 引导类加载器
负责加载java核心类的加载
(System String , 在JDK中JRE的lib目录下rt文件中)
Extension ClassLoder 扩展类加载器
负责JRE的扩展目录中jar包的加载
System ClassLoader 系统类加载器
负责在jvm启动时加载来自java命令的class文件,
以及classPath环境变量中制定的jar包和类路径
4.反射机制(Reflection) ---反射就是通过class文件对象,去使用该文件中的成员变量,构造方法,成员方法
java反射机制是在运行状态中,对于任意一个对象,都能调用他的方法和属性,这种动态获取
信息以及动态调用对象的方法的功能称之为java语言的反射机制
(通过字节码文件对象去是使用文件的成员方法,成员变量,构造函数)
使用反射 : 必须要获取到字节码文件对应的Class对象
Class类 :
成员变量Field
构造方法 Constructor
成员方法 Method
获取class文件对象Class的方法 :
Object类的getClass()方法
Person p = new Person();
Class class = p.getClass();
数据类型的静态属性 class
Class class = Person.class();
** Class类中的静态方法forName(String className)
Class class = Class.forName("类的全路径");
开发中使用哪一种更好?
Class.forName("类的全路径"),基于配置文件的字符串路径
5.通过Class对象获取类的信息
Field[] 表示所有可访问的公共字段 getFileds()
Constructor[] 表示所有的可访问的公共构造方法 getconstructors();
Method[] 表示所有的可访问的公共方法 getMethosd[]
*(前提:如果该属性或方法或构造方法被private修饰的 , 加上Declared 例如:“getDeclaredFileds()”
个人认为 最好用带有Declareds)
获取指定的字段(属性)
Filed 接收 方法用 :getFiled()
获取指定的方法
Method 接收 方法用 :getDeclaredMethod()(方法名,传入的参数类型.class)
(如果该方法是被private修饰,需要 暴力访问(.setAccessible))
.invoke(对象名,数据类型);
获取指定的构造方法
Constructor 接收 方法 : getConstructors()(可能有传参的)
语法 : .newInstance(); 利用Object接收
动态代理 : 通过反射来实现的,
Proxy newProxyInstance(ClassLoader,mClassloader,Class[] interface,InvocationHandler h)
InvocationHandler 接口---- 代理对象真正实现
invoke()
JDK 只提供了对接口做代理
1. 什么是进程 ?
可以通过任务管理器看得到
正在运行的应用程序
系统进行资源分配的基本执行单位
2.什么是线程 ?
** *** 线程 就是程序的一条执行路径
线程是应用程序执行的基本单位
(每一个分支都叫一个线程,main方法是一个主分支,也叫主线程)
3.什么是多线程 ?
两个或两个以上的就叫做多线程(共享内存,可以实现多任务)
多线程的作用 ?
提高应用的使用率
****4.线程和进程的区别 ?
① : 进程可见,线程不可见
② : 线程是依赖于进程存在的
( 注 :
如果进程消失了,则线程就消失了;而如果线程消失的话,则进程依然会执行,未必会消失 )
5:并行和并发的概念?
并行:在某一个时间段内同时运行的,
并发:在某一个时间点上同时运行的,
6:线程的执行特点
①:线程的执行是随机的
②:有默认的优先级,优先级高的执行的概率越大
7:线程的调度模型
① 分时调度:所有线程平均分配CPU的使用权,
② 抢占式调度:优先让优先级高的线程使用CPU,
java使用的是抢占式调度模型
8:线程的优先级
最大值:10
最小值:1
默认值:5
总结 :
1.实现线程的方式 :
继承Thread类
实现Runnable接口
2.两种方式的区别 ?
①Thread不能共享数据,Runnable可以共享数据
②Thread只可单继承,Runnable可以多实现
③创建方式不一样 :
(Thread 直接创建子类的实例,调用.start()
Runnable 创建一个Runnable的实现类的实例,
传给Thread的构造函数,在调用.start())
3.线程的操作方法?
线程休眠:sleep(毫秒值)(重要)
线程加入:join()
线程礼让:yield()
中断线程:stop() , interrupt() (掌握)
守护线程: setDaemon()
4.同步前提是什么?
多线程的环境
多线程操作了同一个共享数据
5.同步的方式 ?
synchronized(任意对象){
需要同步的代码
}
public synchronized void show(){
需要同步的代码
}
6.同步代码块和同步方法的区别 ?
同步代码块 :是同步一块代码,波及的范围小,效率高
同步方法 : 同步了一个完整的方法,波及的范围大,效率低
为什么要用同步 ?
多条线程操作一个共享数据,会产生安全性问题,通过同步可以保证数据的安全。
通过同步可以确保数据在某一时刻只能被一条线程操作
7.线程的生命周期 :
新建 --- 创建一个线程对象
就绪 --- start() 线程有执行资格,没有执行权
运行 --- 有执行资格,有执行权
阻塞--- sleep() wait() yield()
notify() ---
notifyAll() ---
死亡
stop() interrupt()
8.死锁
多个线程因为互相争夺资源而产生一种互相等待的现象
9.死锁的前提
多线程环境
有同步资源
相互持有对方的锁
10:线程间的通信
wait() 当前线程释放锁对象,进入阻塞状态。需要等待唤醒
notify() 唤醒线程,单个的
notifyAll() 唤醒所有的线程
** 多 进程的意义 :
提高CPU的使用率
多 线程的意义 :
提高应用程序的使用率
【【 " 视频笔记 "
java程序的运行原理及JVM的启动是多线程吗 ?
A:java命令去启动JVM,JVM会启动一个进程,该进程会启动一个主线程
B:JVM的启动是多线程的,因为它最低有两个线程启动,主线程的垃圾回收线程
多线程安全问题的原因(通过视频分析)(也是我们以后判断一个程序是否有线程安全问题的依据)
是否具有多线程环境
是否有共享数据
是否有多条语句操作共享数据
同步解决线程安全问题 :
A:同步代码块
synchronized(对象){
需要被同步的代码
}
B:同步方法
把同步加在方法上
这里的锁对象是this
C:静态同步方法
把同步加在方法
这里的锁对象是当前类的字节码文件对象(反射)
】】
同步导致出现死锁的问题
A:多个线程因为争夺资源而产生相互等待的现象就叫死锁
B:解决死锁:
避免同步嵌套
1:什么是网络编程?
实现多台互联的计算机之间的信息传递
网络模型
OSI模型 7层
TCP/IP模型 4层
网络三要素(说话的案例)
IP地址
网络中计算机的唯一标识
端口号
正在运行的程序的标识
0--65535 其中0--1024系统使用的端口
通信协议
通信的规则
TCP
面相连接
可靠的
三次握手
通过IO流来传输数据
对数据大小没有限制
效率低
UDP
面向无连接
不可靠
对数据大小有限制,64k
效率快
④:DOS命令
ipconfig 查看本机IP地址
ping 后面跟IP地址 测试本机与指定的IP地址间的通信是否有问题
⑤:特殊的IP地址
127.0.0.1 回环地址(表示本机)
x.x.x.255 广播地址
2:什么是计算机网络?
通过网线,电话线等方式连接多台计算机形成的集合就叫计算机网络
3:计算机之间怎么通信?
①:通过IP找到对方主机
IP:
②:通过端口号找到对应的程序
③:遵守通信协议
TCP
面相连接
可靠的
三次握手
通过IO流来传输数据
对数据大小没有限制
效率低
UDP
面向无连接
不可靠
对数据大小有限制,64k
效率快
④:交互信息
Socket :网络套接字
Socket编程 : 网络编程,套接字编程
Socket包含了 :IP地址+端口
原理机制 :
通信的两端都有Socket
网络通信其实就是Socket间的通信
数据在两个Socket间通过IO传输
(1)Socket : 用于TCP协议的通信
①:通过IO流进行消息的传输
②:读入和写出
(2)DatagramSocket : 用于UDP协议的通信
①:通常都是把数据封装成一个数据报包 : DatagramPaceket
②:发送和接收
URL:统一资源定位符
{
wwwh原则:
w what?
w why?
w when?
h how?
}
【【 复习 IO流
什么是IO流 ?
IO是用于设备间进行数据传输的操作方式
IO流的分类 :
A: 按照流向分类
输入流 : 读取数据
输出流 : 写出数据
B:按照数据类型分类
字节流 : 按照单个字节来操作数据
字节输入流
字节输出流
字符流 : 字符流 = 字节流 + 编码表
字符输入流
字符输出流
注意 :
①:如果我们没有明确的说明按照什么来划分,那就默认按照数据类型来分
②:文件可以用window自带的记事本打开并且我们能够读懂时,采用字符流,否则采用字节流
字节流 :
inputStream 输入流
FileInputStream
BufferedInputStream
OutputStream 输出流
FileOutputStream
BufferedOutputStream
字符流 :
Reader 输入流
FileReader
BufferedReader
Writer 输出流
FileWriter
BufferedWriter
转换流:
InputStreamReader:
将字节输入流装换为字符输入流
OutputStreamWriter
将字节输出流装换为字符输出流
【【 数据库
1.数据库的概念:
MySQL是什么 ? 数据库服务器软件
①什么是数据库 :
小型的关系型数据库管理系统,存放数据的仓库
②常见的数据库 :
Oracle 甲骨文
MySql 甲骨文
DB2 IBM
SqlServer 微软
Sybase 塞尔斯
③理解数据库 :
RDBMS ---- 关系数据库管理系统
④应用程序与数据库的关系
应用程序存放数据到数据库,包括数据库检索数据
安装MySql数据库服务器软件 :
安装数据库
MySql目录结构
基本命令 :
启动和关闭MySql
* net start mysql 启动
* net stop mysql 关闭
MySql登录与退出
*mysql -uroot -p123
*exit
2.SQL概述及分类 :
a : 什么是SQL : 数据库操作语言
作用 :
操作数据库,操作表,操作数据,创建用户(授权)
(1) DDL
操作数据库,操作表
(2) DML
操作数据 :增,删,改
(3)DCL(了解)
创建用户,授权
(4) DQL
操作数据,查询
DCL : 操作用户,权限
1.创建用户
2.给用户授权
3.撤销授权
4.查看权限
5.删除用户
DDL : 对数据库或表结构进行操作
(1) 操作数据库
* 查看所有数据库 :show databases ;
* 切换数据库(选择要使用数据库) :USE 数据库名 ;
* 创建数据库create database 数据库名;([create database if not exists])数据库名 [charset=utf8]
* 删除数据库:drop database [if exists] 数据库名;
* 修改数据库编码 :alter database 数据库名 character set utf8;
(2) 操作表
创建表 :
create table [if not exists] 表明(
列名 列类型,
列名 列类型,
...
列名 列类型
);
* 查看当前数据库中所有的表 : show tables;
* 查看指定表的创建语句 : show create table 表名;(了解)
* 查看表结构 :desc 表名;
* 删除表 :drop table 表名;
修改表 :
添加列:
alter table 表名 add(列名 列类型 );
修改列类型 :
alter table teacher
modify 列名 新的列类型;
删除列 :
alter table 表名 drop 列名;
修改表名称 :
alter table 旧表名 rename to 新表名
(3) 数据类型(列类型)
int:整型
double: 浮点型,例如double(4,2)表示最多有4位,其中必须有2位小数,即最大值为:99.99
decimal: 浮点型 在表单金钱方面使用该类型,因为不会出现精度缺失的问题
char:固定长度字符串类型:char(255) --- 已经指定固定值:255个字节长度,不足就自动去补充到最大值
varchar:可变长度字符串类型:varchar(65535):实际多大就是多大
text:字符串类型(clob---国际通用标准里面用的)
date:日期类型 格式为:yyyy-MM-dd
time:时间类型 格式为:hh:mm:ss
timestamp:时间戳,格式为:yyyy-MM-dd hh:mm:ss
DDL之表操作:(补充)
* 修改列名:
alter table 表名 change 旧列名 新列名 varchar(10);
* 修改表的字符集为gbk:
alter table 表名 character set gbk;
* 查看MySql字符集:
show variables like '%char%';
* 查看MySql中的表的字符集:
show table status from 数据库名 like '%随便哪个表名%';
* 查看表中数据列的字符集:
show full columns from 表名;
* 修改数据库字符集:
alter database 数据库名 character set utf8;
* 修改表的字符集:
alter table 表名 convert to character set gbk;
* 修改列的字符集:
alter table 表名 modify column 列名 varchar(20) character set gbk not null;
DML:数据操作语言(操作表中数据):增、删、改
1:插入数据(增)
* INSERT INTO 表名(列名1,列名2...列名n) VALUES(列值1,列值2...列值n);
>在表名后给出要插入的列名,其他没有指定的列等同于插入null值,所以插入记录总是插入一行,不会是半行
>在VALUES后给出列值,值的的顺序和个数必须和前面的列对应
insert into person(id,name,year,age) values(2,'lisi',2017-09-26',20);
* INSERT INTO 表名 VALUES(列值1,列值2...,列值n);
>没有给出要插入的列,那么表示插入所有的列
>值的个数必须是该表列的个数
>值的顺序必须与表创建时给出的列的顺序相同
insert into person values(3,'zhaoliu',2020-10-06',21);
注意:
(1)在数据库中所有的字符串类型数据(日期也是属于字符串类型),都必须使用单引号,不能使用双引号。
(2)在DOS窗口中不能输入中文,因为DOS窗口是windows系统的,它有自己的编码,所以在这里和mysql就冲突了。
2:修改数据(改)
* UPDATE 表名 SET 列名1=列值1,列名2=列值2.... [WHERE 条件];
* 条件(条件是可选的)
>条件必须是一个boolean类型的值或表达式:
* 运算符:= 、!=、>、<>、<、>=、<=、IS NULL、NOT、OR、AND、IN(...)、between...and
// 把 id = 1 的数据中的name字段值修改为'男',age列值修改为'18'
update hjm set name='男',age='18' where id='1';
// 把 id = 3 的数据或 id = 4的数据中的name列值修改为'hjm'
update person set name='hjm'where id=3 or id=4;
update person set name='hjm' where id in(3,4);
// 把 age 在 20 到 40 之间的数据中的age列值修改为 age+2(年龄在原来的基础上加2)
update person set age = age+2 where age between 20 and 40;
注意:where age=null; 此条件直接返回false,就算列值为null也不会执行修改的操作, 应该修改为:where age is null;
3:删除数据(删)
* DELETE FROM 表名 [WHERE 条件];
* TRUNCATE TABLE 表名;
是DDL语句,它是先删除表(drop 表名),然后再创建该表(create table 表名;),此语句无法回滚!!!
DQL:数据查询语言:查询不会修改数据库表记录
一:基本查询
(1)列(字段)控制
①:查询所有列
select * from 表名; 其中 * 表示查询所有列
②:查询指定 列()
select 列1 [,列2,列3...] from 表名;
③:完全重复的记录只显示一次
select distinct 列名 from 表名;
④:列运算
* 数值类型的列可以做加、减、乘、除运算
>select 列名+2 from 表名; 把这个列的值加上2
* 字符串类型的列可以做连续运算
>select concat('***',列名) from 表名; 在这个列值前面拼接上3个***
* 转换NULL值
有时候需要把null转换为其他值再来做运算或者复制,如果该列存在null值,做运算还是null,这时就希望把该列的null值转化为0或者其他值再来做运算
>select ifnull(列名,想要转化为什么样的值)+100 from 表名;
* 给列起别名
>select ifnull(列名,0)+100 AS 别名 from 表名; AS 可以省略不写
(2)条件控制:
(1)条件查询
与前面的讲的UPDATE和DELETE的语句一样,SELECT语句也可以使用 WHERE关键字来控制条件
* SELECT 列名1,列名2... 列名n FROM 表名 WHERE 条件;(age>10 AND name IS NOT NULL)
(2)模糊查询
当你想查询姓cang的name时,这时就可以使用模糊查询
* SELECT * FROM 表名 WHERE name LIKE '黄_';( 1 个下划线代表 1 个字符)
:查询限制了字符长度
* SELECT * FROM 表名 WHERE name LIKE '黄%';( % 匹配 0...n 个字符)
:查询不限制字符长度
* SELECT * FROM 表名 WHERE name LIKE '%小%';(name 中有"小"的所有数据)
二:排序:order by 排序的关键字
(1)升序
* SELECT * FROM 表名 ORDER by 列名 ASC;(ASC :升序)
>按照 列名 来做排序---升序
>其中ASC可以省略(建议不要省略)
(2)降序
* SELECT * FROM 表名 ORDER BY 列名 DESC; ( DESC : 降序)
0>按照 列名 来做排序---降序
>其中DESC不可以省略
(3)多列排序
三:聚合函数:聚合函数用来做某列的纵向运算
(1)COUNT
SELECT COUNT(*) FROM 表名;
>计算表中列不全为NULL的记录的行数(有效记录)
SELECT COUNT(列名) FROM 表名;
>计算表中指定的列中值不为NULL的记录的行数
(2)MAX
SELECT MAX(列名) FROM 表名;
>计算指定列中的最大值
(3)MIN
SELECT MIN(列名) FROM 表名;
>计算指定列中的最小值
(4)SUM
SELECT SUM(列名) FROM 表名;
>计算指定列中的所有值的总和
(5)AVG
SELECT AVG(列名) FROM 表名;
>计算指定列中所有值总和的平均值
四:分组查询
分组查询是把所有记录使用某一列进行分组,然后查询组信息
例如:
SELECT age,COUNT(*) FROM 表名 GROUP BY age;
>按照年龄进行分组,查询各个年龄的记录数
SELECT sex,MAX(age) FROM 表名 GROUP BY sex;
>按照性别进行分组,查询每组性别中的最大年龄
SELECT 列名 ,COUNT(*) FROM 表名 GROUP BY 列名 HAVING COUNT(*) > 3;
>按照性别分组,查询每组的记录数 大于 3 条记录数,
五:limit字句(方言---只有MySql有)
LIMIT 用来限定查询结果的起始行,以及总行数
例如:查询起始行为第3行,一共查询4行记录
SELECT * FROM 表名 LIMIT 2,4;
>其中2表示从第三行开始查,4表示查询4条记录,即:第3、4、5、6条记录
limit 被用来做数据分页查询
思考题:
1:一页的记录数:10条
2:查询第3页
开始的位置:(当前页 - 1)*每页记录数
一:约束:约束是添加到列上的,用来约束列的。
A:约束的分类:
(1)主键约束(记录的唯一标识):非空、唯一、被引用
* 当表的某一列被指定为主键之后,该列就不能为空,不能有重复值出现。
* 创建表时指定主键的两种方式:
方式一:
CREATE TABLE stu(
id char(10) PRIMARY KEY,
name varchar(20),
age int;
);
方式二:
CREATE TABLE stu(
id char(10),
name varchar(20),
age int,
PRIMARY KEY(id)
);
>指定id列为主键列,即为id列添加主键约束
* 修改表时指定主键:ALTER TABLE stu ADD PRIMARY KEY(id);
* 删除主键:ALTER TABLE stu DROP PRIMARY KEY;
* 主键自增长:因为主键列的特点是:必须唯一、不能为空。所以一般都会指定主键列的数据类型为整型,然后设置其自动增长,这样可以保证在插入数据时主键列的唯一和非空。
* 创建表时指定主键自增:
CREATE TABLE stu(
id int PRIMARY KEY AUTO_INCREMENT,
name varchar(20)
age int
);
(2)非空约束:因为某些列不能设置为null值,所以可以对列添加非空约束
CREATE TABLE stu(
id int PRIMERY KEY AUTO_INCREMENT,
name vachar(20) NOT NULL,
age int
);
* 对name列添加了非空约束
(3)唯一约束:表中某些列里不能有重复的值,所以可以对列添加唯一约束。
* 例如身份证是不可以重复的。
CREATE TABLE stu(
id int PRIMARY KEY AUTO_INCREMENT,
name varchar(20) NOT NULL,
idcard int UNIQUE
);
(4)外键约束:
* 外键必须是另一张表的主键的值
* 外键可以重复
* 外键可以为空
* 一张表可以有多个外键
*** 外键的作用:保证数据的一致性和完整性
B:创建外键并设置外键约束:
步骤:
①:首先创建一个主表:
CREATE TABLE stu(
id int PRIMARY KEY AUTO_INCREMENT,
name varchar(20),
age int,
fk int (注释:外键)
);
②:创建子表:
CREATE TABLE stumessage(
message int PRIMARY KEY AUTO_INCREMENT,
phone bigint,
address varchar(60),
class int
);
③:设置外键关联:
ALTER TABLE stu ADD CONSTRAINT fuco_stu_stumessage FOREIGN KEY(fk) REFERENCES stumessage(message);
二:多表查询:
A:分类
(1)合并结果集(了解):结果集就是一张表格
* 两张表的结果集相同(列数和列类型)
SELECT * FROM 表1 UNION ALL SELECT * FROM 表2;
> 如果不加all 会去除相同的结果
> 可以合并相同类型的列
(2)连接查询
* 分类:
内连接
外链接
>左外连接
>右外连接
>全外连接(MySql不支持)
自然连接(属于一种简化方式)
①:内连接
* 方言:SELECT * FROM 表1 别名1,表2 别名2 [ WHERE 别名1.列名=别名2.列名 ]
* 标准:SELECT * FROM 表1 别名1 INNER JOIN 表2 别名2 ON 别名1.xx=别名2.xx
* 自然:SELECT * FROM 表1 别名1 NATURAL JOIN 表2 别名2
注意:车祸现场
注意:
①:内连接查询出的所有记录都满足条件
②:笛卡尔积:两表记录数的乘积,会导致产生很对垃圾数据
②:外链接
* 左外连接:SELECT * FROM 表1 别名1 LEFT OUTER JOIN 表2 别名2 ON 别名1.xx=别名2.xx
>左表记录无论是否满足条件都会查询出来,而右表只有满足条件才能出来,左表不满足条件的记录,右表部分都为null
* 左外自然连接:SELECT * FROM 表1 别名1 NATURAL LEFT OUTER JOIN 表2 别名2
* 右外连接:SELECT * FROM 表1 别名1 RIGHT OUTER JOIN 表2 别名2 ON 别名1.xx=别名2.xx
>右表记录无论是否满足条件都会查询出来,而左表只有满足条件才会查询出来,右表不满足条件的记录,左表部分都为null
* 右外自然连接:SELECT * FROM 表1 别名1 NATURAL RIGHT OUTER JOIN 表2 别名2
* 全连接:可以使用UNION来完成
(3)子查询:查询中有查询(一条sql语句中有多个select关键字)
* 出现的位置:
* WHERE 后作为条件存在,是可以做运算
* FROM 后作为表存在(多行多列),可以起别名
* 条件
* 单行单列:SELECT * FROM 表1 别名1 WHERE 列 [ =、>、<、>=、<=、!=] (SELECT 列 FROM 表2 别名2 WHERE 条件);
* 单行多列:SELECT * FROM 表1 别名1 WHERE (列1,列2) IN (SELECT 列 FROM 表2 别名2 WHERE 条件);
* 多行单列:SELECT * FROM 表1 别名1 WHERE 列 [ IN、ALL、ANY ] (SELECT 列 FROM 表2 别名2 WHERE 条件);
* 多行多列:SELECT * FROM 表1 别名1 ,(SELECT * FROM 表2 别名2 WHERE 条件) 别名2 WHERE 条件;
JDBC :
一 什么是JDBC ?
JDBC(Java Datebase connectivity) 就是java数据库连接,通俗的来说 :就是用java语言来操作数据库,
原来我们操作数据库都是在控制台使用SQL语句来操作数据库,JDBC是用java语言向数据库发送SQL语句。
二 JDBC原理 图形
三 JDBC的使用步骤 :
*导入jar包 : 驱动
*加载驱动类 :Class.forName("全类名") ---"com.mysql.jdbc.Driver"
*给出 url username password (其中url需要记下来,用户名和密码就是你的MySql登录的用户名和密码)
*url :jdbc:mysql://localhost:3306/你的数据库名
*username : root
*password : 123
*使用DriverManagerl类来得到一个连接对象
四 操作数据库
A:导入jar包 :驱动
B:加载驱动类 :Class.forName("全类名") ---"com.mysql.jdbc.Driver"
C: 给出 url 、 username 、 password (其中url需要记下来,用户名和密码就是你的MySql登录的用户名和密码)
* url:jdbc:mysql://localhost:3306/你的数据库名
* username:root
* password:123
D:使用DriverManager类来得到一个连接对象
②:通过连接对象获取一个Statement对象(sql语句发送器)
Statement statement = connection.createStatement();
③:通过Statement对象发送sql语句
* 执行DDL、DML操作
String sql = "update student set name='你妹的' where id=1";
// 返回值 count 表示这个sql语句执行影响的记录数
int count = mStatement.executeUpdate(sql);
* 执行DQL操作
String sql = "select * from student";
// 返回值 ResultSet 对象表示一个结果集,里面包含了查询出来的所有记录
ResultSet mResultSet = mStatement.execuQuery(sql);
* 获取结果集里面的值:
// mResultSet.next()判断结果集里面有没有下一行数据,有就返回 true,没有就返回 false
while(set.next()){
int id = set.getInt("列名");// getXxx中的Xxx必须和列类型相同(或者全部用getObject(),然后强转)
String name = set.getString("列名");
}
注意:mResuktSet.getMetaData(),返回所有列的编号对象,mResuktSet.getMetaData().getColumnCount() 返回所有的列数(int类型)
(5)JDBC的规范化形式
* 资源要关闭---倒关
* 通过try{ }catch(){ }finally{ // 在此关闭资源,做非空判断,增强代码健壮性 }
(6)预编译:PreparedStatement:是Statement的子接口
* PreparedStatement的作用:
* 防止SQL攻击
? 什么是SQL攻击:
通过特殊值来混淆SQL语句的判断条件,造成SQL操作错误。
* 提高代码的可读性
* 提高效率
* PreparedStatement:获取方式:
①:给出SQL模板,所有的参数使用 ? 来代替
String sql = "select * from student where username=? and password=? ";
②:通过Connection对象获取 PreparedStatement 对象
PreparedStatement preStatement = mConnection.preparedStatement(sql);
* 预编译这个sql模板
* 校验sql的语法
③:为参数赋值:调用 preStatement 中的一系列 setXxx方法为sql语句中的问号赋值
preStatement.setString(1,uesrname);// 为第一个 ? 赋值
preStatement.setString(2,password);// 为第二个 ?赋值
④:调用executeUpdate()或者executeQuery()方法向数据库发送sql语句
当程序使用某个类的时候,如果该类还未被加载到内存中,
则系统会通过加载,链接,初始化三步 来实现对这个类的初始化。
步骤 :
** 加载 :
将class文件读入内存,并为之创建一个Class对象
任何类被使用时系统都会创建一个Class对象
** 连接 :
①验证 是否正确的内部结构,并和其他类协调一致
②准备 负责为类的静态成员分配内存,并设置默认初始化值
③解析 将类的二进制数据中的符号引用替换为直接引用
** 初始化 :默认初始化,显示初始化,为栈分配空间
2.类的加载时机 :
* 创建类的实例
* 访问类的静态变量或为类的静态变量赋值
* 调用类的静态方法
* 初始化某个类的子类(初始化子类先去初始化父类)
* 直接使用java.exe命令运行某个类
* 使用反射的方式来强制创建某个类或接口对应的Class对象
类加载器 :
负责将class文件加载到内存中,并为之生成对应的Class对象
3.类加载器的组成 :
Bootstrap ClassLoader 根类加载器 - 引导类加载器
负责加载java核心类的加载
(System String , 在JDK中JRE的lib目录下rt文件中)
Extension ClassLoder 扩展类加载器
负责JRE的扩展目录中jar包的加载
System ClassLoader 系统类加载器
负责在jvm启动时加载来自java命令的class文件,
以及classPath环境变量中制定的jar包和类路径
4.反射机制(Reflection) ---反射就是通过class文件对象,去使用该文件中的成员变量,构造方法,成员方法
java反射机制是在运行状态中,对于任意一个对象,都能调用他的方法和属性,这种动态获取
信息以及动态调用对象的方法的功能称之为java语言的反射机制
(通过字节码文件对象去是使用文件的成员方法,成员变量,构造函数)
使用反射 : 必须要获取到字节码文件对应的Class对象
Class类 :
成员变量Field
构造方法 Constructor
成员方法 Method
获取class文件对象Class的方法 :
Object类的getClass()方法
Person p = new Person();
Class class = p.getClass();
数据类型的静态属性 class
Class class = Person.class();
** Class类中的静态方法forName(String className)
Class class = Class.forName("类的全路径");
开发中使用哪一种更好?
Class.forName("类的全路径"),基于配置文件的字符串路径
5.通过Class对象获取类的信息
Field[] 表示所有可访问的公共字段 getFileds()
Constructor[] 表示所有的可访问的公共构造方法 getconstructors();
Method[] 表示所有的可访问的公共方法 getMethosd[]
*(前提:如果该属性或方法或构造方法被private修饰的 , 加上Declared 例如:“getDeclaredFileds()”
个人认为 最好用带有Declareds)
获取指定的字段(属性)
Filed 接收 方法用 :getFiled()
获取指定的方法
Method 接收 方法用 :getDeclaredMethod()(方法名,传入的参数类型.class)
(如果该方法是被private修饰,需要 暴力访问(.setAccessible))
.invoke(对象名,数据类型);
获取指定的构造方法
Constructor 接收 方法 : getConstructors()(可能有传参的)
语法 : .newInstance(); 利用Object接收
动态代理 : 通过反射来实现的,
Proxy newProxyInstance(ClassLoader,mClassloader,Class[] interface,InvocationHandler h)
InvocationHandler 接口---- 代理对象真正实现
invoke()
JDK 只提供了对接口做代理
1. 什么是进程 ?
可以通过任务管理器看得到
正在运行的应用程序
系统进行资源分配的基本执行单位
2.什么是线程 ?
** *** 线程 就是程序的一条执行路径
线程是应用程序执行的基本单位
(每一个分支都叫一个线程,main方法是一个主分支,也叫主线程)
3.什么是多线程 ?
两个或两个以上的就叫做多线程(共享内存,可以实现多任务)
多线程的作用 ?
提高应用的使用率
****4.线程和进程的区别 ?
① : 进程可见,线程不可见
② : 线程是依赖于进程存在的
( 注 :
如果进程消失了,则线程就消失了;而如果线程消失的话,则进程依然会执行,未必会消失 )
5:并行和并发的概念?
并行:在某一个时间段内同时运行的,
并发:在某一个时间点上同时运行的,
6:线程的执行特点
①:线程的执行是随机的
②:有默认的优先级,优先级高的执行的概率越大
7:线程的调度模型
① 分时调度:所有线程平均分配CPU的使用权,
② 抢占式调度:优先让优先级高的线程使用CPU,
java使用的是抢占式调度模型
8:线程的优先级
最大值:10
最小值:1
默认值:5
总结 :
1.实现线程的方式 :
继承Thread类
实现Runnable接口
2.两种方式的区别 ?
①Thread不能共享数据,Runnable可以共享数据
②Thread只可单继承,Runnable可以多实现
③创建方式不一样 :
(Thread 直接创建子类的实例,调用.start()
Runnable 创建一个Runnable的实现类的实例,
传给Thread的构造函数,在调用.start())
3.线程的操作方法?
线程休眠:sleep(毫秒值)(重要)
线程加入:join()
线程礼让:yield()
中断线程:stop() , interrupt() (掌握)
守护线程: setDaemon()
4.同步前提是什么?
多线程的环境
多线程操作了同一个共享数据
5.同步的方式 ?
synchronized(任意对象){
需要同步的代码
}
public synchronized void show(){
需要同步的代码
}
6.同步代码块和同步方法的区别 ?
同步代码块 :是同步一块代码,波及的范围小,效率高
同步方法 : 同步了一个完整的方法,波及的范围大,效率低
为什么要用同步 ?
多条线程操作一个共享数据,会产生安全性问题,通过同步可以保证数据的安全。
通过同步可以确保数据在某一时刻只能被一条线程操作
7.线程的生命周期 :
新建 --- 创建一个线程对象
就绪 --- start() 线程有执行资格,没有执行权
运行 --- 有执行资格,有执行权
阻塞--- sleep() wait() yield()
notify() ---
notifyAll() ---
死亡
stop() interrupt()
8.死锁
多个线程因为互相争夺资源而产生一种互相等待的现象
9.死锁的前提
多线程环境
有同步资源
相互持有对方的锁
10:线程间的通信
wait() 当前线程释放锁对象,进入阻塞状态。需要等待唤醒
notify() 唤醒线程,单个的
notifyAll() 唤醒所有的线程
** 多 进程的意义 :
提高CPU的使用率
多 线程的意义 :
提高应用程序的使用率
【【 " 视频笔记 "
java程序的运行原理及JVM的启动是多线程吗 ?
A:java命令去启动JVM,JVM会启动一个进程,该进程会启动一个主线程
B:JVM的启动是多线程的,因为它最低有两个线程启动,主线程的垃圾回收线程
多线程安全问题的原因(通过视频分析)(也是我们以后判断一个程序是否有线程安全问题的依据)
是否具有多线程环境
是否有共享数据
是否有多条语句操作共享数据
同步解决线程安全问题 :
A:同步代码块
synchronized(对象){
需要被同步的代码
}
B:同步方法
把同步加在方法上
这里的锁对象是this
C:静态同步方法
把同步加在方法
这里的锁对象是当前类的字节码文件对象(反射)
】】
同步导致出现死锁的问题
A:多个线程因为争夺资源而产生相互等待的现象就叫死锁
B:解决死锁:
避免同步嵌套
1:什么是网络编程?
实现多台互联的计算机之间的信息传递
网络模型
OSI模型 7层
TCP/IP模型 4层
网络三要素(说话的案例)
IP地址
网络中计算机的唯一标识
端口号
正在运行的程序的标识
0--65535 其中0--1024系统使用的端口
通信协议
通信的规则
TCP
面相连接
可靠的
三次握手
通过IO流来传输数据
对数据大小没有限制
效率低
UDP
面向无连接
不可靠
对数据大小有限制,64k
效率快
④:DOS命令
ipconfig 查看本机IP地址
ping 后面跟IP地址 测试本机与指定的IP地址间的通信是否有问题
⑤:特殊的IP地址
127.0.0.1 回环地址(表示本机)
x.x.x.255 广播地址
2:什么是计算机网络?
通过网线,电话线等方式连接多台计算机形成的集合就叫计算机网络
3:计算机之间怎么通信?
①:通过IP找到对方主机
IP:
②:通过端口号找到对应的程序
③:遵守通信协议
TCP
面相连接
可靠的
三次握手
通过IO流来传输数据
对数据大小没有限制
效率低
UDP
面向无连接
不可靠
对数据大小有限制,64k
效率快
④:交互信息
Socket :网络套接字
Socket编程 : 网络编程,套接字编程
Socket包含了 :IP地址+端口
原理机制 :
通信的两端都有Socket
网络通信其实就是Socket间的通信
数据在两个Socket间通过IO传输
(1)Socket : 用于TCP协议的通信
①:通过IO流进行消息的传输
②:读入和写出
(2)DatagramSocket : 用于UDP协议的通信
①:通常都是把数据封装成一个数据报包 : DatagramPaceket
②:发送和接收
URL:统一资源定位符
{
wwwh原则:
w what?
w why?
w when?
h how?
}
【【 复习 IO流
什么是IO流 ?
IO是用于设备间进行数据传输的操作方式
IO流的分类 :
A: 按照流向分类
输入流 : 读取数据
输出流 : 写出数据
B:按照数据类型分类
字节流 : 按照单个字节来操作数据
字节输入流
字节输出流
字符流 : 字符流 = 字节流 + 编码表
字符输入流
字符输出流
注意 :
①:如果我们没有明确的说明按照什么来划分,那就默认按照数据类型来分
②:文件可以用window自带的记事本打开并且我们能够读懂时,采用字符流,否则采用字节流
字节流 :
inputStream 输入流
FileInputStream
BufferedInputStream
OutputStream 输出流
FileOutputStream
BufferedOutputStream
字符流 :
Reader 输入流
FileReader
BufferedReader
Writer 输出流
FileWriter
BufferedWriter
转换流:
InputStreamReader:
将字节输入流装换为字符输入流
OutputStreamWriter
将字节输出流装换为字符输出流
【【 数据库
1.数据库的概念:
MySQL是什么 ? 数据库服务器软件
①什么是数据库 :
小型的关系型数据库管理系统,存放数据的仓库
②常见的数据库 :
Oracle 甲骨文
MySql 甲骨文
DB2 IBM
SqlServer 微软
Sybase 塞尔斯
③理解数据库 :
RDBMS ---- 关系数据库管理系统
④应用程序与数据库的关系
应用程序存放数据到数据库,包括数据库检索数据
安装MySql数据库服务器软件 :
安装数据库
MySql目录结构
基本命令 :
启动和关闭MySql
* net start mysql 启动
* net stop mysql 关闭
MySql登录与退出
*mysql -uroot -p123
*exit
2.SQL概述及分类 :
a : 什么是SQL : 数据库操作语言
作用 :
操作数据库,操作表,操作数据,创建用户(授权)
(1) DDL
操作数据库,操作表
(2) DML
操作数据 :增,删,改
(3)DCL(了解)
创建用户,授权
(4) DQL
操作数据,查询
DCL : 操作用户,权限
1.创建用户
2.给用户授权
3.撤销授权
4.查看权限
5.删除用户
DDL : 对数据库或表结构进行操作
(1) 操作数据库
* 查看所有数据库 :show databases ;
* 切换数据库(选择要使用数据库) :USE 数据库名 ;
* 创建数据库create database 数据库名;([create database if not exists])数据库名 [charset=utf8]
* 删除数据库:drop database [if exists] 数据库名;
* 修改数据库编码 :alter database 数据库名 character set utf8;
(2) 操作表
创建表 :
create table [if not exists] 表明(
列名 列类型,
列名 列类型,
...
列名 列类型
);
* 查看当前数据库中所有的表 : show tables;
* 查看指定表的创建语句 : show create table 表名;(了解)
* 查看表结构 :desc 表名;
* 删除表 :drop table 表名;
修改表 :
添加列:
alter table 表名 add(列名 列类型 );
修改列类型 :
alter table teacher
modify 列名 新的列类型;
删除列 :
alter table 表名 drop 列名;
修改表名称 :
alter table 旧表名 rename to 新表名
(3) 数据类型(列类型)
int:整型
double: 浮点型,例如double(4,2)表示最多有4位,其中必须有2位小数,即最大值为:99.99
decimal: 浮点型 在表单金钱方面使用该类型,因为不会出现精度缺失的问题
char:固定长度字符串类型:char(255) --- 已经指定固定值:255个字节长度,不足就自动去补充到最大值
varchar:可变长度字符串类型:varchar(65535):实际多大就是多大
text:字符串类型(clob---国际通用标准里面用的)
date:日期类型 格式为:yyyy-MM-dd
time:时间类型 格式为:hh:mm:ss
timestamp:时间戳,格式为:yyyy-MM-dd hh:mm:ss
DDL之表操作:(补充)
* 修改列名:
alter table 表名 change 旧列名 新列名 varchar(10);
* 修改表的字符集为gbk:
alter table 表名 character set gbk;
* 查看MySql字符集:
show variables like '%char%';
* 查看MySql中的表的字符集:
show table status from 数据库名 like '%随便哪个表名%';
* 查看表中数据列的字符集:
show full columns from 表名;
* 修改数据库字符集:
alter database 数据库名 character set utf8;
* 修改表的字符集:
alter table 表名 convert to character set gbk;
* 修改列的字符集:
alter table 表名 modify column 列名 varchar(20) character set gbk not null;
DML:数据操作语言(操作表中数据):增、删、改
1:插入数据(增)
* INSERT INTO 表名(列名1,列名2...列名n) VALUES(列值1,列值2...列值n);
>在表名后给出要插入的列名,其他没有指定的列等同于插入null值,所以插入记录总是插入一行,不会是半行
>在VALUES后给出列值,值的的顺序和个数必须和前面的列对应
insert into person(id,name,year,age) values(2,'lisi',2017-09-26',20);
* INSERT INTO 表名 VALUES(列值1,列值2...,列值n);
>没有给出要插入的列,那么表示插入所有的列
>值的个数必须是该表列的个数
>值的顺序必须与表创建时给出的列的顺序相同
insert into person values(3,'zhaoliu',2020-10-06',21);
注意:
(1)在数据库中所有的字符串类型数据(日期也是属于字符串类型),都必须使用单引号,不能使用双引号。
(2)在DOS窗口中不能输入中文,因为DOS窗口是windows系统的,它有自己的编码,所以在这里和mysql就冲突了。
2:修改数据(改)
* UPDATE 表名 SET 列名1=列值1,列名2=列值2.... [WHERE 条件];
* 条件(条件是可选的)
>条件必须是一个boolean类型的值或表达式:
* 运算符:= 、!=、>、<>、<、>=、<=、IS NULL、NOT、OR、AND、IN(...)、between...and
// 把 id = 1 的数据中的name字段值修改为'男',age列值修改为'18'
update hjm set name='男',age='18' where id='1';
// 把 id = 3 的数据或 id = 4的数据中的name列值修改为'hjm'
update person set name='hjm'where id=3 or id=4;
update person set name='hjm' where id in(3,4);
// 把 age 在 20 到 40 之间的数据中的age列值修改为 age+2(年龄在原来的基础上加2)
update person set age = age+2 where age between 20 and 40;
注意:where age=null; 此条件直接返回false,就算列值为null也不会执行修改的操作, 应该修改为:where age is null;
3:删除数据(删)
* DELETE FROM 表名 [WHERE 条件];
* TRUNCATE TABLE 表名;
是DDL语句,它是先删除表(drop 表名),然后再创建该表(create table 表名;),此语句无法回滚!!!
DQL:数据查询语言:查询不会修改数据库表记录
一:基本查询
(1)列(字段)控制
①:查询所有列
select * from 表名; 其中 * 表示查询所有列
②:查询指定 列()
select 列1 [,列2,列3...] from 表名;
③:完全重复的记录只显示一次
select distinct 列名 from 表名;
④:列运算
* 数值类型的列可以做加、减、乘、除运算
>select 列名+2 from 表名; 把这个列的值加上2
* 字符串类型的列可以做连续运算
>select concat('***',列名) from 表名; 在这个列值前面拼接上3个***
* 转换NULL值
有时候需要把null转换为其他值再来做运算或者复制,如果该列存在null值,做运算还是null,这时就希望把该列的null值转化为0或者其他值再来做运算
>select ifnull(列名,想要转化为什么样的值)+100 from 表名;
* 给列起别名
>select ifnull(列名,0)+100 AS 别名 from 表名; AS 可以省略不写
(2)条件控制:
(1)条件查询
与前面的讲的UPDATE和DELETE的语句一样,SELECT语句也可以使用 WHERE关键字来控制条件
* SELECT 列名1,列名2... 列名n FROM 表名 WHERE 条件;(age>10 AND name IS NOT NULL)
(2)模糊查询
当你想查询姓cang的name时,这时就可以使用模糊查询
* SELECT * FROM 表名 WHERE name LIKE '黄_';( 1 个下划线代表 1 个字符)
:查询限制了字符长度
* SELECT * FROM 表名 WHERE name LIKE '黄%';( % 匹配 0...n 个字符)
:查询不限制字符长度
* SELECT * FROM 表名 WHERE name LIKE '%小%';(name 中有"小"的所有数据)
二:排序:order by 排序的关键字
(1)升序
* SELECT * FROM 表名 ORDER by 列名 ASC;(ASC :升序)
>按照 列名 来做排序---升序
>其中ASC可以省略(建议不要省略)
(2)降序
* SELECT * FROM 表名 ORDER BY 列名 DESC; ( DESC : 降序)
0>按照 列名 来做排序---降序
>其中DESC不可以省略
(3)多列排序
三:聚合函数:聚合函数用来做某列的纵向运算
(1)COUNT
SELECT COUNT(*) FROM 表名;
>计算表中列不全为NULL的记录的行数(有效记录)
SELECT COUNT(列名) FROM 表名;
>计算表中指定的列中值不为NULL的记录的行数
(2)MAX
SELECT MAX(列名) FROM 表名;
>计算指定列中的最大值
(3)MIN
SELECT MIN(列名) FROM 表名;
>计算指定列中的最小值
(4)SUM
SELECT SUM(列名) FROM 表名;
>计算指定列中的所有值的总和
(5)AVG
SELECT AVG(列名) FROM 表名;
>计算指定列中所有值总和的平均值
四:分组查询
分组查询是把所有记录使用某一列进行分组,然后查询组信息
例如:
SELECT age,COUNT(*) FROM 表名 GROUP BY age;
>按照年龄进行分组,查询各个年龄的记录数
SELECT sex,MAX(age) FROM 表名 GROUP BY sex;
>按照性别进行分组,查询每组性别中的最大年龄
SELECT 列名 ,COUNT(*) FROM 表名 GROUP BY 列名 HAVING COUNT(*) > 3;
>按照性别分组,查询每组的记录数 大于 3 条记录数,
五:limit字句(方言---只有MySql有)
LIMIT 用来限定查询结果的起始行,以及总行数
例如:查询起始行为第3行,一共查询4行记录
SELECT * FROM 表名 LIMIT 2,4;
>其中2表示从第三行开始查,4表示查询4条记录,即:第3、4、5、6条记录
limit 被用来做数据分页查询
思考题:
1:一页的记录数:10条
2:查询第3页
开始的位置:(当前页 - 1)*每页记录数
一:约束:约束是添加到列上的,用来约束列的。
A:约束的分类:
(1)主键约束(记录的唯一标识):非空、唯一、被引用
* 当表的某一列被指定为主键之后,该列就不能为空,不能有重复值出现。
* 创建表时指定主键的两种方式:
方式一:
CREATE TABLE stu(
id char(10) PRIMARY KEY,
name varchar(20),
age int;
);
方式二:
CREATE TABLE stu(
id char(10),
name varchar(20),
age int,
PRIMARY KEY(id)
);
>指定id列为主键列,即为id列添加主键约束
* 修改表时指定主键:ALTER TABLE stu ADD PRIMARY KEY(id);
* 删除主键:ALTER TABLE stu DROP PRIMARY KEY;
* 主键自增长:因为主键列的特点是:必须唯一、不能为空。所以一般都会指定主键列的数据类型为整型,然后设置其自动增长,这样可以保证在插入数据时主键列的唯一和非空。
* 创建表时指定主键自增:
CREATE TABLE stu(
id int PRIMARY KEY AUTO_INCREMENT,
name varchar(20)
age int
);
(2)非空约束:因为某些列不能设置为null值,所以可以对列添加非空约束
CREATE TABLE stu(
id int PRIMERY KEY AUTO_INCREMENT,
name vachar(20) NOT NULL,
age int
);
* 对name列添加了非空约束
(3)唯一约束:表中某些列里不能有重复的值,所以可以对列添加唯一约束。
* 例如身份证是不可以重复的。
CREATE TABLE stu(
id int PRIMARY KEY AUTO_INCREMENT,
name varchar(20) NOT NULL,
idcard int UNIQUE
);
(4)外键约束:
* 外键必须是另一张表的主键的值
* 外键可以重复
* 外键可以为空
* 一张表可以有多个外键
*** 外键的作用:保证数据的一致性和完整性
B:创建外键并设置外键约束:
步骤:
①:首先创建一个主表:
CREATE TABLE stu(
id int PRIMARY KEY AUTO_INCREMENT,
name varchar(20),
age int,
fk int (注释:外键)
);
②:创建子表:
CREATE TABLE stumessage(
message int PRIMARY KEY AUTO_INCREMENT,
phone bigint,
address varchar(60),
class int
);
③:设置外键关联:
ALTER TABLE stu ADD CONSTRAINT fuco_stu_stumessage FOREIGN KEY(fk) REFERENCES stumessage(message);
二:多表查询:
A:分类
(1)合并结果集(了解):结果集就是一张表格
* 两张表的结果集相同(列数和列类型)
SELECT * FROM 表1 UNION ALL SELECT * FROM 表2;
> 如果不加all 会去除相同的结果
> 可以合并相同类型的列
(2)连接查询
* 分类:
内连接
外链接
>左外连接
>右外连接
>全外连接(MySql不支持)
自然连接(属于一种简化方式)
①:内连接
* 方言:SELECT * FROM 表1 别名1,表2 别名2 [ WHERE 别名1.列名=别名2.列名 ]
* 标准:SELECT * FROM 表1 别名1 INNER JOIN 表2 别名2 ON 别名1.xx=别名2.xx
* 自然:SELECT * FROM 表1 别名1 NATURAL JOIN 表2 别名2
注意:车祸现场
注意:
①:内连接查询出的所有记录都满足条件
②:笛卡尔积:两表记录数的乘积,会导致产生很对垃圾数据
②:外链接
* 左外连接:SELECT * FROM 表1 别名1 LEFT OUTER JOIN 表2 别名2 ON 别名1.xx=别名2.xx
>左表记录无论是否满足条件都会查询出来,而右表只有满足条件才能出来,左表不满足条件的记录,右表部分都为null
* 左外自然连接:SELECT * FROM 表1 别名1 NATURAL LEFT OUTER JOIN 表2 别名2
* 右外连接:SELECT * FROM 表1 别名1 RIGHT OUTER JOIN 表2 别名2 ON 别名1.xx=别名2.xx
>右表记录无论是否满足条件都会查询出来,而左表只有满足条件才会查询出来,右表不满足条件的记录,左表部分都为null
* 右外自然连接:SELECT * FROM 表1 别名1 NATURAL RIGHT OUTER JOIN 表2 别名2
* 全连接:可以使用UNION来完成
(3)子查询:查询中有查询(一条sql语句中有多个select关键字)
* 出现的位置:
* WHERE 后作为条件存在,是可以做运算
* FROM 后作为表存在(多行多列),可以起别名
* 条件
* 单行单列:SELECT * FROM 表1 别名1 WHERE 列 [ =、>、<、>=、<=、!=] (SELECT 列 FROM 表2 别名2 WHERE 条件);
* 单行多列:SELECT * FROM 表1 别名1 WHERE (列1,列2) IN (SELECT 列 FROM 表2 别名2 WHERE 条件);
* 多行单列:SELECT * FROM 表1 别名1 WHERE 列 [ IN、ALL、ANY ] (SELECT 列 FROM 表2 别名2 WHERE 条件);
* 多行多列:SELECT * FROM 表1 别名1 ,(SELECT * FROM 表2 别名2 WHERE 条件) 别名2 WHERE 条件;
JDBC :
一 什么是JDBC ?
JDBC(Java Datebase connectivity) 就是java数据库连接,通俗的来说 :就是用java语言来操作数据库,
原来我们操作数据库都是在控制台使用SQL语句来操作数据库,JDBC是用java语言向数据库发送SQL语句。
二 JDBC原理 图形
三 JDBC的使用步骤 :
*导入jar包 : 驱动
*加载驱动类 :Class.forName("全类名") ---"com.mysql.jdbc.Driver"
*给出 url username password (其中url需要记下来,用户名和密码就是你的MySql登录的用户名和密码)
*url :jdbc:mysql://localhost:3306/你的数据库名
*username : root
*password : 123
*使用DriverManagerl类来得到一个连接对象
四 操作数据库
A:导入jar包 :驱动
B:加载驱动类 :Class.forName("全类名") ---"com.mysql.jdbc.Driver"
C: 给出 url 、 username 、 password (其中url需要记下来,用户名和密码就是你的MySql登录的用户名和密码)
* url:jdbc:mysql://localhost:3306/你的数据库名
* username:root
* password:123
D:使用DriverManager类来得到一个连接对象
②:通过连接对象获取一个Statement对象(sql语句发送器)
Statement statement = connection.createStatement();
③:通过Statement对象发送sql语句
* 执行DDL、DML操作
String sql = "update student set name='你妹的' where id=1";
// 返回值 count 表示这个sql语句执行影响的记录数
int count = mStatement.executeUpdate(sql);
* 执行DQL操作
String sql = "select * from student";
// 返回值 ResultSet 对象表示一个结果集,里面包含了查询出来的所有记录
ResultSet mResultSet = mStatement.execuQuery(sql);
* 获取结果集里面的值:
// mResultSet.next()判断结果集里面有没有下一行数据,有就返回 true,没有就返回 false
while(set.next()){
int id = set.getInt("列名");// getXxx中的Xxx必须和列类型相同(或者全部用getObject(),然后强转)
String name = set.getString("列名");
}
注意:mResuktSet.getMetaData(),返回所有列的编号对象,mResuktSet.getMetaData().getColumnCount() 返回所有的列数(int类型)
(5)JDBC的规范化形式
* 资源要关闭---倒关
* 通过try{ }catch(){ }finally{ // 在此关闭资源,做非空判断,增强代码健壮性 }
(6)预编译:PreparedStatement:是Statement的子接口
* PreparedStatement的作用:
* 防止SQL攻击
? 什么是SQL攻击:
通过特殊值来混淆SQL语句的判断条件,造成SQL操作错误。
* 提高代码的可读性
* 提高效率
* PreparedStatement:获取方式:
①:给出SQL模板,所有的参数使用 ? 来代替
String sql = "select * from student where username=? and password=? ";
②:通过Connection对象获取 PreparedStatement 对象
PreparedStatement preStatement = mConnection.preparedStatement(sql);
* 预编译这个sql模板
* 校验sql的语法
③:为参数赋值:调用 preStatement 中的一系列 setXxx方法为sql语句中的问号赋值
preStatement.setString(1,uesrname);// 为第一个 ? 赋值
preStatement.setString(2,password);// 为第二个 ?赋值
④:调用executeUpdate()或者executeQuery()方法向数据库发送sql语句