目录
一、异常
1.常见异常类型
2.异常体系结构
3.异常处理
(1)finally
(2)throws
二、JDBC
1.JDBC搭建
2.执行SQL语句两种方法
三、MySQL数据库
1.ddl
2.dml
3.dql
(1)字符函数
(2)逻辑处理
(3)数学函数
(4)日期函数
(5)分组函数
(6)条件查询、模糊查询
(7)排序
4.多表
5.关联查询
6.子查询
一、异常
程序在运行过程中出现的不正常现象称之为异常;
例如用户输入数据有问题,读写文件文件被强制删除了,网络传输过程中突然断网;
出现异常后,会导致jvm(虚拟机)停止运行,后续程序无法进行;
java默认异常处理机制:将出现的异常,按类型分类,为每种异常封装一个类来表达;
当出现某种类型异常情况,会抛出此类对象,然后终止虚拟机运行,使用异常处理机制,对程序运行时出现的异常情况捕捉和处理。
注意:代码编写错误不算异常
1.常见异常类型
ArithmeticException 算术异常
ArrayIndexOutOfBoundsException 数组索引越界
StringIndexOutOfBoundsException 字符串索引越界
ClassCastException 类型转换异常
NumberFormatException 数字格式化异常
2.异常体系结构
● Throwable
java.lang.Throwable类是Java程序执行过程中发生的异常事件对应的类的根父类。
Throwable中的常用方法:public void printStackTrace();打印异常的详细信息。
●Error:Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源耗尽等严重情况。一般不编写针对性的代码进行处理。
例如:StackOverflowError(栈内存溢出)和OutOfMemoryError(堆内存
溢出)。
●Exception: 其它因编程错误或偶然的外在因素导致的一般性问题,需要使用针对性的代码进行处理,使程序继续运行。否则一旦发生异常,程序也会挂掉。
3.异常处理
编码时,对可能出现问题的代码预先编译一些处理机制(通过时间经验自己积累)
格式为:
try{
编码时可能出现异常的代码
}catch(异常类型){
处理机制
}
public class Demo2 {public static void main(String[] args) {int a = 10;int b = 0;try {int c = a/b;}catch (ArithmeticException a1){//算数异常a1.printStackTrace();//打印异常信息到控制台,一般在开发阶段使用,供开发人员定位异常信息System.out.println("异常处理");}System.out.println("结束");}
}
注:一个try后可以catch多个类型的异常,但如果其中有Exception类的异常,必须放在最后一个catch中。
(1)finally
无论是否发生异常,代码总能执行
格式:
try{
可能会发生异常的代码
}catch(异常类型 引用名){
异常处理代码
}finally{
必须执行代码
}
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;public class Demo3 {public static void main(String[] args) throws IOException {
//使用场景1:异常没有被捕捉到,后面代码无法执行,但是finally里代码可以运行try{int num = Integer.parseInt("as5");}catch (ArrayIndexOutOfBoundsException a){a.printStackTrace();System.out.println("sd");}finally {System.out.println("saddad");}FileInputStream f = null;
//使用场景2:存放必须要执行的代码try{f = new FileInputStream("D:/as.txt");//文件找不到就会出现异常while (f.read()!=-1){//进行读取操作}}catch (FileNotFoundException ff){ff.printStackTrace();System.out.println("文件找不到异常");}finally {if (f!=null)f.close();//这里我们希望,即使读文件操作异常也要把流对象关闭,而不是程序直接结束}int d = su(10,0);}public static int su(int a, int b){
//使用场景3:无论try还是catch执行return,都要先执行finally里的代码才能returntry{return a/b;}catch (ArithmeticException sa){sa.printStackTrace();System.out.println("算术异常");return -1;}finally {System.out.println("关闭流");}}
}
(2)throws
throws 异常类型 —— 声明表示此方法可能出现给定的异常,且该方法不处理异常,抛给上一级,谁最终调用谁处理。
可以throws多个异常,每个异常用逗号连接,用以扩大范围
import java.io.UnsupportedEncodingException;public class Demo4 {public static void main(String[] args) {//main属于顶层方法了,此处再进行抛出,就给了虚拟机,但是虚拟机不会处理异常,因此必须在这里处理,再抛出就不合适了try {mta();} catch (UnsupportedEncodingException e) {e.printStackTrace();}System.out.println("异常");}public static void mta() throws UnsupportedEncodingException {mtb();System.out.println("mta");}//mtb()模拟一个底层方法,一般我们程序出现异常不会在子类里解决,不然父类还以为程序是正常进行的,一般抛到最高层再处理public static void mtb() throws UnsupportedEncodingException {//throws UnsupportedEncodingException表示此方法可能出现 UnsupportedEncodingException异常String s = "asd";s.getBytes("gbk-1");//根据一个编码表进行转换,System.out.println("mtb");}
}
注:throws用在方法声明部分,表示此方法可能出现的异常类型,该方法不做异常处理,谁调用谁处理
异常细分为:
①检查器异常:编译期间主动提示程序员需要进行处理的异常(编码不支持,文件找不到);
②运行期异常:编译期间不会提示程序员进行处理,程序运行时报出的异常(数组越界,算术异常,类型转换异常);
区别在于异常类有没有继承RuntimeException()方法--ctrl+鼠标左键,点进异常类中进行查看
(3)throw
throw关键字用于显式抛出异常,抛出的时候是抛出的是一个异常类的实例化对象.
语法:throw new 异常类构造方法
(4)自定义异常
现实生活中,根据具体业务创建出的java方法和语句,要想程序给出相应的异常提示,使用java现有的异常类型是远远不够的。
这时候就需要自定义异常,来满足我们业务需求。在方法中使用throw抛出后,必须在方法中try-catch或throws抛出
/*例如这里我们自己规定,当输入的数字<0或>100时抛出要继承Exception/RuntimeException类自定义异常类中往往不写其他方法,只重载需要使用的构造方法即可*/
public class SizeException extends Exception{public SizeException(String message){super(message);}
}class Demo6 {public static void main(String[] args) {try {char c = level(101);}catch (SizeException ar){ar.printStackTrace();System.out.println(ar.getMessage());}System.out.println("结束");}public static char level(int size) throws SizeException {if (size<0||size>100){throw new SizeException("非法分数");}else if (size>0||size<=100){return 'A';}else {return 'B';}}
}
二、JDBC
即java数据库连接。是一种用于执行SQL语句的Java API,可以为多种关系型数据库提供统一访问, 它由一组用Java语言编写的类和接口组成。
因为要连接数据库,因此就需要一些java以外的功能代码。这里放置了mysql官方开发实现的,具体连接数据库的功能代码,需要者自行下载。
提取码:1234
1.JDBC搭建
创建一个新项目,与数据库连接交互具体过程如下:
import java.sql.*;public class Demo1 {public static void main(String[] args) throws ClassNotFoundException, SQLException {//2.加载驱动类(打开与数据库的通信通道)Class.forName("com.mysql.cj.jdbc.Driver");//3.建立与数据库的链接,获得连接对象//URL中是:ip(127.0.0.1):端口(3306)/数据库名?serverTimezone=Asia/Shanghai(这是服务时区,记住就行)String url = "jdbc:mysql://127.0.0.1:3306/test?serverTimezone=Asia/Shanghai";String user = "root";String password = "root";Connection connection = DriverManager.getConnection(url,user,password);//4.发生sql(这里我们对学生选课数据库的专业表进行修改)Statement st = connection.createStatement();st.executeUpdate("insert into major(name)value('数学')");//5.关闭数据库连接(关闭通道)st.close();connection.close();}
}
2.执行SQL语句两种方法
●获得Satement执行sql语句
●Statement st = connection.createStatement();
Satement中的方法:
Int executeUpdate(String sql) 用于执行ddl语句和dml(增,删,改)语句,返回操作的行数
用于执行ddl语句返回0
用于执行dml语句返回操作的行数
ResultSet executeQuery(String sql); 用于执行查询语句 返回一个ResultSet 集合
● 获得PrepareStatement执行sql语句
● 在sql语句中参数位置使用占位符,使用setXX方法向sql中设置参数
● PrepareStatement ps = connection.prepareStatement(sql);
PrepareStatement中的方法:
Int executeUpdate() 用于执行ddl语句和dml(增,删,改)语句 返回操作的行数
用于执行ddl语句返回0
用于执行dml语句返回操作的行数
ResultSet executeQuery(); 用于执行查询语句 返回一个ResultSet 集合
注:PrepareStatement执行sql语句可以进行预先编译----(? 是占位符,表示此处需要接受一个参数)
PreparedStatement ps = connection.prepareCall("insert into student(name,gender,birthday,tel,address,majorid)"+
"values(?,?,?,?,?,?)");
三、MySQL数据库
1.ddl
-- 创建数据库(CREATE DATABASE 数据库名),设置字符集编码(CHARSET 基字符集)
CREATE DATABASE IF NOT EXISTS test CHARSET utf8
-- 删除数据库
DROP DATABASE test;
-- 修改字符集
ALTER DATABASE test CHARSET gbk;
创建数据库表内容
表 表名
列 特定信息 如:姓名,年龄
行 数据 如:张三,19
列的数据类型
字符串型:
char(n)长度为n的定长字符串,设n=5,存入两个字符,其长度还是5,剩下三位会补空格一般存储定长数据
varchar(n)长度为n的变长字符串,设n=5,存入两个字符,长度就为2
日期类型:
date 年月日
datetime 年月日 时分秒
整数型:
TINYINT 字节1
SMALLINT 字节2
MEDIUMINT 字节3
INT 字节4
BIGINT 字节8
浮点型:
decimal(M,D)
M:精度,数据的总长度
D:标度,小数点后的长度
为列添加约束
例如学号,唯一,不能为空,只能有一个学号:
为学号添加主键(PRIMARY KEY)约束(唯一不能重复,不能为空,一个表只能有一个列设置主键)
PRIMARY KEY 主键,在一张表中代表唯一的一条记录,不能为空,不能重复
AUTO_INCREMENT 设置主键列自动增长,只能修饰主键列,而且主键列类型为整形
NOT NULL 不为空
UNIQUE 唯一约束,约束的列不能出现重复数据,可以添加到多个列
CHECK 约束,如设置身高项不超过2.13,height DECIMAL(3,2) check(height<2.13),年龄不小于18岁,age varchar(3) check(age>18),超过的数据不录入数据库
comment'注释' 字段注释
DEFAULT 设置默认值
如下是一个学生表
CREATE TABLE student (num INT PRIMARY KEY AUTO_INCREMENT COMMENT '学号 主键',NAME VARCHAR (10) NOT NULL COMMENT '姓名',gender CHAR (1) NOT NULL DEFAULT '男' COMMENT '性别',birthday DATE,tel CHAR (11) NOT NULL UNIQUE,address VARCHAR (30),height DECIMAL (3, 2) CHECK (height < 2.13),reg_time DATETIME
)
2.dml
插入数据:
方式1: INSERT INTO 表名(列1,列2......,列n) VALUES(值1,值2.....,值n);
方式2: INSERT INTO 表名 set 列名1=值1,..列名n=值n;
方式3: INSERT INTO 表名(列1,列2......,列n) VALUES(值1,值2.....,值n),(值1,值2.....,值n);
方式4:INSERT INTO 表名(列1,列2......,列n) 查询语句(查询的列数与插入列数匹配)
INSERT INTO student (NAME,gender,tel,address,height,reg_time) VALUES('张三','女','12345678212','汉中',1.86,NOW());
INSERT INTO student SET NAME = '李四',gender = '男',tel = '12345678989',height = 1.88;
INSERT INTO student (NAME,gender,birthday,tel,address,height,reg_time) VALUES('王五','男','2003-4-5','12374859632','西安',1.75,NOW()),('赵六','男','2003-4-5','12374857732','西安',1.60,NOW());
修改语句:(注意条件,即where之后的)
UPDATE 表名 SET 列名 = '值' WHERE 列名 = 值
删除语句:
DELETE FROM student -- 没有条件,删除所有语句
DELETE FROM student WHERE num = 51
3.dql
基础查询:
select 查询列表 from 表名
select * from 表名(查询表中所有信息)
查询时可能会出现两行查询结果相同,利用distinct消除其中一行:
select distinct 列名 from 表名
注:sql中 + - * / 只做算术运算,不能当做连接符
(1)字符函数
-- length():获取参数值的字节个数
SELECT NAME,LENGTH(NAME)AS NAME,gender FROM student
-- char_length()获取参数值的字符个数
SELECT NAME,CHAR_LENGTH(NAME)AS NAME FROM student
-- concat(str1,str2,.....):拼接字符串
SELECT num,CONCAT(NAME,':',gender)AS NAME FROM student
-- upper()/lower():将字符串变成大写/小写
SELECT UPPER(NAME),LOWER(NAME) FROM student
-- substring(str,pos,length):截取字符串 位置从1开始
SELECT SUBSTRING(NAME,1,1) FROM student
-- instr(str,指定字符):返回子串第一次出现的索引,如果找不到返回0
SELECT INSTR(NAME,'张') FROM student
-- trim(str):去掉字符串前后的空格或子串,trim(指定子串 from 字符串)
SELECT NAME,CHAR_LENGTH(TRIM(NAME)) FROM student
-- lpad(str,length,填充字符):用指定的字符实现左填充将str填充为指定长度
SELECT LPAD(NAME,5,'a') FROM student
-- rpad(str,length,填充字符):用指定的字符实现右填充将str填充为指定长度
SELECT RPAD(NAME,5,'b') FROM student
-- replace(str,old,new):替换,替换所有的子串
SELECT REPLACE(NAME,'张','找')FROM student
(2)逻辑处理
-- case when 条件 then 结果1 else 结果2 end; 可以有多个when
SELECT height,(CASE WHEN height>=1.80 THEN '高个子' WHEN height>=1.75 THEN '正常身高' ELSE '矮个子' END)AS height FROM student
-- ifnull(被检测值,默认值)函数检测是否为null,如果为null,则返回指定的值,否则返回原本的值
SELECT NAME,IFNULL(address,'暂未录入')AS adddress FROM student
-- if函数:if else的 效果 if(条件,结果1,结果2
SELECT NAME,IF(height>=1.80,'高个子','正常身高')FROM student
(3)数学函数
-- round(数值):四舍五入
SELECT NAME,ROUND(height)FROM student
-- ceil(数值):向上取整,返回>=该参数的最小整数
SELECT NAME,CEIL(height)FROM student
-- floor(数值):向下取整,返回<=该参数的最大整数
SELECT NAME,FLOOR(height)FROM student
-- truncate(数值,保留小数的位数):截断,小数点后截断到几位
SELECT NAME,TRUNCATE(height,1)FROM student
-- mod(被除数,除数):取余,被除数为正,则为正;被除数为负,则为负
SELECT NAME,MOD(num,3)FROM student
-- rand():获取随机数,返回0-1之间的小数
SELECT NAME,RAND()FROM student
(4)日期函数
-- now()
SELECT NAME,NOW(),CURDATE(),CURTIME() FROM student
-- 日期格式化
SELECT NAME,YEAR(reg_time),MONTH(reg_time),DAY(reg_time)FROM student
-- 字符串格式化为日期类型
-- 将日期格式化为指定字符串
SELECT DATE_FORMAT(birthday,'%Y-%m')FROM student
-- 计算两日期间相差天数
SELECT DATEDIFF(NOW(),birthday)FROM student
(5)分组函数
-- sum 求和、avg 平均值、max 最大值、min 最小值、count 计数(非空)
-- sum,avg一般用于处理数值型max,min,count可以处理任何类型
SELECT SUM(num)FROM student
SELECT AVG(num) FROM student
SELECT MAX(height)FROM student
SELECT MIN(height)FROM student
-- count函数的一般使用count(*)用作统计行数
SELECT COUNT(*)FROM student
-- 以上分组函数都忽略null值
(6)条件查询、模糊查询
-- select <结果> from <表名> where <条件>
-- and 所有条件均要满足
SELECT * FROM student WHERE height >= 1.80 AND address = '汉中' AND num <= 46
-- or 满足一个即可
SELECT *FROM student WHERE height >=1.70 OR height >=1.80
-- 不等于
SELECT *FROM student WHERE address != '汉中'
SELECT *FROM student WHERE address <> '汉中'
-- 模糊查询 like %字符%,要查字符串第几个字,其余字就要用%填充 通配符:%
SELECT *FROM student WHERE NAME LIKE '张%'
-- between and(两者之间,包含临界值) 相当于 条件一 and 条件二
SELECT *FROM student WHERE height >=1.70 AND height <=1.80
-- 查身高 in 判断某字段的值是否属于in列表中的某一项 相当于height = 1.75 or height = 1.86 or height = 1.88
SELECT *FROM student WHERE height IN(1.75,1.86,1.88)
(7)排序
-- 排序 默认升序(ASC)
SELECT *FROM student ORDER BY height
-- DESC降序
SELECT *FROM student ORDER BY height DESC
-- 多个排序条件,依次执行
SELECT *FROM student ORDER BY birthday DESC,height ASC
-- 什么排序都没有,默认主键升序
SELECT *FROM student
(8)数量限制、分组查询
-- 数量限制 limit子句:对查询的显示结果限制数目 (sql语句最末尾位置)
-- limit 开始位置(开始位置为0),查询的数量
-- 用于网页物品分页,一次查询一部分数据,提高效率
SELECT *FROM student LIMIT 0,2 -- n 表示当前页码
-- 分组查询
-- group by 分组条件(列名)出现在sql语句末尾
SELECT COUNT(*),gender FROM student GROUP BY gender
-- 分组统计名字数量,查询重复名字
-- where是对原始表中数据过滤
-- HAVING 在 group by 后使用,为分组的数据添加过滤条件
SELECT COUNT(*)AS n,NAME FROM student GROUP BY NAME HAVING COUNT(*)>1
4.多表
第一范式:确保每列保持原子性,即数据库表中的所有字段值都是不可分解的原子值
第二范式:要有主键,其他字段依赖于主键。因此也就成为唯一的了
第三范式:确保每列都和主键列直接相关,而不是间接相关,要求一个数据库表中不包含已在其它表中包含的非主关键字信息。即一个表关联另一个表的主键即可,没必要再关联另一个表其余的冗余信息。因为通过那个主键,就可直接查询到另一个表的所有其他信息
外键
-- majorid称为外键,外键必须与另一个表主键关联,类型一致
-- 例如,学生表与专业表关系:多对一关系
-- 添加外键约束,不添加约束就会随意操作数据,致使数据极不安全
-- 为外键加约束,保证数据完整性
ALTER TABLE student ADD CONSTRAINT fk_student_major_on_majorid FOREIGN KEY(majorid ) REFERENCES major(id)
5.关联查询
关联查询会引起笛卡尔积现象
-- 笛卡尔乘积现象:表1有m行,表2有n行,结果=m*n
-- 发生原因:没有有效的连接条件
-- 如何避免:添加有效的连接条件
-- 语法:Select 结果 from 表1,表2 where 表1.column1 = 表2.column2
(1)内连接
-- 内关联 只筛选出满足条件的
SELECT
s.num,
s.name,
s.gender,
m.name
FROM student s INNER JOIN major m ON s.majorid = m.id
(2)外连接
-- 外连接 左外连接 显示表一所有部分,表一表二相交部分
-- select 结果 from 表1 left join 表2 on 表1.column1 = 表2.column2
SELECT *FROM student s LEFT JOIN major m ON s.majorid = m.id
-- 右外连接 表二所有部分,表一表二相交部分
SELECT* FROM student s RIGHT JOIN major m ON s.majorid = m.id
-- 统计每个专业人数
SELECT COUNT(s.num)COUNT,m.name
FROM student s RIGHT JOIN major m
ON s.majorid = m.id
GROUP BY m.name
6.子查询
出现在其他语句中的select语句,称为子查询或内查询;外部的查询语句,称为主查询或外查询
按子查询出现的位置分类:
-- from后面:支持表子查询(结果集一般为多行多列)
-- where:支持标量子查询(结果集只有一行一列),列子查询(结果集只有一列多行)
-- 查身高最高的(标量子查询)
SELECT * FROM student WHERE height = (SELECT MAX(height) FROM student)
-- 查身高等于165 和 175的学生(列子查询)
SELECT *FROM student WHERE height IN (SELECT height FROM student WHERE height = 1.65 OR height = 1.75)
-- 查重名的(表子查询)
SELECT *FROM (SELECT s.name,COUNT(*)c FROM student s GROUP BY s.name)sc WHERE sc.c>1
javaSE和MySQL数据库的知识总结到这里就结束了,如有不同见解,欢迎在评论区探讨!