一、Java基础回顾
1.标识符
表示在Java程序中需要起名字
- 组成: 字母(a-z,A-Z)、数字(0-9)、下划线(_)、$
- 规则:
- 不能以数字开头
- 不能Java的关键字和保留字(goto、const)
- 长度无限制
- 严格区分大小写 public
- 起名字:
- 不能用中文(用英文)
- 起变量名、方法名(驼峰命名) likeYouMe
- 类名 每个单词的首字母都需要大写
2.Java基本数据类型
- 整数类型(默认int)
- byte 1字节 8位 -128 – 127 -2^7 — 2^7-1
- short 2字节 16位 -2^15 - 2^15-1
- int 4字节 32位 -2^31 - 2^31-1
- long 8字节 64位 … L/l
- 浮点(double)
- 单精度 float 4字节 32位 F/f
- 双精度 double 8字节 64位
- 字符
- char ’ ’
- 布尔类型
- boolean true/false
3.数据类型转换
- 自动转换
- 小---->大
- 整数----->小数
- char---->int (ASCII码表)
- 强制转换(可能会损失精度)
- 大转小
- 小数转整数
- int —>char
- double x=23.8; int y=(int)x;
4.引用数据类型
- String类
- 数组
- 类
- 对象
- 集合
- 引用数据类型和基本类型区别: JVM的内存分布不同(栈内存、堆内存中)
- 面试题:JVM的内存分布(5个部分)、OOM(内存溢出)
5.流程控制语句
-
if语句
-
单分支
if(boolean表达式){ 满足条件执行 }
-
双分支
if(boolean表达式){ 表达式成立时执行 }else{ 表达式不成立时执行 }
-
多分支
if(boolean表达式1){
表达式成立时执行
}else if(boolean表达式2){
表达式2成立时执行
}else{以上都不成立时执行
}
-
-
switch语句
switch(byte/short/int/char/String){ case 具体情况值:执行内容;break default:默认执行 }
-
while循环
先判断后执行
while(boolean表达式){ 满足条件执行 循环体 }
-
do…while循环
先执行后判断
do{
循环体
}while(boolean表达式);
- for循环
for(起始于语句;判断语句;迭代语句){
循环体
}
- break和continue的区别
相同:都表示结束
不同:
break既可以用在循环中也可用于switch语句
continue只能用于循环中 表示结束本轮循环进入下一轮循环
6.运算符
-
算术运算符 +、-、*、/、%、++、-- 自增/自减 在右(先赋值后运算) 在左(先运算后赋值)
当多种类型进行混合运算时其结果类型以最大的为准
当变量和字符串进行混合运算时,字符串的左边正常运算,右边直接拼接
-
赋值运算符 +=、-=、*=、/=、%=
a+=b =》 a=a+b
-
比较运算符 >、<、>=、<=、==、!=
-
逻辑运算符 &(一假则假)、|(一真则真)、^(异或—相同为假、相异为真)、&&(短路与)、||(短路或)、!(取反面)
-
位运算符 &、|、^
-
三元(目)运算符 boolean表达式?表达式成立执行:表达式不成立时执行
7.数组
-
一维数组
-
声明方式:
数据类型 [] 数组名={元素1,元素2.....}; int [] arr={1,2,3,4,5,6,7,8} 数据类型 []数组名=new 数据类型[]{元素1,元素2,元素3....} int [] arr1=new int[]{5,6,7,8}; 数据类型 []数组名=new 数据类型[长度]; int [] arr3=new int[4]; 数组存放在堆内存中,有默认值 int 0 float/double 0.0 char 空 String null 获取数组长度: 数组名.length arr.length 数组的最小下标是0,最大下标 数组名.length-1 获取数组的元素:数组名[下标] arr1[1] 数组的长度一旦确定是不能更改的 遍历数组: 普通for: for(int 下标=0;下标<数组名.length;下标++){ System.out.println(数组名[下标]) } 增强for: for(数组类型 自定义变量:数组名){ System.out.println(自定义变量) } int []x={1,2,3,4,5,6}; //增强for遍历 for(int y:x){ System.out.println(y); } //使用Arrays工具类遍历 Arrays.toString(数组名);
-
-
多维数组
二维数组: 数据类型[][]数组名={{元素...},{元素...},{元素...}}; int [][] arr={{1,2,3,4,5,7},{1,5,6},{1,9,7}}; 数据类型 [][]数组名=new 数据类型[外长度][内长度]; int [][]arr2=new int[3][4]; 获取元素:数组名[外下标][内下标] arr[1][1] 遍历二维数组 for(int 外下标=0;外下标<数组名.length;外下标++){ for(int 内下标=0;内下标<数组名[外下标].length;内下标++){ System.out.println(数组[外下标][内下标]) } } 三维数组: int [][][]arr3={{{1,2,3},{4,5,6},{7,8,9},{3,4,5}}}
-
数组的排序(面试题)
- 选择排序
- 冒泡排序
二、面向对象回顾
1.面向对象的基础内容
-
了解类和对象
- 什么类? 具有共性特征的事务 人、猫、狗、桌子
- 什么对象? 客观存在的唯一个体 张三、李四、翠花
- 类与对象的关系 类是对象的模板,对象是类的具体化
-
面向对象编程思想 OOP
具体的业务需求转换成具体的模型
C 面向过程 C/S结构 客户端/服务器 桌面应用
Java 结果 Java企业级应用 B/S结构 浏览器/服务器
找对象?
1.sun公司提供好的一些工具类,我们了解并使用即可 Scanner、Random
2.自定义类(重点)
-
自定义类
[修饰符] class 类名{ 成员变量 [修饰符] 数据类型 变量名; 成员方法 [修饰符] 返回值类型(有返回/void) 方法名([形参]){ 方法的执行内容 } } public class Person { //成员变量 /* 修饰符 public 公共 protected 受保护的 默认 private 私有的 */ public String name;//用户名 public String password;//密码 public char sex;//性别 //成员方法 public void play(){ //无返回值类型方法 System.out.println("我正在和翠花玩游戏"); } public String eat(){//有返回值类型的方法 return "面条"; } public void study(String book){ //有形参的方法 System.out.println(book); } //静态方法(类方法) public static void sprot(){ System.out.println("我喜欢和方俊老师打篮球"); }
-
创建对象和调用
类名 对象名=new 类名(); 调用属性: 对象名.属性名 调用方法: 对象名.方法名([实参]) //创建对象 Person person=new Person(); System.out.println(person.sex); //调用方法 person.play(); person.study("21天精通Java");//调用有参数的方法需要传递实参
-
构造函数
[修饰符] 类名([参数]){} public class Animal { public String name; public int age; public String js; //使用构造函数来进行赋值 public Animal(String name,int age,String js){ //方法中的变量和方法外变量重名时使用的是方法内部的变量 //使用this this表示当前对象 当前类 this.属性名表示全局 this.name=name; this.age=age; this.js=js; } public Animal(){ //调用上面的构造函数 //构造函数之间进行调用使用this([参数]) this("蓝猫",3,"喵喵"); } public Animal(String name) { this.name = name; } public Animal(String name, int age) { this.name = name; this.age = age; } public static void main(String[] args) { //创建对象时默认会调用构造函数 //如果类中没有构造函数JVM会默认提供一个参数为空的构造函数 //Animal animal=new Animal(); // animal.name="哈士奇"; // animal.age=2; // animal.js="呜呜"; Animal animal=new Animal("蓝猫",1,"喵喵"); System.out.println(animal.name); } }
-
方法的重载
在同一类中,方法名相同,参数列表不同 public void add(){ System.out.println("和为:"+(n1+n2)); } //方法的重载 public void add(int num1,int num2){ System.out.println(num1+num2); }
-
this关键字
this表示当前类,当前对象 使用场景: 当局部变量和全局变量重名 使用this来进行区分 this.属性名表示全局变量 this()表示当前类的构造函数 使用场景: 构造函数之间的调用
-
return关键字
使用场景:一般用于有返回值的方法中,用于结束方法并返回结果,一般放在方法的尾行 1)return 数据; 用于有返回值的方法中,结束方法并返回结果 2)return; 用于无返回值的方法中,表示结束
-
static关键字
public class StaticDemo { public static String name;//修饰成员变量 //修饰成员方法 public static void play(){ System.out.println("pppp"); } //静态代码块 static{ System.out.println("代码块"); } public static void main(String[] args) { //静态成员直接使用类名调用 StaticDemo.name="zhangsan"; StaticDemo.play(); //如果类中有静态代码块,会最先执行,并且只执行一次 } }
-
形参和实参
形参一般是在方法的小括号中 实参一般调用有形参的方法时需要传递的具体数值
2.面向对象的特征
-
封装
1)针对成员变量的私有化,需要使用private来进行私有化 格式: private 数据类型 变量名; 必须要提供get和set方法 public class Cat { private int cid;//私有化以后,除了本类,其他类是无法来进行访问的 public String sex; //使用get和set方法提供给外界来操作属性 //get方法表示获取 public int getCid(){ return cid; } //set方法表示设置值 public void setCid(int cid){ this.cid=cid; } public String getSex(){ return sex; } public void setSex(String sex){ if(sex.equals("男")||sex.equals("女")){ this.sex=sex; }else{ this.sex="有黑客入侵"; } } }
2)方法的封装-将项目中的某个功能模块或者是重复的代码进行抽取,方便复用
-
继承
含义:某一个类可以派生出多个子类,把这个类叫父类,派生出来的类叫子类 关键字: extends 语法: class 子类名 extends 父类名{} 父类: public class Animal { public String name; public int id; private String sex;//男 //如果父类中有构造函数,子类必须要进行调用 public Animal(String name){ System.out.println("父类的构造函数"); } public void play(){ System.out.println("动物喜欢玩"); } void eat(){ System.out.println("吃水果"); } }
子类:
public class Dog extends Animal{ //父类的属性不能满足子类的需求时,需要子类进行自由扩展 public String food; public Dog(){ super("mm"); } //子类继承了父类 有啥好处 //子类可以拥有父类的一些属性和方法 //子类不能继承父类的私有属性和方法,构造函数也无法继承 //因为创建子类对象时,会先创建父类对象,所以需要在子类构造函数中调用父类的构造函数 //每个类中的默认构造函数中都会调用父类的参数为空的构造函数 //父类中的方法不能满足子类的需求1.重写父类方法 2.自定义 //override重写、覆盖、覆写 //1.子类重写父类的方法必须要原型一致(参数、返回值类型、方法名) //2.修饰符的范围>=父类 public>protected >默认 >private //overload重载 //子类想要调用父类的方法和属性 使用super(表示父类或父类对象) @Override public void play() { System.out.println("狗喜欢吃肉"); } @Override void eat() { super.eat(); } public void sleep(){ //调用父类的方法 super.eat(); //调用父类的属性 System.out.println(super.id); } }
-
多态
含义:事物的多种形态 变量:类型转换 自动转换 强制转换 对象:建立在继承的基础上 子类向上转型成父类 public class StudentTest { public static void main(String[] args) { //子类向上转型成父类 Person person=new Student(); //子类向上转型成父类以后,子类的功能暂时隐藏,只能显示父类的信息 //如果父类的方法被子类重写,那么调用的那个方法就是子类重写过后的方法 person.eat(); person.run(); //父类向下转型成子类 // Student stu= (Student) new Person();// ClassCastException 类转换异常 //如果父类要向下转型成子类,该父类必须是由子类向上转型而成 //父类向下转型成子类,子类的功能全部恢复 Student stu= (Student) person; //instanceof 判断某个对象是否属于某个类 结果为true,才能向下转型 System.out.println(person instanceof Student); stu.eat(); } }
-
抽象
public abstract class Shape { //图形类,计算面积和周长 // 矩形、正方形、圆形 //不同的图形,计算面积和周长的方法不同 /** * abstract表示抽象 * 被abstract修饰的方法叫抽象方法 * 抽象方法没有方法体 * 有抽象方法的类一定是抽象类 * 抽象类不一定有抽象方法 * abstract关键字只能修饰类和方法 * 抽象类不能创建对象,但是可以声明 */ public abstract void area(); public abstract void per(); public static void main(String[] args) { //匿名内部类 //局限性比较大,只能使用一次,没办法调用 //某个抽象类的内容只需要实现一次 Shape shape= new Shape() { @Override public void area() { } @Override public void per() { } }; } } public class React extends Shape{ //子类继承抽象类,必须要重写抽象类中所有的抽象方法 public int length; public int width; @Override public void area() { System.out.println("面积:"+length*width); } @Override public void per() { System.out.println("周长:"+(length+width)*2); } }
-
接口
public interface Shape extends Shape01,Shape02 { /** * 接口的出现是为了弥补Java单继承的不足 * 接口不是类 * 接口中的方法都是抽象方法,接口中的关键字不需要带abstract关键字 * 接口中不能声明变量,可以声明常量 * 接口和接口之间可以进行多继承 * */ public void area(); } public interface Shape04 { public void per(); } //implements 完成,实现 //接口实现类需要实现(重写)接口中所有的方法 //接口实现类可以同时实现多个接口 public class Square implements Shape,Shape04{ public int length; @Override public void area() { System.out.println("正方形的面积"+length*length); } @Override public void per() { System.out.println("正方形的周长是:"+length*4); } } public class Shapetest { public static void main(String[] args) { Square square = new Square(); square.length=8; square.area(); square.per(); } }
三、JavaAPI回顾
1.Object类
Object类是所有类的父类,基类
构造函数
Object()
常用方法
equals(Object obj) 判断两个对象是否相等
hashCode() 获取对象的哈希码值
toString() 将对象转换成字符串
举例1
public class ObjectDemo01 {
public static void main(String[] args) {
Object o = new Object();
System.out.println(o);//首地址信息 堆内存的数据都有地址信息
Object o1 = new Object();
System.out.println(o.equals(o1));//每个对象的首地址信息都不一样
System.out.println(o.hashCode());//每个对象的哈希码是不一样的
System.out.println(o1.hashCode());
System.out.println(o.toString());//将首地址信息变成字符串
}
}
举例2
public class Person {
public String name;
public int sno;
public Person(String name, int sno) {
this.name = name;
this.sno = sno;
}
@Override
public boolean equals(Object o) {
//先判断 o是否为null
if(o==null){
return false;
}
//判断当前对象和o的首地址是否一致
if(this==o){
return true;
}
//向下转型需要先使用instanceof判断
if(o instanceof Person){
Person p=(Person) o;
return this.name.equals(p.name)&&this.sno==p.sno;
}
return false;
}
@Override
public String toString() {
return "["+name+","+sno+"]";
}
public static void main(String[] args) {
//如果两个person对象的name和sno的值一致那么可以判断这两个对象为同一个对象
//equals()来比较两个对象是否为同一个对象
Person lzm01 = new Person("lzm", 110);
Person lzm02 = new Person("lzm", 110);
System.out.println(lzm01.equals(lzm02));
//打印对象名的时候需要输出的是属性的值
System.out.println(lzm01); //打印对象名的时候默认调用tostring
}
}
2.final关键字
表示最终的
使用场景:
1.final可以修饰class 表示最终类(没有子类)
public final class person{}
2.final修饰变量 表示常量
public final int x=9;
3.final修饰方法 最终方法 不能够被重写,但是可以调用
public final void test(){}
3.String类
表示字符串类,因为被final修饰,所以表示最终类
String字符串一旦创建以后,值不能更改 通过StringBuffer、StringBulider可以实现值的更改
public class StringDemo {
public static void main(String[] args) {
//构造函数
String str=new String();//创建空字符串
byte []by={12,9,87,45,3};
String str01 = new String(by);//将byte数组转换成字符串
System.out.println(str);
char []ch={'c','a','2','u'};
String str02 = new String(ch);//将char数组转换成字符串
System.out.println(str02);
//常用方法
String str03="ahjhsadjfhsajwqerwq";
String str04="XYZ";
String str05=" aaa ";
//根据下标找出对应字符
System.out.println(str03.charAt(5));
//拼接字符串
System.out.println(str03.concat("XYZ"));
//是否以指定字符串结尾
System.out.println(str03.endsWith("q"));
//是否以指定字符串开头
System.out.println(str03.startsWith("a"));
//比较字符串的值是否相等
System.out.println(str03.equals("dfghj"));
//字符串变大写
System.out.println(str03.toUpperCase());
//字符串变小写
System.out.println(str04.toLowerCase());
//忽略大小写比较
System.out.println(str03.equalsIgnoreCase(str03.toUpperCase()));
//将字符串变成byte数组
byte[] bytes = str03.getBytes();
System.out.println(Arrays.toString(bytes));
//查询指定字符第一次出现的位置
System.out.println(str03.indexOf('s'));
//查询最后一次出现的位置
System.out.println(str03.lastIndexOf('s'));
//获取字符串的长度
System.out.println(str03.length());
//判断字符串是否为空
System.out.println(str03.isEmpty());
//替换
System.out.println(str03.replace("sa","xx"));
//以指定字符来进行切割
String[] js = str03.split("j");
System.out.println(Arrays.toString(js));
//将字符串变成char数组
char[] chars = str03.toCharArray();
System.out.println(Arrays.toString(chars));
System.out.println(str05);
//去除字符串左右两边的空格
System.out.println(str05.trim());
//将其他类型转换成字符串对象
String s = String.valueOf(5);
System.out.println(s);
String str06="abc";
String str07="abc";
//如果当前字符串在参数字符串前返回负数,否则正数,相等为0
System.out.println(str06.compareTo(str07));
}
}
4.StringBuffer和StringBuilder
public class StringBufferAndStringBuilder {
public static void main(String[] args) {
/**
* String、StringBuffer、StringBuilder区别
* String是不可变字符串,一旦创建值不能更改
* StringBuffer和StringBuider是可变字符串,值是可以更改的
* StringBuffer是线程安全的,但是效率会低
* StringBuilder是线程非安全的,效率高
*/
StringBuffer sb = new StringBuffer();//创建空可变字符串
System.out.println(sb);
StringBuffer sb01 = new StringBuffer("aaaa");//将字符串变成可变字符串
System.out.println(sb01);
//append追加
StringBuffer sb03 = sb01.append("xyz");
System.out.println(sb03);
System.out.println(sb01.equals(sb03));
String str="abc";
String str01 = str.concat("xyz");
System.out.println(str.equals(str01));
//delete删除
System.out.println(sb03.delete(1,3));
//insert插入
System.out.println(sb03.insert(3,"ooo"));
//reverse反转
System.out.println(sb03.reverse());
//将可变字符串转换成不可变
String str04 = sb03.toString();
//练习: 通过控制台输入一个字符串,并判断该字符串是否对称
}
}
5.包装类
Java中8种基本数据类型 包装类
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
public class PackClass {
public static void main(String[] args) {
//包装类中需要重点掌握各个类型之间的转换方式
// String、包装类、基本类型 (char不参与)
// 1.基本类型--->String
int x=20;
//方式1 valueOf
String str = String.valueOf(x);
//方式2 直接拼接“”
String str01=x+"";
System.out.println(str01);
//2. 基本类型---->包装类
int y=30;
//方式1 valueOf
Integer integer = Integer.valueOf(y);
System.out.println(integer);
//方式2 自动装箱
Integer integer1=y;
//3.包装类---->基本类型
//方式1 intValue()
int z=integer1.intValue();
//方式2 自动拆箱
int m=integer1;
//4.包装类---->String
String str03 = integer1.toString();
//5.String ----> 基本类型
String str08="123";
int i = Integer.parseInt(str08);//JavaWeb项目
System.out.println(i);
double v = Double.parseDouble(str08);
//6.String---->包装类
//String value="abc";
//Integer integer2 = Integer.valueOf(value);//NumberFormatException
// System.out.println(integer2);
//Character 字符向上转型而成
//判断是否为数字
boolean s = Character.isDigit('1');
//判断是否为字母
boolean b = Character.isLetter('1');
System.out.println(b);
}
}
6.Math类
Math表示数学类
public class MathDemo {
public static void main(String[] args) {
//绝对值
System.out.println(Math.abs(-1));
//向上取整
System.out.println(Math.ceil(12.3));
//向下取整
System.out.println(Math.floor(12.9));
//取幂
System.out.println(Math.pow(2,3));
//随机数 0-1之间
System.out.println(Math.random());
//四舍五入
System.out.println(Math.round(12.5));
//随机数 100-250之间的随机数
int y= (int)(Math.round(Math.random()*150)+100); //0-150
System.out.println(y);
// 360-750 之间的随机数
long x=Math.round(Math.random()*390+360);
}
}
7.Date类
Date表示日期时间类
public class DateClass {
public static void main(String[] args) {
//获取计算机的本地时间
Date date = new Date();
System.out.println(date);
//获取毫秒值 1s=1000ms
long time = date.getTime();
System.out.println(time);
//将毫秒值转换为具体时间
Date date02 = new Date(165411686l);
System.out.println(date02);
//将时间转换本地时间格式
System.out.println(date02.toLocaleString());
}
}
8.Calendar类
Calendar表示日历类
public class CalendarClass {
public static void main(String[] args) {
//获取计算机的时间
Calendar instance = Calendar.getInstance();
System.out.println(instance);
//常用方法
Date time = instance.getTime();//转成Date对象
int i = instance.get(Calendar.DAY_OF_MONTH);//获取日期中的字段值
int y = instance.get(Calendar.DAY_OF_YEAR);
System.out.println(y);
}
}
9.日期格式化
SimpleDateFormat用于格式化日期和用于将时间字符串解析成Date
public class SDFClass {
public static void main(String[] args) throws ParseException {
//日期格式化 SimpleDateFormat
// SimpleDateFormat sdf = new SimpleDateFormat();
//设置需要日期格式 2022年6月29日 15时39分20秒
// String str="yyyy年MM月dd日 HH时mm分ss秒";
//将格式应用到sdf对象中
// sdf.applyPattern(str);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
//时间
Date date = new Date();
//开始格式时间
String time = sdf.format(date);
System.out.println(time);
parseTime();
}
//解析时间
public static void parseTime() throws ParseException {
//将字符串转换成Date对象
String str="2022/06/29 15:44:44";
//创建SimpleDateFormat
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");//格式一定要跟字符串的保持一致,否则无法解析
//解析字符串时间
Date date = sdf.parse(str);
System.out.println(date);
}
}
四、异常处理
1.异常概述
Exception表示是异常
Error 表示是错误
Exception主要是代码在编译或者是运行的过程中产生的一些bug,可以来进行修复的
Error 主要是的错误不是来源于代码,硬件,软件,配置 JVM内存溢出
一般在程序中的异常会有两种情况:编译期异常、运行时异常
编译期异常:代码在编译的过程中产生的报错,一般的话IDE工具会有提示,可以即时修复
运行时异常:代码在运行的时候产生的报错,500
2.常见的异常
public class ExceptionClass {
public static void main(String[] args) {
//运行时异常 (RuntimeException)
//System.out.println(1/0);//ArithmeticException 算术异常
int []x={1,2,3};
//System.out.println(x[4]);//ArrayIndexOutOfBoundsException 下标越界异常
String str=null;
//System.out.println(str.length());//NullPointerException 空指针异常
//Student stu= (Student) new Person();//ClassCastException 类转换异常
//编译期异常 Exception
// ParseException
}
public static void parseTime() throws ParseException {
//将字符串转换成Date对象
String str="2022/06/29 15:44:44";
//创建SimpleDateFormat
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");//格式一定要跟字符串的保持一致,否则无法解析
//解析字符串时间
Date date = sdf.parse(str);
System.out.println(date);
}
}
3.异常处理方式
public class ExceptionClass02 {
public static void main(String[] args) {
//异常处理
//1.throws 抛出异常 不能解决异常,将这个问题留给下一个调用者解决
//语法: public void 方法名() throws 异常名{}
//2.try....catch 捕获异常并解决
/*
* try{
* 可能会发生异常的代码
* }catch(ArithmeticException e){
* 解决方案
* }catch(ArrayIndexOutOfBoundsException e){
* 解决方案
* }finally{最终
* 不管是否有发生异常都会执行
* }
* */
try{
System.out.println(1/1);
String str="";
System.out.println(str.length());
}catch(ArithmeticException e){
System.out.println("除数不能为0");
}catch(NullPointerException e){
System.out.println("字符串的值为null");
}finally{
System.out.println("我时finally");
}
}
}
4.自定义编译期异常
public class Person {
/*
* 自定义异常
* 自定义编译期异常
* 类要继承Exception
* 自定义运行时异常
* 类要继承RuntimeException
* */
private String name;
private int age;//0-100
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) throws AgeLT0Exception, AgeGT100Exception {
if(age<0){
//触发小于0的异常
//触发异常的关键字 throw
throw new AgeLT0Exception();
}else if(age>=100){
//触发大于100的异常
throw new AgeGT100Exception();
}else{
this.age = age;
}
}
public static void main(String[] args) throws AgeLT0Exception, AgeGT100Exception {
Person person = new Person();
person.setAge(100);
}
}
public class AgeLT0Exception extends Exception{
public AgeLT0Exception(){
super("年龄不能小于0");
}
}
public class AgeGT100Exception extends Exception{
public AgeGT100Exception(){
super("年龄不能超过100");
}
}
5.自定义运行时异常
public class Person {
/*
* 自定义异常
* 自定义编译期异常
* 类要继承Exception
* 自定义运行时异常
* 类要继承RuntimeException
* */
private String name;
private int age;//0-100
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age){
if(age<0){
//触发小于0的异常
//触发异常的关键字 throw
throw new AgeLT0Exception();
}else if(age>=100){
//触发大于100的异常
throw new AgeGT100Exception();
}else{
this.age = age;
}
}
public static void main(String[] args) {
Person person = new Person();
person.setAge(100);
}
}
public class AgeLT0Exception extends RuntimeException{
public AgeLT0Exception(){
super("年龄不能小于0");
}
}
public class AgeGT100Exception extends RuntimeException{
public AgeGT100Exception(){
super("年龄不能超过100");
}
}
五、集合
1.集合概述
集合的特征:
1.长度无限制
2.集合只能存放对象类型
3.类型无限制
2.Collection集合常用方法
public class CollectionClass {
public static void main(String[] args) {
/**
* Collection集合接口
* 子接口: List、Set
* 子接口的实现类: ArrayList、HashSet
* 常用方法:
* 增:
* add()
* addAll()
* 删:
* clear()
* remove(Object o)
* removeAll(Collection<?> c)
* retainAll(Collection<?> c)
* 查:
* contains(obj)
* containsAll()
* isEmpty()
* iterator()
* size()
* 其他:
* toArray()
*
*/
//创建集合对象
Collection col=new ArrayList();
//添加元素
col.add(123);
col.add(456);
col.add(789);
Collection col01=new ArrayList();
//添加元素
col01.add("abc");
col01.add("opq");
col01.add("xyz");
//将col01添加到col中
col.addAll(col01);
System.out.println(col);
//是否包含指定元素
System.out.println(col.contains("xyz"));
//是否包含参数集合
System.out.println(col.containsAll(col01));
//是否为空
System.out.println(col.isEmpty());
//获取集合长度
System.out.println(col.size());
//迭代器,遍历集合
Iterator it = col.iterator();
while(it.hasNext()){//判断是否有元素可以迭代
System.out.println(it.next());//获取元素
}
//将集合变数组
Object[] array = col.toArray();
//移除不同元素
col.retainAll(col01);
System.out.println(col+"----");
//移除指定集合
col.removeAll(col01);
//移除指定元素
col.remove(123);
//清空集合
col.clear();
System.out.println(col);
}
}
3.List集合
public class ListClass {
/**
* List集合 有序可重复的集合 本质上跟数组类似
* 实现类:
* ArrayList、LinkedList、Vector
* 三个实现类的区别 ?
* 常用方法:
* get(int index)
* remove(int index)
* set(int index, E element)
* 注意:创建集合时需要设定泛型,方便后续操作
*/
public static void main(String[] args) {
ArrayList<Integer> list=new ArrayList<>();
list.add(123);
list.add(456);
list.add(789);
//根据下标找出对应的元素
System.out.println(list.get(0));
//移除自定位置的元素
list.remove(2);
//修改指定位置的元素
list.set(1,666);
System.out.println(list);
//list的集合的遍历方式
//方式1:迭代器遍历
Iterator<Integer> it = list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
System.out.println("-----");
//方式2:普通for循环
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
System.out.println("------");
//方式3:增强for循环
// 集合类型 元素名:集合名
for(Integer in:list){
System.out.println(in);
}
}
}
4.Set集合
public class SetClass {
public static void main(String[] args) {
/**
* Set集合 无序不可重复
* 实现类:
* HashSet、LinkedHashSet、TreeSet
*/
Set<Integer> set=new HashSet<>();
set.add(123);
set.add(456);
set.add(789);
set.add(789);
System.out.println(set);
//需求:通过控制台输入一段字符串,然后找出该字符串中的重复出现的字符
//abcaxyzx a,x
}
}
5.Map集合
public class MapClass {
public static void main(String[] args) {
/**
* map集合 属于键值对集合
* 实现类:
* HashMap
* 常用方法:
* clear()
* containsKey(Object key)
* containsValue(Object value)
* entrySet()
* get(Object key)
* keySet()
* put(K key, V value)
* remove(Object key)
* replace(K key, V value)
* size()
*/
//创建map集合时需要确定key和value的类型
Map<Integer,String> map=new HashMap<>();
//添加元素
map.put(1001,"老坛");
map.put(1002,"火腿");
map.put(1003,"卤蛋");
map.put(1004,"绝味");
//是否包含指定的key
System.out.println(map.containsKey(1002));
//是否包含指定的value
System.out.println(map.containsValue("火"));
//根据key获取对应的value
System.out.println(map.get(1004));
//替换
System.out.println(map.replace(1004,"可乐"));
//获取键值对的数量
System.out.println(map.size());
//移除
map.remove(1004);
//清空
//map.clear();
//遍历map集合
//方式1: 获取所有的键,然后根据键找出对应的值 keySet()
Set<Integer> keys = map.keySet();
for (Integer key:keys) {
System.out.println(key+"---"+map.get(key));
}
//方式2:使用entrySet获取所有的映射关系
//Entry 表示一个完整的键值对
Set<Map.Entry<Integer, String>> entrySet = map.entrySet();
for (Map.Entry<Integer, String> entry:entrySet) {
System.out.println(entry.getKey()+"**************"+entry.getValue());
}
System.out.println(map);
}
}
6.其他工具类(Collections、Arrays、System、Scanner)
public class CollectionsClass {
public static void main(String[] args) {
//Collections表示集合工具类 一般用于list集合
//sort、shuffle、reverse
List<Integer> list=new ArrayList<>();
list.add(12);
list.add(25);
list.add(5);
list.add(80);
Collections.sort(list);//排序
Collections.reverse(list);//反转
Collections.shuffle(list);//乱序
System.out.println(list);
}
}
public class ArraysClass {
public static void main(String[] args) {
//Arrays表示数组工具类
int []x={12,8,90,45,7};
Arrays.sort(x);//排序
System.out.println(Arrays.toString(x));//输出数组元素
}
}
public class ScannerClass {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//输入不同类型的数据
//sc.next() 输入字符串
//sc.nextLine() 输入字符串
//String name=sc.next();
String line = sc.nextLine();
}
}
public class SystemClass {
public static void main(String[] args) {
//Syetem.exit(0) 结束JVM
//获取毫秒值
long l = System.currentTimeMillis();
}
}
六、IO操作
1.File类
public class FileClass {
public static void main(String[] args) {
/**
* File 文件
* 学习IO的主要目的是可以使用Java操作磁盘的文件、上传、下载互联网上文件
* 构造函数:
* File(String pathname)
* 常用方法:
* createNewFile()
* exists()
* getName()
* getParentFile()
* mkdirs()
*/
// ctrl+alt+t
try {
File file = new File("D:/aaa.txt");//将本地磁盘的aaa.txt文件转换成File对象
File to = new File("D:/a/b/c/xx.txt");
//获取父级路径对象
File parentFile = to.getParentFile();
if(!parentFile.exists()){//判断路径是否存在
parentFile.mkdirs();//创建多级文件夹
}
to.createNewFile();//创建文件
System.out.println(file);
System.out.println(to.getName());//获取文件名
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.字节输入流和输出流
public class FileInputStreamClass {
public static void main(String[] args) throws IOException {
/**
* FileInputStream字节输入流如何使用?
* 构造函数:
* FileInputStream(File file)
* FileInputStream(String name)
*/
//创建file对象,一定要存在
//File file = new File("D:/x.txt");
//创建字节输入流对象
//FileInputStream input = new FileInputStream(file);
FileInputStream input = new FileInputStream("D:/x.txt");
//创建byte数组
byte [] by=new byte[1024];// 1GB=1024M 1M=1024KB
//声明读取的长度
int len=0;
//读取的长度为-1时说明文件读完了
while((len=input.read(by))!=-1){
//需要将字节转换成字符串输出
String str = new String(by, 0, len);
System.out.println(str);
}
//释放资源
input.close();
}
}
public class FileOutPutStreamClass {
public static void main(String[] args) throws IOException {
/**
* FileOutPutStream字节输出流
* 写数据
* FileOutputStream(File file)
* FileOutputStream(String name)
* write(byte[]by)
*/
//创建字节输出流对象
FileOutputStream out = new FileOutputStream("D:/y.txt");
String str="hello,我是人类高质量男性";
//写入数据
out.write(str.getBytes());
//释放资源
out.close();
}
}
3.字符输入流和输出流
public class FileReaderClass {
public static void main(String[] args) throws IOException {
//创建数据源端
File file = new File("D:/x.txt");
//创建FileReader对象
FileReader fr = new FileReader(file);
//读取文件内容
char []ch=new char[1024];
int len=0;
while((len=fr.read(ch))!=-1){
//将char数组中的数据转换成String字符串
String str = new String(ch, 0, len);
System.out.println(str);
}
//释放资源
fr.close();
}
}
public class FileWriterClass {
public static void main(String[] args) throws IOException {
//创建数据目的端
File to = new File("D:/m.txt");
//创建FileWriter对象
FileWriter fw = new FileWriter(to);
String str="现在有点饿....";
fw.write(str);
//释放资源
fw.close();
}
}
4.增强流
public class BufferedInputStreamClass {
public static void main(String[] args) throws IOException {
//BufferedInputStream增强输入流
//提升文件传输的效率
//创建FileInputStream
FileInputStream in = new FileInputStream("D:/m.txt");
//创建增强输入流
BufferedInputStream bis = new BufferedInputStream(in);
byte[] by=new byte[1024];
int len=0;
while((len=bis.read(by))!=-1){
String str = new String(by, 0, len);
System.out.println(str);
}
//关流
bis.close();
}
}
public class BufferedOutputStreamClass {
public static void main(String[] args) throws IOException {
//创建FileOutputStream
FileOutputStream out = new FileOutputStream("D:/n.txt");
//创建BufferedOutputStream
BufferedOutputStream bos = new BufferedOutputStream(out);
bos.write("今天天气好凉爽".getBytes());
//需要先刷出
bos.flush();
bos.close();
}
}
5.对象序列化流
public class ObjectOutputStreamClass {
public static void main(String[] args) throws IOException {
//作用:将对象持久化保存到本地
//创建ObjectOutputStream对象
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:/obj.txt"));
oos.writeObject(new Student(1001,"张三",18,"女"));
oos.writeObject(new Student(1002,"李四",18,"女"));
oos.writeObject(new Student(1003,"王五",18,"女"));
oos.writeObject(new Student(1004,"赵六",18,"女"));
oos.flush();
oos.close();
}
}
public class ObjectInputStreamClass {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//读取ObjectOutputStream生成的文件
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:/obj.txt"));
//读取数据
for (int i=1;i<5;i++) {
Object obj = ois.readObject();
if (obj instanceof Student) {
Student stu = (Student) obj;
System.out.println(stu);
}
}
ois.close();
}
}
注意:需要将实体类实现序列化接口
七、线程
1.线程和进程的概述
进程:一个正在运行的程序
线程:程序在运行的过程中同时有多个功能在同时进行数据的交互
进程包含线程
2.Thread实现线程方式
步骤:自定义类继承Thread,重写run方法,创建线程对象,然后通过start方法开启线程
public class Thread01 extends Thread{
@Override
public void run() {
for (int i=1;i<51;i++){
//获取当前正在执行的线程
//获取线程的名字
String name = Thread.currentThread().getName();
System.out.println(name+"----"+i);
}
}
}
public class Thread02 extends Thread{
@Override
public void run() {
for (int i=1;i<51;i++){
//获取当前正在执行的线程
//获取线程的名字
String name = Thread.currentThread().getName();
System.out.println(name+"----"+i);
}
}
}
public class ThreadTest {
//主线程
public static void main(String[] args) {
Thread01 t1 = new Thread01();
t1.setName("线程1");
t1.setPriority(7);
Thread02 t2 = new Thread02();
t2.setName("线程2");
t2.setPriority(4);
t1.start();
t2.start();
//获取线程的优先级
int p1 = t1.getPriority();
int p2 = t2.getPriority();
System.out.println(Thread.MAX_PRIORITY);//最大的优先级是10
System.out.println(Thread.MIN_PRIORITY);//最小的优先级是1
System.out.println(Thread.NORM_PRIORITY);//平均的优先级是5
System.out.println(p1+"----"+p2);
for (int i=1;i<51;i++){
//获取当前正在执行的线程
//获取线程的名字
String name = Thread.currentThread().getName();
System.out.println(name+"----"+i);
}
//线程的执行是根据原则:谁优先获取到cpu的资源谁就优先执行
}
}
3.Runnable实现线程的方式
Runable是共享线程,可以实现数据的共享
public class RunableClass implements Runnable {
@Override
public void run() {
for (int i=1;i<51;i++){
//获取当前正在执行的线程
//获取线程的名字
String name = Thread.currentThread().getName();
System.out.println(name+"----"+i);
}
}
}
public class RunnableTest {
public static void main(String[] args) {
//共享线程 共享线程中的数据
RunableClass aClass = new RunableClass();
//借助Thread来进行线程的开启
Thread t1 = new Thread(aClass);
Thread t2 = new Thread(aClass);
Thread t3 = new Thread(aClass);
//开启线程
t1.start();
t2.start();
t3.start();
}
}
4.synchronized同步锁
public class TicketClass implements Runnable{
public int num=100;
public Object obj=new Object();
@Override
public void run() {
while(true) {
//同步锁
//每个线程获取到锁对象之后,其他的线程只能等待,等待该线程并释放锁
synchronized (obj) {
if (num > 0) {
//增加休眠方法
try {
/**
* A -----> 100 休眠
* B -----> 100 休眠
*/
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "卖出了第" + (num--) + "张票");
}
}
}
}
}
public class TicketTest {
public static void main(String[] args) {
TicketClass ticketClass = new TicketClass();
Thread t1 = new Thread(ticketClass);
t1.setName("窗口1");
Thread t2 = new Thread(ticketClass);
t2.setName("窗口2");
Thread t3 = new Thread(ticketClass);
t3.setName("窗口3");
//线程不安全 数据不同步
t1.start();
t2.start();
t3.start();
}
}
5.Lock锁
public class TicketClass implements Runnable{
public int num=100;
//需要创建lock锁对象
public Lock lock=new ReentrantLock();
@Override
public void run() {
while(true){
try{
//获取锁
lock.lock();
if(num>0){
//增加休眠方法
try {
/**
* A -----> 100 休眠
* B -----> 100 休眠
*/
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"卖出了第"+(num--)+"张票");
}
}finally {
//释放锁
lock.unlock();
}
}
}
}
public class TicketTest {
public static void main(String[] args) {
TicketClass ticketClass = new TicketClass();
Thread t1 = new Thread(ticketClass);
t1.setName("窗口1");
Thread t2 = new Thread(ticketClass);
t2.setName("窗口2");
Thread t3 = new Thread(ticketClass);
t3.setName("窗口3");
//线程不安全 数据不同步
t1.start();
t2.start();
t3.start();
}
}
6.交替打印
public class LetterClass implements Runnable{
public Object obj;
public LetterClass(Object obj){
this.obj=obj;
}
@Override
public void run() {
aa:while(true){
synchronized (obj){
for (char i='A';i<='Z';i++){
System.out.print(i+" ");
//唤醒打印数字的线程
obj.notifyAll();
//自己等待
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
public class DigitClass implements Runnable{
public Object obj;
public DigitClass(Object obj){
this.obj=obj;
}
@Override
public void run() {
aa:while(true){
synchronized (obj){
//自己等待
for (int i=1;i<=26;i++){
System.out.print(2*i-1+" "+2*i+" ");
if(i==26){
break aa;
}
//唤醒对方
obj.notifyAll();
//自己进入等待状态
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
public class DLTest {
public static void main(String[] args) {
Object obj = new Object();
Thread t1 = new Thread(new LetterClass(obj));
Thread t2 = new Thread(new DigitClass(obj));
t1.start();
t2.start();
}
}
八、反射
1.Class对象的获取
public class ReflectClass {
public static void main(String[] args) throws ClassNotFoundException {
//获取Class对象的方式
//1.通过类名的方式获取
Class<Person> personClass = Person.class;
System.out.println(personClass);
//2.通过对象的方式来进行获取
Person person = new Person();
Class<? extends Person> aClass = person.getClass();
System.out.println(aClass);
System.out.println(personClass==aClass);
//3.通过Class.forName()来进行获取
Class<?> aClass1 = Class.forName("com.tedu.reflect.Person");
System.out.println(aClass1);
}
}
2.获取构造函数
public class ReflectClass02 {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//先获取Class对象
Class<Person> personClass = Person.class;
//获取Class对象中的构造函数
//1.获取该类中所有的构造函数 只能获取非私有的构造函数
Constructor<?>[] constructors = personClass.getConstructors();
System.out.println(constructors.length);
//2.获取无参的构造函数
Constructor<Person> constructor = personClass.getConstructor();
//将获取到的构造函数进行对象的创建newInstance()
Person person = constructor.newInstance();
System.out.println(person);
//3.获取有参的构造函数
Constructor<Person> constructor1 = personClass.getConstructor(String.class, int.class);
Person lzm = constructor1.newInstance("lzm", 12);
System.out.println(lzm);
//4.获取私有的构造函数
Constructor<Person> declaredConstructor = personClass.getDeclaredConstructor(String.class);
//忽略权限 暴力破解
declaredConstructor.setAccessible(true);
Person zhangsan = declaredConstructor.newInstance("zhangsan");
System.out.println(zhangsan);
}
}
3.获取方法
public class ReflectClass03 {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//获取Class对象
Class<Person> personClass = Person.class;
//获取构造函数
Constructor<Person> constructor = personClass.getConstructor();
//实例化对象
Person person = constructor.newInstance();
//获取方法
Method[] methods = personClass.getMethods();
System.out.println(methods.length);
//获取无参方法
Method play = personClass.getMethod("play");
//执行方法
play.invoke(person);
//获取有参的方法
Method eat = personClass.getMethod("eat", String.class);
//执行eat方法
eat.invoke(person,"水果");
//获取私有的方法
Method sleep = personClass.getDeclaredMethod("sleep", String.class);
//暴力破解
sleep.setAccessible(true);
//执行sleep方法
sleep.invoke(person,"flower");
//获取多个参数的方法
Method study = personClass.getMethod("study", String.class,String.class);
study.invoke(person,"2022-06-07","java");
}
}
4.获取属性
public class ReflectClass04 {
public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//1.获取Class对象
Class<Person> personClass = Person.class;
//获取构造函数
Constructor<Person> constructor = personClass.getConstructor();
//实例化对象
Person person = constructor.newInstance();
//2.获取所有的属性 获取当前类中非私有的属性
Field[] fields = personClass.getFields();
System.out.println(fields.length);
//3.获取单个属性
Field name = personClass.getField("name");
//4.给属性赋值
name.set(person,"李四");
System.out.println(person.name);
//获取私有属性
Field sex = personClass.getDeclaredField("sex");
sex.setAccessible(true);
sex.set(person,"男");
System.out.println(person);
}
}
九、JDBC
1.mysql基本的sql语句回顾
-- 插入数据
-- 全部插入 因为主键自增,所以使用null来进行代替
-- insert into 表名 values(字段值1,字段值2,....);
INSERT INTO student VALUES(NULL,'张三','男',18)
-- 局部插入 在表名后面指定需要插入的字段
-- insert into 表名(字段名1,字段名2,....) values(字段值1,字段值2,....);
INSERT INTO student(sname) VALUES('李四')
-- 修改
-- update 表名 set 字段名1=字段值1,字段名2=字段值2,.... where 条件
UPDATE student SET sex='男' WHERE sid=2
UPDATE student SET sex='女',age=10 WHERE sid=2
-- 删除
-- delete from 表名 where 条件
DELETE FROM student WHERE sid=2
-- 查询
-- 全查
-- select * from 表名
SELECT * FROM student
-- 局部查询
-- select 字段名,字段名.... from 表名
SELECT sname,sex FROM student
-- 条件查询
-- select 字段名,字段名.... from 表名 where 条件
SELECT sname,sex FROM student WHERE sid=4
2.获取数据库连接
public class JdbcTest {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//1.加载mysql的连接驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取数据库的连接,需要知道三个参数 账号、密码、url
String user="root";
String password="root";
String url="jdbc:mysql://localhost:3306/db07";
//获取连接
Connection connection = DriverManager.getConnection(url, user, password);
System.out.println(connection);
}
}
4.增删改查
public class FindAllClass {
public static void main(String[] args) throws SQLException, ClassNotFoundException {
FindAllClass findAllClass = new FindAllClass();
// findAllClass.findAll();
// findAllClass.findById(1);
// findAllClass.add("翠花","女",18);
// findAllClass.update("小白",7);
// findAllClass.del(7);
// List<Student> list = findAllClass.findAllStu();
//System.out.println(list);
Student allStuById = findAllClass.findAllStuById();
System.out.println(allStuById);
}
//全查
public void findAll() throws ClassNotFoundException, SQLException {
Connection connection = JDBCUtils.getConnection();
//创建sql
String sql = "select * from student";
//对sql进行预编译
PreparedStatement ps = connection.prepareStatement(sql);
//执行查询
ResultSet rs = ps.executeQuery();
//从resultSet中取出查询的结果
while(rs.next()){
//获取sid的值
int sid = rs.getInt("sid");
//获取sname的值
String sname = rs.getString("sname");
//获取sex
String sex = rs.getString("sex");
//获取age
int age = rs.getInt("age");
System.out.println(sid+"---"+sname+"---"+sex+"---"+age);
}
//释放资源
/*rs.close();
ps.close();
connection.close();*/
JDBCUtils.close(rs,ps,connection);
}
//全查 在Java中操作对象其实就是在操作表
//一般全查的时候返回值都是list集合
public List<Student> findAllStu() throws ClassNotFoundException, SQLException {
List<Student> list=new ArrayList<>();
//数据库表中的一条记录对应Java中的一个对象
Connection connection = JDBCUtils.getConnection();
//创建sql
String sql = "select * from student";
//对sql进行预编译
PreparedStatement ps = connection.prepareStatement(sql);
//执行查询
ResultSet rs = ps.executeQuery();
//从resultSet中取出查询的结果
while(rs.next()){
Student student = new Student();
//获取sid的值
int sid = rs.getInt("sid");
//获取sname的值
String sname = rs.getString("sname");
//获取sex
String sex = rs.getString("sex");
//获取age
int age = rs.getInt("age");
//将每一条的数据保存在对象中
student.setSid(sid);
student.setAge(age);
student.setSex(sex);
student.setSname(sname);
//将对象保存在list集合中
list.add(student);
}
//释放资源
/*rs.close();
ps.close();
connection.close();*/
JDBCUtils.close(rs,ps,connection);
return list;
}
public Student findAllStuById() throws ClassNotFoundException, SQLException {
Student student=new Student();
//数据库表中的一条记录对应Java中的一个对象
Connection connection = JDBCUtils.getConnection();
//创建sql
String sql = "select * from student";
//对sql进行预编译
PreparedStatement ps = connection.prepareStatement(sql);
//执行查询
ResultSet rs = ps.executeQuery();
//从resultSet中取出查询的结果
while(rs.next()){
//获取sid的值
int sid = rs.getInt("sid");
//获取sname的值
String sname = rs.getString("sname");
//获取sex
String sex = rs.getString("sex");
//获取age
int age = rs.getInt("age");
//将每一条的数据保存在对象中
student.setSid(sid);
student.setAge(age);
student.setSex(sex);
student.setSname(sname);
}
//释放资源
/*rs.close();
ps.close();
connection.close();*/
JDBCUtils.close(rs,ps,connection);
return student;
}
//根据id查询
public void findById(int id) throws SQLException, ClassNotFoundException {
/* //1.加载mysql的连接驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取数据库的连接,需要知道三个参数 账号、密码、url
String user="root";
String password="root";
String url="jdbc:mysql://localhost:3306/db07";
//获取连接
Connection connection = DriverManager.getConnection(url, user, password);*/
Connection connection = JDBCUtils.getConnection();
//编写sql 需要传递的参数使用?来进行占位
String sql="select * from student where sid=?";
//预编译
PreparedStatement ps = connection.prepareStatement(sql);
//设置占位符的参数
ps.setInt(1,id);
//执行查询
ResultSet rs = ps.executeQuery();
//从resultSet中取出查询的结果
while(rs.next()){
//获取sid的值
int sid = rs.getInt("sid");
//获取sname的值
String sname = rs.getString("sname");
//获取sex
String sex = rs.getString("sex");
//获取age
int age = rs.getInt("age");
System.out.println(sid+"---"+sname+"---"+sex+"---"+age);
}
//释放资源
/* rs.close();
ps.close();
connection.close();*/
JDBCUtils.close(rs,ps,connection);
}
//添加
public void add(String name,String sex,int age) throws ClassNotFoundException, SQLException {
/* //1.加载mysql的连接驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取数据库的连接,需要知道三个参数 账号、密码、url
String user="root";
String password="root";
String url="jdbc:mysql://localhost:3306/db07?useUnicode=true&characterEncoding=UTF8";
//获取连接
Connection connection = DriverManager.getConnection(url, user, password);*/
Connection connection = JDBCUtils.getConnection();
//创建sql
String sql="insert into student values(null,?,?,?)";
//预编译
PreparedStatement ps = connection.prepareStatement(sql);
ps.setString(1,name);
ps.setString(2,sex);
ps.setInt(3,age);
//执行添加 添加、修改、删除都是同一个方法
int i = ps.executeUpdate();
//释放资源
/*ps.close();
connection.close();*/
JDBCUtils.close(ps,connection);
}
//修改
public void update(String name,int sid) throws SQLException, ClassNotFoundException {
/* //1.加载mysql的连接驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取数据库的连接,需要知道三个参数 账号、密码、url
String user="root";
String password="root";
String url="jdbc:mysql://localhost:3306/db07?useUnicode=true&characterEncoding=UTF8";
//获取连接
Connection connection = DriverManager.getConnection(url, user, password);*/
Connection connection = JDBCUtils.getConnection();
//编写sql
String sql="update student set sname=? where sid=?";
//预编译
PreparedStatement ps = connection.prepareStatement(sql);
ps.setString(1,name);
ps.setInt(2,sid);
//执行修改
int i = ps.executeUpdate();
//释放资源
/* ps.close();
connection.close();*/
JDBCUtils.close(ps,connection);
}
//删除
public void del(int sid) throws SQLException, ClassNotFoundException {
/* //1.加载mysql的连接驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取数据库的连接,需要知道三个参数 账号、密码、url
String user="root";
String password="root";
String url="jdbc:mysql://localhost:3306/db07?useUnicode=true&characterEncoding=UTF8";
//获取连接
Connection connection = DriverManager.getConnection(url, user, password);*/
Connection connection = JDBCUtils.getConnection();
//编写sql
String sql="delete from student where sid=?";
PreparedStatement ps = connection.prepareStatement(sql);
ps.setInt(1,sid);
//执行修改
int i = ps.executeUpdate();
//释放资源
JDBCUtils.close(ps,connection);
}
}
十、Dbutils工具类的使用
需要先导入commons-dbutils-1.6.jar
//如果是全查,需要返回多个对象那么返回值一定是list
public List<Student> findAll() throws SQLException {
//1.获取数据库的连接
Connection connection = JDBCUtils.getConnection();
//2.创建QueryRunner对象
QueryRunner qr = new QueryRunner();
//3.创建sql
String sql="select * from student";
//4.执行查询 BeanListHandler将结果集映射到对应的list集合中 前提:数据库表的字段名必须要和实体类中的属性名保持一致,可能会映射不成功
List<Student> list = qr.query(connection, sql, new BeanListHandler<Student>(Student.class));
//5.释放资源
DbUtils.closeQuietly(connection);
return list;
}
//根据id来进行查询返回的是一条记录,所以就是一个Student对象
public Student findById(int id) throws SQLException {
//1.获取数据库的连接
Connection connection = JDBCUtils.getConnection();
//2.创建QueryRunner对象
QueryRunner qr = new QueryRunner();
//3.编写sql
String sql="select * from student where sid=?";
//4.执行查询 返回值是一个对象的时候使用BeanHandler
Student student = qr.query(connection, sql, new BeanHandler<Student>(Student.class), id);
//5.释放资源
DbUtils.closeQuietly(connection);
return student;
}
//修改 因为修改成功会返回成功的记录条数 所以返回值使用int
public int updateById(int id,String sname) throws SQLException {
//1.获取数据库的连接
Connection connection = JDBCUtils.getConnection();
//2.创建QueryRunner对象
QueryRunner qr = new QueryRunner();
//3.编写sql
String sql = "update student set sname=? where sid=?";
//执行修改
int i = qr.update(connection, sql, sname, id);
//5.释放资源
DbUtils.closeQuietly(connection);
return i;
}
//添加 修改、删除 返回值都是int类型
public int add(String sname,String sex,int age) throws SQLException {
//1.获取数据库的连接
Connection connection = JDBCUtils.getConnection();
//2.创建QueryRunner对象
QueryRunner qr = new QueryRunner();
//3.编写sql
String sql="insert into student values(null,?,?,?)";
//4.执行添加
int i = qr.update(connection, sql, sname, sex, age);
//5.释放资源
DbUtils.closeQuietly(connection);
return i;
}
//删除
public int del(int id) throws SQLException {
//1.获取数据库的连接
Connection connection = JDBCUtils.getConnection();
//2.创建QueryRunner对象
QueryRunner qr = new QueryRunner();
//3.编写sql
String sql="delete from student where sid=?";
//4.执行删除
int i = qr.update(connection, sql, id);
//5.释放资源
DbUtils.closeQuietly(connection);
return i;
}
@Test
public void testFindAll() throws SQLException {
//List<Student> list = findAll();
// Student student = findById(3);
// int id = updateById(3, "lucy");
// int i = add("法外狂徒", "男", 20);
// int i = del(8);
List<Student> list = findAll01();
System.out.println(list);
}
}
十一、Druid数据库连接池
需要先导入druid-1.0.9.jar
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/db07?characterEncoding=UTF-8
username=root
password=root
initialSize=5
maxActive=10
maxWait=3000
public class JDBCPROUtils {
private static DataSource dataSource;
//获取数据库连接池
static {
//加载配置文件,将配置文件转换成字节输入流
InputStream stream = JDBCPROUtils.class.getClassLoader().getResourceAsStream("druid.properties");
//创建Properties对象
Properties properties = new Properties();
//读取输入流中的相关数据
try {
properties.load(stream);
dataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
//返回连接池对象
public static DataSource getDataSource(){
return dataSource;
}
//返回数据库连接
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
}
//如果是全查,需要返回多个对象那么返回值一定是list
public List<Student> findAll01() throws SQLException {
//1.创建QueryRunner对象,并从数据库的连接池中获取数据库的连接
QueryRunner qr = new QueryRunner(JDBCPROUtils.getDataSource());
//2.创建sql
String sql="select * from student";
//3.执行查询 BeanListHandler将结果集映射到对应的list集合中 前提:数据库表的字段名必须要和实体类中的属性名保持一致,可能会映射不成功
List<Student> list = qr.query(sql, new BeanListHandler<Student>(Student.class));
return list;
}
public Student findById01(int id) throws SQLException {
//2.创建QueryRunner对象
QueryRunner qr = new QueryRunner(JDBCPROUtils.getDataSource());
//3.编写sql
String sql="select * from student where sid=?";
//4.执行查询 返回值是一个对象的时候使用BeanHandler
Student student = qr.query( sql, new BeanHandler<Student>(Student.class), id);
return student;
}
十二、MySQL
1.SQL语句分类
DDL:针对数据库、表、字段的操作
DML: 针对表记录的操作
DQL: 主要查询
2.数据库的操作
-- 创建数据库
-- create database 数据库名
CREATE DATABASE db08;
-- 创建数据库并设置编码字符集
CREATE DATABASE db09 CHARACTER SET utf8;
-- 删库(谨慎操作)
DROP DATABASE db08;
-- 查看数据库
SHOW DATABASES;
-- 使用数据库
USE db09;
3.表的操作
-- 建表
-- 约束(主键、外键、唯一、非空)
-- 主键特征:唯一性、非空
-- AUTO_INCREMENT自增,一般用于主键中
-- char和varchar区别 都表示字符串 varchar长度在范围可以伸缩,char是固定长度
-- 表的字段类型
-- 常用类型:double、int、varchar、date
CREATE TABLE ACCOUNT(
-- 字段名 字段类型 约束
aid INT PRIMARY KEY AUTO_INCREMENT,
aname VARCHAR(10) NOT NULL,
sex CHAR(3)
)
4.表记录操作
-- 表记录操作
-- 添加
-- 创建表
CREATE TABLE acc(
-- 字段名 字段类型 约束
aid INT PRIMARY KEY AUTO_INCREMENT,
aname VARCHAR(10) NOT NULL,
money DOUBLE,
payType VARCHAR(10),
descript VARCHAR(10)
)
-- 全部插入
INSERT INTO acc VALUES(NULL,'收入',123456.8,'工商银行','年终奖');
-- 局部插入
INSERT INTO acc(aname,money) VALUES('支出','4000')
-- 同时插入多条数据
INSERT INTO acc VALUES(NULL,'支出',10000,'支付宝','给女朋友买包'),(NULL,'收入',100000,'工商银行','买卢布');
-- 修改
UPDATE acc SET descript='给女朋友买DR' WHERE aid=3
UPDATE acc SET money=100,payType='微信支付',descript='给男朋友买衣服' WHERE aid=4
-- 删除 保留之前的痕迹
DELETE FROM acc WHERE aid=4
-- 不留痕迹
TRUNCATE TABLE acc
-- 删除 (物理、逻辑) 经常使用逻辑删除
5.单表查询
#创建员工表
CREATE TABLE emp(
eid INT,
ename VARCHAR(20),
sex CHAR(1),
salary DOUBLE,
hire_date DATE,
dept_name VARCHAR(20)
);
#添加数据
INSERT INTO emp VALUES(1,'孙悟空','男',7200,'2013-02-04','教学部');
INSERT INTO emp VALUES(2,'猪八戒','男',3600,'2010-12-02','教学部');
INSERT INTO emp VALUES(3,'唐僧','男',9000,'2008-08-08','教学部');
INSERT INTO emp VALUES(4,'白骨精','女',5000,'2015-10-07','市场部');
INSERT INTO emp VALUES(5,'蜘蛛精','女',5000,'2011-03-14','市场部');
INSERT INTO emp VALUES(6,'玉兔精','女',200,'2000-03-14','市场部');
INSERT INTO emp VALUES(7,'林黛玉','女',10000,'2019-10-07','财务部');
INSERT INTO emp VALUES(8,'黄蓉','女',3500,'2011-09-14','财务部');
INSERT INTO emp VALUES(9,'吴承恩','男',20000,'2000-03-14',NULL);
INSERT INTO emp VALUES(10,'孙悟饭','男', 10,'2020-03-14','财务部');
INSERT INTO emp VALUES(11,'兔八哥','女', 300,'2010-03-14','财务部');
-- 别名 as 一般可以省略
SELECT ename '姓名',salary '工资' FROM emp;
-- 去重 distinct
SELECT * FROM emp;
SELECT DISTINCT(sex) FROM emp;
-- 条件查询
-- 运算符
-- 比较 >、<、>=、<=、<>(!=)、=
-- 区间 between...and
-- 集合 in
-- 模糊查询 like %、_
-- 判断为NULL is null
-- 判断不为null is not null
-- 逻辑运算符
-- and 与
-- or 或
-- not 非
# 查询员工姓名为黄蓉的员工信息
SELECT * FROM emp WHERE ename='黄蓉'
# 查询薪水价格为5000的员工信息
SELECT * FROM emp WHERE salary=5000
# 查询薪水价格不是5000的所有员工信息
SELECT * FROM emp WHERE salary <> 5000
# 查询薪水价格大于6000元的所有员工信息
SELECT * FROM emp WHERE salary > 6000
# 查询薪水价格在5000到10000之间所有员工信息
SELECT * FROM emp WHERE salary BETWEEN 5000 AND 10000
# 查询薪水价格是3600或7200或者20000的所有员工信息
SELECT * FROM emp WHERE salary IN (3600,7200,20000)
# 查询含有'精'字的所有员工信息
SELECT * FROM emp WHERE ename LIKE '%精%'
# 查询以'孙'开头的所有员工信息
SELECT * FROM emp WHERE ename LIKE '孙%'
# 查询第二个字为'兔'的所有员工信息
SELECT * FROM emp WHERE ename LIKE '_兔%'
# 查询没有部门的员工信息
SELECT * FROM emp WHERE dept_name IS NULL
# 查询有部门的员工信息
SELECT * FROM emp WHERE dept_name IS NOT NULL
-- 排序 order by asc 升序 desc降序
SELECT * FROM emp ORDER BY salary DESC
-- 组合排序 第一个参数相等的情况下,排第二个
SELECT * FROM emp ORDER BY salary DESC,eid DESC
-- 聚合函数
-- max、min、avg、count(总记录数)、sum
#1 查询员工的总数
SELECT COUNT(*) '总员工数' FROM emp
#2 查看员工总薪水、最高薪水、最小薪水、薪水的平均值
SELECT SUM(salary) '总薪水',MAX(salary) '最高薪水',MIN(salary) '最小薪水',AVG(salary)'平均薪水' FROM emp
#3 查询薪水大于4000员工的个数
SELECT COUNT(*) FROM emp WHERE salary>4000
#4 查询部门为'教学部'的所有员工的个数
SELECT COUNT(*) FROM emp WHERE dept_name='教学部'
#5 查询部门为'市场部'所有员工的平均薪水
SELECT AVG(salary) FROM emp WHERE dept_name='市场部'
-- 分组查询 group by 一般和聚合函数搭配使用
#1.查询所有部门信息
#2.查询每个部门的平均薪资
SELECT dept_name '部门名称',AVG(salary)'平均薪资' FROM emp GROUP BY dept_name
#3.查询每个部门的平均薪资, 部门名称不能为null
SELECT dept_name '部门名称',AVG(salary)'平均薪资' FROM emp WHERE dept_name IS NOT NULL GROUP BY dept_name
-- 一般分组之后在加条件 having
SELECT dept_name '部门名称',AVG(salary)'平均薪资' FROM emp GROUP BY dept_name HAVING dept_name IS NOT NULL
-- limit 分页
SELECT * FROM emp
-- 每页显示3条,显示第3页的数据
SELECT * FROM emp LIMIT 0,3
-- limit a,b b表示每页显示的条数, (当前页-1)*b
SELECT * FROM emp LIMIT 6,3