面向对象, 常用类, 集合, 异常, JDBC, mysql数据库内容的复习

面向对象

l 类的结构
• 变量:事物属性的描述(名词)
• 方法:事物的行为(可以做的事情 动词)
• 构造方法:初始化对象
• 块:一段没有名称的代码块
• 内部类: 即在类体中声明的类
类的声明格式为 :
[ 访问权限修饰符 ] [ 修饰符 ] class Car{
}
访问修饰符有两种 public ,无 ( 默认 )
修饰符: final,abstract
关键字 class 用来定义一个类
Java 类名的命名规范 :
类名首字母大写 , 见名知意 , 驼峰表示
l 创建并使用对象
对象 :是类的一个实例,是以类为模板在内存中创建的实际存在的实例。
对象的创建和使用
Car bm= new Car();
Car bm :使用Car类作为类型声明一个变量 bm .
new Car() :使用new 创建对象,然后调用Car类的构造方法初始化对象.
= : 将右边创建的对象地址赋给左边的 bm 变量
同一类的每个对象有不同存储空间。
对象是类的一个实例,必然具备该类事物的属性和行为(即方法)。
使用对象名.属性或对象名.方法的方式访问对象成员(包括属性和方法)
l 总结类和对象
类是一类事物的抽象概念,是一个模型.
对象是由这个模型所创造的,一个个具体存在的,实实在在存在的实例.
所以创建对象的过程也叫实例化对象.
l 现实生活中先有对象后有类,而编程时先设计类后创建对象.
构造方法
构造方法名与类名相同 , 且没有返回值,且不需要使用void修饰
作用: 在构造方法中为创建的对象成员变量初始化赋值
特点: 每个类都有构造方法,如果没有显式地为类定义构造方法,Java将会为该类提供一个默
认无参构造方法,但是只要在一个Java类中定义了一个有参构造方法后,默认的无参构造方法
会失效。
一个类可以有多个构造方法。
例: public class Car{
public Car(){ }
public Car(String name){ // 这个构造方法有一个参数:name }
}
例:创建Car类的对象
Car car1 = new Car();
Car car2 = new Car("宝马")
l 方法的重载是指一个类中具有相同的名字,但参数不同的多个方法。
l 参数不同(可以有三方面的不同)
• 数量不同
• 类型不同
• 顺序不同
l 调用时,会根据不同的参数表选择对应的方法
注意:方法重载跟方法的返回值类型没有任何关系
对象与引用
例如: 我们有一个自定义类为 Car (汽车类)
class Car{
String name;
String color;
float price;
}
Car bm= new Car();
通常把这条语句的动作称之为创建一个对象,其实,它包含了三个动作。
1 )右边的" new Car()" ,是以 Car 类为模板 , 在堆空间里创建一个 Car 类对象。
2 )左边的" Car bm" 创建了一个 Car 类型引用变量。所谓 Car 类的引用,就是以后可以用来指
向 Car 对象的对象引用。
3 ) "=" 操作符使对象引用指向刚创建的那个 Car 对象。
我们可以把这条语句拆成两部分:
Car bm;
bm= new Car();
这样写,就比较清楚了,有两个实体:一个是对象引用变量,一个是对象本身。
this关键字
this关键字代表当前对象
使用this关键字引用成员变量
使用this关键字引用成员方法或构造方法。
在一个类的方法或构造方法内部,可以使用"this.成员变量名"这样的
格式来引用成员变量名,常常用来区分同名的成员变量和局部变量。
public class Demo{
int name;
public Demo(int name){
this.name = name;
}
}
static 关键字
● static属性
静态属性是类的所有对象共享的,即不管创建了多少个对象,静态属性在内存中
只有一个。
• 静态变量在类被加载时由系统默认初始化。
• 静态变量值是所有对象共享。
• 静态变量可以在任意方法、代码块、构造器中直接使用。
• 可以通过类名.静态变量直接访问,也可以通过对象.静态变量的方式访问(但
是更推荐使用类名.静态变量的方式)。
public class Chinese{
String name ;//姓名
static String country="中国";//国家

● 用static修饰的成员方法就是静态方法。
● 静态方法在本类的任意方法、代码块、构造器中都可以直接被调用。
● 静态方法在其他类中可以通过类名.静态方法的方式调用。也可以通过对
象.静态方法的方式调用(但是更推荐使用类名.静态方法的方式)。
● 在static方法内部只能访问类的static修饰的属性或方法,不能访问类的
非static的成员。
● 因为不需要实例就可以访问static方法,因此static方法内部不能有this,
也不能有super。
代码块
● 代码块在类中声明,类似一个没有名称的方法体 ( 代码块 ) ,代码分实例块和静态块
实例块:每次创建对象时自动调用
{
// 任何符合语法的 Java 代码
}
静态块:类加载时自动调用,仅一次,与是否创建对象无关。
static {
// 任何符合语法的 Java 代码
}

● 在编写 Java 程序时,随着程序架构越来越大,类的个数也越来越多,这时就会
发现管理程序中维护类名称也是一件很麻烦的事,尤其是一些同名问题的发生。
有时,开发人员还可能需要将处理同一方面的问题的类放在同一个目录下,以
便于管理。
● 为了解决上述问题,Java 引入了包(package)机制,提供了类的多层命名空
间,用于解决类的命名冲突、类管理等问题。
● 使用package关键字修饰包
● 每个类属于一个特定的包,所以java中一个类的完整名称等于包名+类名
● 包的作用:
按照不同功能管理类
避免类重名
控制访问权限
访问权限修饰符
● 访问权限修饰符
public
protected
(default)
private
Java语言有四个权限访问修饰符,权限从大到小依次为:
1)public :公共权限 修饰类、属性、方法。可以在任意类中访问
2)protected:受保护的权限 修饰属性、方法。可以在同包类访问,如果
不是同包类,必须是该类的子类才可以访问。
3)default:同包权限 修饰类、属性、方法。只能在同包的类访问
4)private:私有权限
面向对象特征 -- 封装
● 具体表现
使用不同的访问权限
public class Demo{
private String name; //将类的成员变量访问权限设置为私有
public String getName (){
return name;
}
public void setName(String name){
this.name = name;
}
}
成员变量和局部变量
l 在类中的位置不同
成员变量:在类中定义 局部变量:在方法中定义或者方法的参数
l 权限修饰不同
成员变量:可以使用权限修饰符 局部变量:不可以使用权限修饰符
l 初始化不同
成员变量:创建对象后,由构造方法初始化
局部变量:没有默认初始化值,必须定义,赋值。
l 生命周期不同
成员变量:随着对象的创建而存在,随着对象的销毁而消失
局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
l 在内存中的位置不同
成员变量:与对象一起在堆内存中 局部变量: 与方法一样在栈中
面向对象特征 -- 继承
l 继承的好处
继承的出现减少了代码冗余,提高了代码的复用性。
继承的出现,更有利于功能的扩展。
继承的出现让类与类之间产生了is-a的关系,为多态的使用提供了前提。
l 继承的语法
通过 extends关键字,可以声明一个类B继承另外一个类A,定义格式如下:
[修饰符] class 类A {
...
}
[修饰符] class 类B extends 类A {
...
}
类B,称为子类/派生类
类A,称为父类/基类
继承性的细节
● 子类会继承父类所有的实例变量和实例方法
● 子类不能直接访问父类中私有的(private)的成员变量和方法
● 在Java 中,继承的关键字用的是"extends",表示子类是对父类的扩展
● Java支持多层继承(继承体系)
● 一个父类可以同时拥有多个子类
● Java只支持单继承,不支持多重继承
抽象类
l 抽象方法
抽象方法是一种特殊的方法:它只有声明,而没有具体的实现 .
抽象方法必须用 abstract 关键字进行修饰 .
使用关键字 abstract 定义抽象类,一般语法:
[访问权限] abstract class 类名 {
成员列表
}
public abstract class Shapes {
public abstract void draw();
}
使用关键字 abstract 定义抽象类,一般语法:
[访问权限] abstract class 类名 {
成员列表
}
public abstract class Shapes {
public abstract void draw();
}
面向对象特征 -- 多态
● 多态
父类引用指向子类对象,从而产生多种形态
Animal dog = new Dog();
Animal cat = new Cat();
同一种事物,在不同时刻表现不同状态
二者存在直接或者间接的继承关系时,父类引用指向子类的对象,即
形成多态。
当编译期类型是父类,运行期类型是子类时,被称为父类引用指向子类对象
class Animal{
......
}
class Cat extends Animal{
......
}
class Dog extends Animal {
......
}
Animal c = new Cat() //Animal 的引用指向Cat的对象
Animal d = new Dog() //Animal 的引用指向Dog的对象
● 向上转型
class Animal{
void eat(){ }
}
class Cat extends Animal{
void eat() {
System.out.println("狗吃骨头");
}
}
.........
Animal x=new Cat() //向上造型,Cat对象提升到Animal对象
x.eat() //在编译奇迹只能调用父类中定义的方法, 如果子类重写了父类方法,那么运行时
调用子类重写的方法
● 向上转型
class Animal{
void eat(){ }
}
class Cat extends Animal{
void eat() {
System.out.println("狗吃骨头");
}
}
.........
Animal x=new Cat() //向上造型,Cat对象提升到Animal对象
x.eat() //在编译奇迹只能调用父类中定义的方法, 如果子类重写了父类方法,那么运行时
调用子类重写的方法
final 关键字
l final 用于修饰类,方法,参数,和属性
类:不能被定义为抽象类或是接口,不可被继承
方法:子类里不可以重写
参数:参数值在方法中不可被修改
属性:定义时就必须直接赋值或者在构造方法中进行赋值,并且后期都不能修改
接口
● 认识一下接口
public interface MyInterface {
int num = 10;
public void foo()
public static void test(){ }
public default void test1(){}
}
接口的定义和使用
接口的定义:使用 interface 关键字用来声明一个接口。
[访问修饰符] interface 接口名称 [extends 其他的接口名1,....其他的接口名n]
{
// 声明常量 抽象方法 静态方法 默认方法
}
接口的使用: 类使用implements关键字实现接口。在类声明中,Implements
关键字放在class声明后面。
[访问修饰符] class 类名 implements 接口名1,接口名2......{ }
结合继承:
[访问修饰符] class 类名 extends 父类名

常用类

Java API 概述
l API(Application Programming Interface)应用程序编程接口
是对java预先定义的类或接口功能和函数功能的说明文档,目的是提供
给开发人员进行使用帮助说明.
本章会学习java提供的一些基础常用类,以便后期学习需要.
后面的章节以具体模块化学习为主,本质就是学习java中提供的类的功能.
Object
● Object类是所有Java类的祖先(根基类)。每个类都使用 Object 作为超类
(父类)。所有对象(包括数组)都继承实现这个类的方法。
● 如果在类的声明中未使用extends关键字指明其基类,则默认基类为Object类
public class Person { ...
}
等价于:
public class Person extends Object {
...
}
Object
● Object类是所有Java类的祖先(根基类)。每个类都使用 Object 作为超类
(父类)。所有对象(包括数组)都继承实现这个类的方法。
● 如果在类的声明中未使用extends关键字指明其基类,则默认基类为Object类
public class Person { ...
}
等价于:
public class Person extends Object {
...
}
● equals 方法
● Object 类中定义有:
● public boolean equals(Object obj) 方法 , 判断对象是否相等的逻辑。
public boolean equals(Object obj) {
return (this == obj);
}
● Object 中的 equals 方法默认使用 == 比较 , 比较的是对象地址 , 这点需
要注意 .
● JDK 提供的一些类,如 String , Date 等,重写了 Object 的 equals 方
法,调用这些类的 equals 方法, x.equals (y) , 当 x 和 y 所引用的对象
是同一类对象且属性内容相等返回 true 否则返回 false 。
Arrays
● java.util.Arrays类用于操作数组工具类,里面定义了常见操作数组的静态方法.
● equals 方法
比较两个数组对象中元素是否相等.
而数组对象中的equals用来判断与另一个数组对象是否相等。
声明:public static boolean equals(type[]a,type[]a2)
参数的类型可以是原生数据类型和引用类型的任意一种类型
返回:如果两个相等,则返回true,否则返回false\
● sort -排序
● 作用于数组的所有元素
public static void sort(type[] a)
● 作用于数组指定范围内的元素
public static void sort(type[] a, int fromIndex(包括), int
toIndex(不包括))
将指定的类型数组所有元素按数字升序进行排序。
l 自定义对象排序
自定义类实现Comparable接口
重写compareTo方法
binarySearch -使用二分搜索算法搜索指定数组
public static int binarySearch(type[] a, type key)
public static int binarySearch(long[] a,int fromIndex,int
toIndex,long key)
● 参数:
a - 要搜索的数组。
key - 要搜索的值。
fromIndex - 要排序的第一个元素的索引(包括)。
toIndex - 要排序的最后一个元素的索引(不包括)。
● 如果key在数组中,则返回搜索值的索引;否则返回负数,表示不存在
● copyOf方法
● 数组复制,将指定数组中的元素复制到一个指定长度的新数组中,并返回
新数组.
● static int[] copyOf(int[] a, int newLength)
● fill方法
● 将指定的int值分配给指定的int数组的每个元素。
● fill(int[] a, int val)
toString() 方法
● public static String toString(type[] a)
● 返回指定数组内容的字符串表示形式。
基本数据类型包装类
● Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面
向对象的,这在实际使用时存在很多的不便,为了解决这个不足,在设
计类时为每个基本数据类型设计了一个对应的类进表示,这样八个和基
本数据类型对应的类统称为包装类.
● 包装类(如:Integer,Double等)这些类封装了一个相应的基本数据
类型数值,并为其提供了一系列操作方法。
● 包装类常用属性方法
● 以下方法以 java.lang.Integer 为例
public static final int MAX_VALUE 最大的 int 型数( 2 31 -1 )
public static final int MIN_VALUE 最小的 int 型数( -2 31 )
构造方法
Integer(int a);
Integer(String a);
比较方法
static int compareTo(Integer a);
boolean equals(Object);
int max(int a,int b);
int min(int a,int b);
转换方法
static toBinaryString(int i);
static String toHexString(int i);
static String toOctalString(int i);
int intValue();
static int parseInt(String s);
String toString();
static Integer valueOf(int i)
static Integer valueOf(String s)
● 装箱和拆箱Auto-boxing/unboxing
● 装箱
自动将基本数据类型转换为包装器类型
装箱的时候自动调用的是Integer的valueOf(int)方法
● 拆箱
自动将包装器类型转换为基本数据类型
拆箱的时候自动调用的是Integer的intValue方法
// 装箱
int a = 12;
Integer b = Integer.valueOf(a);
// 拆箱
int c = b.intValue();
int a = 12;
// 自动装箱
Integer b = a;
// 自动拆箱
int c = b;
String
● String类概述
字符串是由多个字符组成的一串数据(字符序列)的字符串常量,java中所有字
符串都是String类的实例.
● 有两种创建形式:
● 第一种:
String s = "abc";
先在栈中创建一个对String类的对象引用变量s,然后去字符串常量池中查找
有没有"abc", 如果没有则在常量池中添加"abc", s引用变量指向常量池中
的"abc",如果常量池中有,则直接指向改地址即可,不用重新创建.
● 第二种:
一概在堆中创建新对象,值存储在堆内存的对象中。
String s = new String("abc");
● 构造方法
public String()
public String(String str)
public String(byte[] bytes)
public String(char[] value)
● 判断功能
boolean equals(Object obj)
boolean equalsIgnoreCase(String str)
boolean contains(String str)
boolean isEmpty()
boolean startsWith(String prefix)
boolean endsWith(String suffix)
获取功能
int length()
char charAt(int index)
int indexOf(String str)
int indexOf(String str,int fromIndex)
String substring(int start)
String substring(int start,int end)
● 转换功能
byte[] getBytes()
char[] toCharArray()
static String valueOf(char[] chs)
String toLowerCase()
String toUpperCase()
String concat(String str)
Stirng[] split(分割符);
● 转换功能
byte[] getBytes()
char[] toCharArray()
static String valueOf(char[] chs)
String toLowerCase()
String toUpperCase()
String concat(String str)
Stirng[] split(分割符);
StringBuffer
● StringBuffer 类概述
我们如果对字符串进行拼接操作,每次拼接,都会构建一个新的 String
对象,既耗时,又浪费空间。而 StringBuffer 就可以解决这个问题
线程安全的可变字符序列
● StringBuffer 和 String 的区别 ?
● 构造方法
public StringBuffer()
public StringBuffer(String str)
● 添加功能
public StringBuffer append(String str)
public StringBuffer insert(int offset,String str)
● 删除功能
public StringBuffer deleteCharAt(int index)
public StringBuffer delete(int start,int end)
● 替换功能
public StringBuffer replace(int start,int end,String str)
● 反转功能
public StringBuffer reverse()
截取功能
public String substring(int start)
public String substring(int start,int end)
● 截取功能和前面几个功能的不同
返回值类型是 String 类型,本身没有发生改变
● StringBuilder 类功能和 StringBuffer 功能完全一致 , StringBuffer 是线程
安全的
● String :是字符常量 , 适用于少量的字符串操作的情况
● StringBuilder :适用于单线程下在字符缓冲区进行大量操作的情况
● StringBuffer :适用多线程下在字符缓冲区进行大量操作的情况
● String :是字符常量 , 适用于少量的字符串操作的情况
● StringBuilder :适用于单线程下在字符缓冲区进行大量操作的情况
● StringBuffer :适用多线程下在字符缓冲区进行大量操作的情况
Random
● Random类概述
此类用于产生随机数
● 构造方法
public Random()
l 成员方法
public int nextInt()
public int nextInt(int n)
Date类/Calendar类/ SimpleDateFormat类
Date类
● 使用Date类代表当前系统时间
Date d = new Date();
Date d = new Date(long d);
Calendar类
● Calendar类是一个抽象类,在实际使用时实现特定的子类的对象,创建
对象的过程对程序员来说是透明的,只需要使用getInstance方法创建
即可。
Calendar c1 = Calendar.getInstance();
c1.get(Calendar.
● SimpleDateFormat 日期格式化类
● 构造方法
SimpleDateFormat(格式); // yyyy-MM-dd
● 日期转字符串
Date now=new Date();
myFmt.format(now);
● 字符串转日期
myFmt.parse("2018-02-10");
字符串日期格式与 指定格式必须一致
例如:String s = "2018-03-15";
new SimpleDateFormat("yyyy-MM-dd")
BigInteger
● 在 Java 中,有许多数字处理的类,比如 Integer类,但是Integer类有一定的局限性。
● 我们都知道 Integer 是 Int 的包装类,int 的最大值为 2^31-1。若希望描述更大的
整数数据时,使用Integer 数据类型就无法实现了,所以Java中提供了BigInteger 类。
● BigInteger类型的数字范围较Integer,Long类型的数字范围要大得多,它支持任意
精度的整数,也就是说在运算中 BigInteger 类型可以准确地表示任何大小的整数值而
不会丢失任何信息。
● BigInteger类位于java.math包中
● 构造方法
BigInteger(String val) /BigInteger(byte[] val) ...
基本运算方法
add(),subtract(),multiply(),divide()
BigDecimal
● 在计算机中float 还是double都是浮点数,而计算机是二进制的,浮点数会失
去一定的精确度。
● 根本原因是:十进制浮点值没有完全相同的二进制表示形式;十进制浮点值的二进
制表示形式不精确,只能无限接近于那个值.
System.out.println((0.1 + 0.2)==0.3);//结果是?
但是,在项目中,我们不可能让这种情况出现,特别是金融项目,因为涉及金
额的计算都必须十分精确,你想想,如果你的支付宝账户余额显示
193.99999999999998,那是一种怎么样的体验?
• Java在java.math包中提供的API类BigDecimal
• 构造方法
BigDecimal(String val)
基本运算方法
add(),subtract(),multiply(),divide()

集合

Collection 接口
● Collection 接口-定义了存取一组对象的方法,其子接口 Set 和 List 分别定义
了存储方式。
● Set 中的数据对象不可以重复。
● List 中的数据对象有顺序 ( 添加顺序 ) 且可以重复。
List 接口及实现类
● List继承了Collection接口,有三个实现的类
- ArrayList
数组列表,数据采用数组方式存储。
- LinkedList
链表
- Vector
数组列表,添加同步锁,线程安全的
List 接口及实现类
ArrayList的常用方法
add(E element)
add(int index, E element)
get(int index)
indexOf(Object o)
lastIndexOf(Object o)
remove(int index) 删除并返回指定位置元素
set(int index, E element)
LinkedList的常用方法
add(int index,Object element)
addFirist(Object element)
addLast(Object element)
get(int index)
removeFirst()
removeLast()
remove(int index)
getFirst()
getLast()
Set 接口
● Set接口继承了Collection接口。
Set中所存储的元素是不重复的,但是是无序的, Set中的元素是没有索引的
● Set接口有两个实现类
● HashSet
HashSet类中的元素不能重复
● TreeSet
可以给Set集合中的元素进行指定方式的排序。存储的对象必须实现Comparable接口。
Set 接口
● Set接口继承了Collection接口。
Set中所存储的元素是不重复的,但是是无序的, Set中的元素是没有索引的
● Set接口有两个实现类
● HashSet
HashSet类中的元素不能重复
● TreeSet
可以给Set集合中的元素进行指定方式的排序。存储的对象必须实现Comparable接口。
HashMap
HashMap中元素的key值不能重复, 排列顺序是不固定的,可以存储一个
为null的键。
● TreeMap
TreeMap中所有的元素都保持着某种固定的顺序,如果需要得到一个有序
的Map就应该使用TreeMap,key值所在类必须实现Comparable接口。
● HashTable
实现了同步。
不能存储为null的键
Map 集合遍历
l 方式1:根据键找值
• 获取所有键的集合
• 遍历键的集合,获取到每一个键
• 根据键找值
l 方式2:根据键值对对象找键和值
• 获取所有键值对对象的集合
• 遍历键值对对象的集合,获取到每一个键值对对象
• 根据键值对对象找键和值
TreeMap
适用于按自然顺序或自定义顺序遍历键(key)。
TreeMap根据key值排序,key值需要实现Comparable接口,
重写compareTo方法。TreeMap根据compareTo的逻辑,对
key进行排序。
键是红黑树结构,可以保证键的排序和唯一性
Collections
● Collections 是集合类的工具类,与数组的工具类 Arrays 类似 .
addAl l(Col lection<? super T> c, T... elements);
binarySearch(List<? extends Comparable<? super T>> l ist, T key)
sort(List<T> l ist)
sort(List<T> l ist, Comparator<? super T> c)
swap(List<?> l ist, int i, int j)
copy(List<? super T> dest, List<? extends T> src) ; 注意 dest size 需大于等于 src.size
fi l l(List<? super T> l ist, T obj)
max(Col lection<? extends T> col l)
min(Col lection<? extends T> col l)
replaceAl l(List<T> l ist, T oldVal, T newVal)
reverse(List<?> l ist)
shuffle(List<?> l ist) 随机排序
copy(dest,src) 集合复制

异常

Java 异常概述
异常:
指的是程序在执行过程中,出现的非正常情况,如果不处理最终会导致
JVM的非正常停止。
• 异常指的并不是语法错误。语法错了,编译不通过,不会产生字节码文
件,根本不能运行。
异常的抛出机制
Java中是如何表示不同的异常情况,又是如何让程序员得知,并处理异常的呢?
Java中把不同的异常用不同的类表示,一旦发生某种异常,就创建该异常类型
的对象,并且抛出。
然后程序员可以捕获到这个异常对象,并处理;
如果没有捕获这个异常对象,那么这个异常将会导致程序终止。
● Throwable
java.lang.Throwable类是Java程序执行过程中发生的异常事件对应的类的根父类。
Throwable 中的常用方法:
public void printStackTrace() :打印异常的详细信息。
包含了异常的类型、异常的原因、异常出现的位置、在开发和调试阶段都得使用 printStackTrace 。
public String getMessage() :获取发生异常的原因。
Throwable可分为两类:Error和Exception。
分别对应着java.lang.Errorjava.lang.Exception两个类。
Error:Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源耗尽等
严重情况。一般不编写针对性的代码进行处理。
例如:StackOverflowError(栈内存溢出)和OutOfMemoryError(堆内存
溢出,简称OOM)。
Exception: 其它因编程错误或偶然的外在因素导致的一般性问题,需要使用针对
性的代码进行处理,使程序继续运行。否则一旦发生异常,程序也会挂掉。
常见的异常
异常--运行时异常
数组越界异常
类型转换异常
数字格式化异常
空指针异常
算术异常
异常处理
● Java的异常处理是通过5个关键字来实现的:try、catch、
finally、throw、throws
• 基本语法
try{
可能会发生异常的代码
}catch(异常类型 引用名){
异常处理代码
}finally{
必须执行代码
}
● try
检测不安全的代码块(发现异常)
try块中任何一条语句发生了异常,下面的代码将不会被执行,程序将
跳转到异常处理代码块中,即catch块。因此,不要随意将不相关的代
码放到try块中,因为随时可能会中断执行。
● catch
把抓到的类型匹配的异常捕获,保证程序能继续运行下去
catch语句必须紧跟着try语句之后,称为捕获异常,也就是异常处理函数,
一个try后面可以写多个catch,分别捕获不同类型的异常,要从子类往父类
的顺序写,否则有编译错误
捕获异常的有关信息:
与其它对象一样,可以访问一个异常对象的成员变量或调用它的方法。
• getMessage() 获取异常信息,返回字符串
• printStackTrace() 获取异常类名和异常信息,以及异常出现在程序中的
位置。返回值void。
● finally
finally该内容总是会执行的,只能有一个finally语句
finally{
必须执行的逻辑
}
● throws,定义一个方法的时候可以使用throws关键字声明,表示此方法
不处理异常,而交给方法调用处进行处理。
例如:
public void test throws 异常1,异常2,异常3{
}
● 任何方法都可以使用throws关键字声明异常类型,包括抽象方法。
● 调用使用了throws的方法时必须处理声明的异常,要么使用try-catch,要么
继续使用throws声明。
● 如果抛出的是运行期异常,则不会有任何提示,需要查看所调用的方法结构.
运行期异常和编译期异常
● 异常分为运行期异常和编译期异常两种
编译时期异常 (即checked异常、受检异常):在代码编译阶段,编译器就能明
确警示当前代码可能发生(不是一定发生)XX异常,并明确督促程序员提前编写
处理它的代码。如果程序员没有编写对应的异常处理代码,则编译器就会直接判
定编译失败,从而不能生成字节码文件。通常,这类异常的发生不是由程序员的
代码引起的,例如:FileNotFoundException(文件找不到异常)。
运行时期异常 (即runtime异常、unchecked异常、非受检异常):在代码编译
阶段,编译器完全不做任何检查,无论该异常是否会发生,编译器都不给出任何
提示。只有等代码运行起来并确实发生了XX异常,它才能被发现。通常,这类异
常是由程序员的代码编写不当引起的,只要稍加判断,或者细心检查就可以避免。
● java.lang.RuntimeException类及它的子类都是运行时异常。比如:
ArrayIndexOutOfBoundsException数组下标越界异常,
ClassCastException类型转换异常。
• throw关键字用于显式抛出异常,抛出的时候是抛出的是一个异常类的实例化
对象.
语法:throw new 异常类构造方法
如: throw new RunTimeException();
public static void someMethod() {
if (1==1) {
throw new RuntimeException(" 错误原因 ");
}
}
自定义异常
● 自定义异常就是自己定义的异常类,也就是API中的标准异常类的直接或间接的
子类
● 作用:用自定义异常标记业务逻辑的异常,避免与标准异常混淆
● 自定义异常类
● 基本语法
public class 异常类名 extends Exception/RuntimeException{
public 异常类名(String msg){
super(msg);
}
}
● 自定义异常类中往往不写其他方法,只重载需要使用的构造方法
● 继承Exception,在方法中使用throw抛出后,必须在方法中try-catch或
throws抛出

JDBC

● 注册JDBC驱动程序:
● 这需要初始化驱动程序,这样就可以打开与数据库的通信信道。
Class.forName("com.mysql.cj.jdbc.Driver"); //反射实现
或者
DriverManager.registerDriver(new Driver());
● 建立与数据库连接:
● 这需要使用 DriverManager.getConnection() 方法来创建一个
Connection 对象,它代表一个物理连接的数据库 .
● Connection conn =
DriverManager.getConnection(URL,USER,PASS);
URL:jdbc:mysql://ip(127.0.0.1): 端口 (3306)/ 数据库
名 ?serverTimezone=Asia/Shanghai
USER: 用户名 (root)
PASS: 密码
● 获得 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 集合
● 关闭与数据库的链接通道
● 每次操作完成后关闭所有与数据库交互的通道
st.close();
rs.close();
conn.close();
ps.close();
PreparedStatement Statement
基于以下的原因:
1、代码的可读性和可维护性.
虽然用PreparedStatement来代替Statement会使代码多出几行,但这样的代码无
论从可读性还是可维护性上来说.都比直接用Statement的代码高很多档次:
stmt.executeUpdate("insert into tb_name (col1,col2,col2,col4) values
('"+var1+"' , '"+var2+"' , "+var3+" , '"+var4+"')");
perstmt = con.prepareStatement("insert into tb_name (col1,col2,col2,col4)
values (?,?,?,?)");
perstmt.setString(1,var1);
perstmt.setString(2,var2);
perstmt.setString(3,var3);
perstmt.setString(4,var4);
perstmt.executeUpdate(); //prestmt是 PreparedStatement 对象实例
结果集处理
● PreparedStatement 和 Statement 中的 executeQuery() 方法中会返回一
个 ResultSet 对象 , 查询结果就封装在此对象中 .
● 使用 ResultSet 中的 next() 方法获得下一行数据
● 使用 getXXX(String name) 方法获得值

mysql数据库

**数据库概述**

数据库(DataBase)为了方便数据的存储和管理,它将数据按照特定的

规则存储在磁盘上,就是一个存储数据的仓库。

● 数据库的相关概念

DB:数据库(DataBase)

存储数据的容器,它保存了一系列有组织的数据。

DBMS:数据库管理系统(DataBase Management System)

又称为数据库软件或数据库产品,用于创建或管理DB。

● 常见的数据库产品:

国外

MySQL 快捷、可靠 开源、免费

Oracle:功能强大,收费.

SQL Server(微软): 只能安装在Windows操作系统

DB2 (IBM):适合处理海量数据,收费.

国内

南大通用GBASE: 天津南大通用数据技术股份有限公司

达梦:武汉达梦数据库股份有限公司

人大金仓:北京人大金仓信息技术股份有限公司

神通:神舟通用公司

MySQL是一个关系型数据库管理系统**,**由瑞典MySQL AB 公司开发,目

前属于 Oracle旗下产品。MySQL 流行的关系型数据库管理系统。

● MySql是一种关系数据库管理系统。

● MySql软件是一种开放源码软件,你可以修改源码来开发自己的 Mysql 系统。

● MySql数据库服务器具有快速、可靠和易于使用的特点。

● MySql使用标准的sql语言,并且支持多种操作系统,支持多种语言.

● mysql商业版与社区版

● MySQL商业版是由MySQL AB公司负责开发与维护,需要付费才能使用

● MySQL社区版是由分散在世界各地的MySQL开发者、爱好者一起开发与维

护,可以免费使用

命令行方式连接mysql

登录:mysql [-hlocalhost -P3306](本机可省略) -uroot -p(可以直

接写密码,不能有空格)

-h:主机名

-P:端口号

-u:用户名

-p:密码

退出:exit

• MySQL的常用命令

查看当前所有的数据库:show databases;

选择指定的库:use 库名

查看当前的所有表:show tables;

查看其他库的所有表:show tables from 库名;

查看mysql版本 select version();

• 安装可视化客户端工具

SQLyog / Navicat

结构化查询语言(Structured Query Language)简称SQL,是一种特殊

目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以

及查询、更新和管理关系数据库系统.

SQL优点:

不是某个特定数据库供应商专有的语是言,几乎所有DBMS都支持SQL

简单易学,灵活使用可以进行非常复杂和高级的数据库操作

**DDL**

● 数据(结构)定义语言DDL(Data Definition Language),是用于创

建和修改数据库表结构的语言。

● 常用的语句:create ,alter,drop,rename

创建,删除数据库

创建数据库并设置编码格式

CREATE DATABASE [if not exists] 数据库名 [ CHARSET utf8]

删除数据库

DROP DATABASE 数据库名 / [IF EXISTS数据库名];

修改字符集

ALTER DATABASE 数据库名 CHARSET gbk;

数据库表的基本概念

1、数据表

表(table)是数据存储的最常见和最简单的形式,是构成关系型数据库的基本元素。

表的最简单形式是由行和列组成,分别都包含着数据。 每个表都有一个表头和表体,表头定

义表名和列名 .表中的行被看作是文件中的记录,表中的列被看作是这些记录的字段。

2、字段

字段是表里的一列,用于保存每条记录的特定信息。如客户订单表的字段包括"订单

ID"、"姓名"、"客户ID"、"职务"、"上级"、"地区"、"运货商"、"国家"等。

数据表的一列包含了特定字段的全部信息。

3、记录

记录也被称为一行数据,是表里的一行数据。

设计表(数据类型)

char(n) 长度为n的定长字符串,最大长度255个字符

varchar(n) 最大长度为n的可变长字符串

date 日期, 包含年月日

datetime 年月日 时分秒

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/9665691e861c46aea796acb2f45688e4.png)

设计表(数据类型)

浮点

decimal

数据类型(M,D)

M:精度,数据的总长度;

D:标度,小数点后的长度

设计表(数据类型)

TEXT列字符字符串

有4种TEXT类型:TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT。

它的长度:

TINYTEXT:最大长度255个字符(2^8-1)

TEXT:最大长度65535(2^16-1)

MEDIUMTEXT:最大长度16777215(2^24-1)

LONGTEXT最大长度4294967295(2^32-1)

主键:

在一张表中代表唯一的一条记录,不能为空,不能重复

约束:

PRIMARY KEY 设置主键约束

NOT NULL 不能为空约束

UNIQUE 唯一性约束

检查约束 设置条件

外键约束

主键自动增长,设置为自动增长时,只能为整数类型

AUTO_INCREMENT

默认值

DEFAULT default_value

字段注释:

comment '注释'

创建表语法:

CREATE TABLE 表名(列名 数据类型 [约束] [默认值] [ 注释],......)

CREATE TABLE t_user(

id INT [PRIMARY KEY NOT NULL AUTO_INCREMENT],

number INT(5) NOT NULL,

stuname VARCHAR(10) NOT NULL,

age INT(3) CHECK(age>18),

birthday DATE,

weight DOUBLE,

opertime datetime,

[CONSTRAINT 约束名 约束规则]

)

删除表,修改表名

删除表

DROP TABLE [if exists ]表名

修改表名

RENAME TABLE 旧表名 TO 新表名

复制表结构

CREATE TABLE 新表名 LIKE 被复制表名;

实例

```mysql

-- 创建数据库

-- CREATE DATABASE [if not exists] 数据库名 [ CHARSET utf8]

CREATE DATABASE test;

-- 创建数据库 并设置字符集编码

CREATE DATABASE schooldb CHARSET utf8;

-- 创建数据库 并设置字符集编码 并判断数据库是否存在

CREATE DATABASE IF NOT EXISTS test CHARSET utf8;

-- 删除数据库

DROP DATABASE test;

-- mysql数据库一旦创建不能修改,只能修改字符集编码

ALTER DATABASE test CHARSET utf8;

/*

创建数据库表

表 表名

列 特定信息 姓名,性别....

行 数据 张三 男

创建表的步骤:

确定表名: 学生信息 -- 学生表

确定列名: 学生的具体信息 姓名,性别,生日....

列的数据类型:

字符串型:

char(n) 长度为n的定长字符串, 例如n=5, 如果我们只存储了2个字符进去,长度依然是5,会补空格

一般用来存储长度固定的数据, 例如性别,电话.

varchar(n) 最大长度为n的变长字符串, 例如n=10,如果我们只存储了3个字符,实际长度为3

日期时间类型

date 日期--年月日

datetime 时间--年月日 时分秒

数值

整数

TINYINT 1

SMALLINT 2

MEDIUMINT 3

int 4

bigint 8

浮点:

decimal(M,D)

3,2

1.73

TEXT列字符字符串 长文本类型 例如存储新闻信息,小说...

列的约束: 列的规则

*/

-- 学生表 学号,姓名,性别,生日,电话,地址,身高,注册时间

CREATE TABLE student(

num INT,

NAME VARCHAR(10),

gender CHAR(1),

birthday DATE,

phone CHAR(11),

address VARCHAR(30),

height DECIMAL(3,2),

reg_time DATETIME

)

-- 删除表

DROP TABLE student

-- 创建表,并为列添加约束

/*

学号 唯一,不能为空 而且只能有一个学号

可以为学号列添加主键约束(唯一不能重复,不能为空,一个表中只能有一个列添加主键约束)

PRIMARY KEY 设置列为主键

AUTO_INCREMENT 设置主键列自动增长, 只能修饰主键列,而且主键列类型为整数

not null 不能为空约束 可以添加到多个普通列

unique 唯一约束 可以添加到多个普通列

CHECK(height<2.60) 检查约束

*/

CREATE TABLE student(

num INT PRIMARY KEY AUTO_INCREMENT,

NAME VARCHAR(10) NOT NULL,

gender CHAR(1) NOT NULL,

birthday DATE,

phone CHAR(11) NOT NULL UNIQUE,

address VARCHAR(30),

height DECIMAL(3,2) CHECK(height<2.60),

reg_time DATETIME

)

DROP TABLE student

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,

phone CHAR(11) NOT NULL UNIQUE,

address VARCHAR(30),

height DECIMAL(3,2) CHECK(height<2.60),

reg_time DATETIME

)

-- 修改表名

RENAME TABLE student TO stu

RENAME TABLE stu TO student

-- 复制表结构

CREATE TABLE stu LIKE student

```

**DML**

数据操纵语言DML(Data Manipulation Language)

● 常用语句: insert,delete,update

插入数据

方式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) 查询语句(查询的列数与插入列数匹配

修改数据

UPDATE 表名 SET 列名 = '新值'WHERE 条件

删除数据

DELETE FROM 表名 WHERE 条件

TRUNCATE TABLE 表名;清空整张表

实例

```mysql

-- DML 表数据操作语句

-- insert delete update

/*

方式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,birthday,phone)VALUES('张三','男','2003-3-5','15233336666')

INSERT INTO student(NAME,gender,birthday,phone,address,height,reg_time)

VALUES('张三','男','2003-3-5','15233336688','汉中',1.75,NOW())

INSERT INTO student(NAME,gender,birthday,phone,address,height,reg_time)

VALUES('张三丰','男','2003-3-5','15233336677','汉中',1.75,NOW()),

('李四','女','2003-3-3','15233336699','汉中',1.85,NOW()),

('王五','男','2003-4-3','15233336609','汉中',1.95,NOW())

INSERT INTO student SET NAME = '赵六',gender='女',phone='15777778888'

INSERT INTO stu(NAME,gender,birthday,phone,address,height,reg_time)

SELECT NAME,gender,birthday,phone,address,height,reg_time FROM student

-- 修改语句 需要注意条件的准确性, 否则修改所有的数据

UPDATE student SET address='陕西西安',height=1.65,reg_time = '2003-4-5 14:20:10' WHERE num = 1

-- 删除语句

DELETE FROM stu -- 没有条件 删除所有的数据

DELETE FROM student WHERE num = 13

```

**DQL-****基础查询**

● DQL(Data Query Language)数据查询语言查询是使用频率最高的一个操作,

可以从一个表中查询数据,也可以从多个表中查询数据。

● 基础查询

● 语法:

select 查询列表 from 表名;

● 特点:

查询列表可以是:表中的字段、常量、表达式、函数

查询的结果是一个虚拟的表格

● 查询结果处理:

特定列查询:select column1,column2 from table

全部列查询: select * from table

算数运算符:+ - * /

排除重复行: select distinct column1,column2 from table

查询函数:select 函数; / 例如version()

● 查询结果处理:

● 函数:类似于java中的方法,将一组逻辑语句事先在数据库中定义好,可以直接调

分类:

单行函数:如concat、length、ifnull等

分组函数:做统计使用,又称为统计函数、聚合函数、组函数

单行函数

● 字符函数

length():获取参数值的字节个数

char_length()获取参数值的字符个数

concat(str1,str2,.....):拼接字符串

upper()/lower():将字符串变成大写/小写

substring(str,pos,length):截取字符串 位置从1开始

instr(str,指定字符):返回子串第一次出现的索引,如果找不到返回0

trim(str):去掉字符串前后的空格或子串,trim(指定子串 from 字符串)

lpad(str,length,填充字符):用指定的字符实现左填充将str填充为指定长度

rpad(str,length,填充字符):用指定的字符实现右填充将str填充为指定长度

replace(str,old,new):替换,替换所有的子串

● 单行函数

• 逻辑处理

case when 条件 then 结果1 else 结果2 end; 可以有多个when

ifnull(被检测值,默认值)函数检测是否为null,如果为null,则返回指定的值,否则返回

原本的值

if函数:if else的 效果 if(条件,结果1,结果2)

● 单行函数

● 数学函数

round(数值):四舍五入

ceil(数值):向上取整,返回>=该参数的最小整数

floor(数值):向下取整,返回<=该参数的最大整数

truncate(数值,保留小数的位数):截断,小数点后截断到几位

mod(被除数,除数):取余,被除数为正,则为正;被除数为负,则为负

rand():获取随机数,返回0-1之间的小数

● 单行函数

日期函数

now():返回当前系统日期+时间

curdate():返回当前系统日期,不包含时间

curtime():返回当前时间,不包含日期

可以获取指定的部分,年、月、日、小时、分钟、秒

YEAR(日期列),MONTH(日期列),DAY(日期列) ,HOUR(日期列) ,MINUTE(日期列)

SECOND(日期列)

str_to_date(字符串格式日期,格式):将日期格式的字符转换成指定格式的日期

date_format(日期列,格式):将日期转换成字符串

datediff(big,small):返回两个日期相差的天数

分组函数

功能:用作统计使用,又称为聚合函数或统计函数或组函数

分类:sum 求和、avg 平均值、max 最大值、min 最小值、count 计数

(非空)

1.sum,avg一般用于处理数值型max,min,count可以处理任何类型

2.以上分组函数都忽略null值

3.count函数的一般使用count(*)用作统计行数

4.和分组函数一同查询的字段要求是group by后的字段

条件查询

使用WHERE 子句,将不满足条件的行过滤掉,WHERE 子句紧随 FROM 子句。

语法:select <结果> from <表名> where <条件>

比较

=, != 或<>, >, <, >=, <=

逻辑运算

and 与

or 或

not 非

● 条件查询

模糊查询

LIKE

:是否匹配于一个模式 一般和通配符搭配使用,可以判断字符型数值

或数值型.

通配符: % 任意多个字符

between and 两者之间,包含临界值;

in 判断某字段的值是否属于in列表中的某一项

IS NULL(为空的)或 IS NOT NULL(不为空的)

1、UNION 的语法如下:

[SQL 语句 1]

UNION

[SQL 语句 2]

2、UNION ALL 的语法如下:

[SQL 语句 1]

UNION ALL

[SQL 语句 2]

当使用union 时,mysql 会把结果集中重复的记录删掉,而使用union all ,

mysql 会把所有的记录返回,且效率高于union 。

排序

查询结果排序,使用 ORDER BY 子句排序 order by 排序列 ASC/DESC

asc代表的是升序,desc代表的是降序,如果不写,默认是升序

order by子句中可以支持单个字段、多个字段

• 数量限制

limit子句:对查询的显示结果限制数目 (sql语句最末尾位置)

SELECT * FROM table LIMIT offset rows;

SELECT * from table LIMIT 0,5;

分组查询

语法:

select 分组函数,列(要求出现在group by的后面)

from 表

[where 筛选条件]

group by 分组的列表

[having 分组后的筛选]

[order by 子句]

注意:查询列表比较特殊,要求是分组函数和group by后出现的字段

分组查询中的筛选条件分为两类:

数据源 源位置 关键字

分组前筛选 原始表 group by子句的前面 where

分组后筛选 分组后的结果集 group by的后面 having

实例

```mysql

-- 基本查询语法

-- select 查询的列 from 表名 where 条件 排序 数量限制 分组....

-- select 结果处理 from 表名

-- 结果处理

-- 查询特定的列

SELECT num,NAME,gender FROM student

-- 查询所有的列, 在开发中一般不建议, 使用哪些列,查询哪些

SELECT * FROM student

-- sql中+ - * / 只能做算数运算 +不能连接字符串

SELECT num+100,NAME FROM student

-- 字符串函数 连接多个字符串

SELECT num,CONCAT(NAME,':',gender)AS NAME FROM student

SELECT VERSION();

-- 去除查询结果中重复数据, 何为重复数据: 所有的列都相同

SELECT DISTINCT NAME,gender,birthday FROM student

-- 查询结果中使用函数

-- 单行函数--会对查询的每条记录进行操作

-- 分组函数--sum() 也称为聚合函数,统计函数, 把多行数据最终处理为一行

-- 字符函数

-- length():获取参数值的字节个数

SELECT NAME,LENGTH(NAME) FROM student

-- char_length()获取参数值的字符个数

SELECT NAME,CHAR_LENGTH(NAME)AS NAME,gender FROM student

-- concat(str1,str2,.....):拼接字符串 as 别名

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,2,3) FROM student

-- instr(str,指定字符):返回子串第一次出现的索引(indexof()),如果找不到返回0

SELECT INSTR(NAME,'三') FROM student

-- trim(str):去掉字符串前后的空格或子串,trim(指定子串 from 字符串)

SELECT CHAR_LENGTH(TRIM(NAME)) FROM student

SELECT TRIM('张' FROM NAME) FROM student

-- lpad(str,length,填充字符):用指定的字符实现左填充将str填充为指定长度

SELECT LPAD(NAME,5,'a') , RPAD(NAME,5,'b')FROM student

-- rpad(str,length,填充字符):用指定的字符实现右填充将str填充为指定长度

-- replace(str,old,new):替换,替换所有的子串

SELECT REPLACE(NAME,'i','I') FROM student

/*

case when 条件 then 结果1 else 结果2 end; 可以有多个when

ifnull(被检测值,默认值)函数检测是否为null,如果为null,则返回指定的值,否则返回

原本的值

if函数:if else的 效果 if(条件,结果1,结果2)

*/

SELECT NAME,

(CASE WHEN height>=1.80 THEN '高个子' ELSE '正常身高' END)AS height,

gender

FROM student

SELECT NAME,

(CASE WHEN height>=1.80 THEN '高个子'

WHEN height>=1.60 THEN '正常身高'

ELSE '低个子' END) AS height,

gender

FROM student

SELECT NAME,IFNULL(address,'暂未录入')AS address FROM student

SELECT NAME,IF(height>=1.80,'高个子','正常身高') FROM student

-- 数学函数

-- round(数值):四舍五入

SELECT NAME,ROUND(height) FROM student

-- 指定保留小数位数

SELECT NAME,ROUND(height,1) FROM student

-- ceil(数值):向上取整,返回>=该参数的最小整数

SELECT NAME,CEIL(height),FLOOR(height) FROM student

-- floor(数值):向下取整,返回<=该参数的最大整数

-- truncate(数值,保留小数的位数):截断,小数点后截断到几位, 不会四舍五入

SELECT NAME,TRUNCATE(height,1) FROM student

-- mod(被除数,除数):取余,被除数为正,则为正;被除数为负,则为负

SELECT NAME, MOD(num,3) FROM student

-- rand():获取随机数,返回0-1之间的小数

SELECT NAME, RAND() FROM student

-- 日期函数

-- now()

SELECT NAME, NOW(),CURDATE(),CURTIME() FROM student

-- 日期格式化

SELECT NAME, YEAR(reg_time),MONTH(reg_time),DAY(reg_time) FROM student

-- select count(*) from student group by year(birthday)

-- 将字符串格式化为日期类型

SELECT STR_TO_DATE('2001-2-2','%Y-%m-%d') FROM student

-- 将日期格式化为指定的字符串

SELECT DATE_FORMAT(birthday,'%Y-%m') FROM student

-- 计算两个日期之间相差的天数

SELECT DATEDIFF(CURDATE(),birthday) FROM student

SELECT DATEDIFF(STR_TO_DATE('2020-1-1','%Y-%m-%d'),birthday) FROM student

-- 分组函数 / 聚合函数, 统计函数、

-- sum 求和、avg 平均值 、 max 最大值 、 min 最小值、count 计数

-- sum(), avg() 只能用于数值类型

-- max (), min() ,count()可以适用于所有类型

-- 2.以上分组函数都忽略null值

-- 3.count函数的一般使用count(*)用作统计行数

-- .和分组函数一同查询的字段(属性)要求是group by后的字段(属性)

SELECT SUM(height),AVG(height) ,MAX(height),MIN(height) FROM student

SELECT MAX(height),MIN(height) FROM student

-- 统计行数 count(*)官方推荐的 count(1) count (列名) 列的值为空不统计

SELECT COUNT(*) FROM student

SELECT COUNT(address)FROM student

SELECT COUNT(1) FROM student

SELECT COUNT(num) FROM student

SELECT * FROM student WHERE height= ( SELECT MAX(height) FROM student)

```

```mysql

-- 条件查询 select 结果列 from 表名 where 条件

SELECT * FROM student WHERE num = 1

-- and 所有条件都需要满足

SELECT *FROM student WHERE gender = '男' AND height>=1.70 AND address = '汉中'

-- or 满足一个条件即可

SELECT *FROM student WHERE gender = '男' OR height >=1.70

-- 不等于

SELECT * FROM student WHERE gender != '男'

SELECT * FROM student WHERE gender <> '男'

-- 模糊查询 like %字符% 通配符

SELECT * FROM student WHERE NAME LIKE '张%'

SELECT * FROM student WHERE NAME LIKE '%三%'

SELECT *FROM student WHERE height >=1.70 AND height <= 2.0

SELECT *FROM student WHERE height BETWEEN 1.70 AND 2.0

SELECT *FROM student WHERE height = 1.75 OR height = 1.85 OR height = 1.95

-- 查询身高 1.75 1.85 1.95

SELECT *FROM student WHERE height IN(1.75,1.85,1.95)

SELECT *FROM student WHERE height NOT IN(1.75,1.85,1.95)

-- 查询值为空的数据

SELECT *FROM student WHERE address IS NULL

SELECT *FROM student WHERE address IS NOT NULL

-- union 合并多个结果 并去重 合并多个查询的结果,可以去除重复的数据

SELECT num ,NAME, gender FROM student WHERE gender = '男'

UNION

SELECT num ,NAME, gender FROM student WHERE gender = '女'

SELECT num ,NAME, gender FROM student WHERE gender = '男'

UNION ALL

SELECT num ,NAME, gender FROM student WHERE gender = '女'

SELECT num ,NAME, gender FROM student WHERE gender = '男'

UNION

SELECT num ,NAME, gender FROM student WHERE height = 1.65

-- union all 合并多个查询结果, 只是合并, 不去重

-- 当使用union 时,mysql 会把结果集中重复的记录删掉,而使用union all ,

-- mysql 会把所有的记录返回,且效率高于union 。

SELECT num ,NAME, gender FROM student WHERE gender = '男'

UNION ALL

SELECT num ,NAME, gender FROM student WHERE height = 1.65

UNION ALL

SELECT num ,NAME, gender FROM student WHERE height = 1.75

-- 排序

-- 按升高排序, 默认是升序排序

SELECT *FROM student ORDER BY height

SELECT *FROM student ORDER BY height ASC

-- ASC 升序(默认) DESC降序

SELECT *FROM student ORDER BY birthday DESC

SELECT *FROM student ORDER BY height DESC

-- 多个排序条件

SELECT *FROM student WHERE num > 0 ORDER BY birthday DESC, height ASC-- 先对生日排序 在生日排序的基础上再对升高排序

-- 先对生日进行降序排序 再对身高进行升序排序(先对生日进行降序排序, 在生日相同的数据中进行身高的升序排序)

-- 有生日相同再对身高进行排序

-- 什么排序都没有,默认主键 升序排序

SELECT * FROM student

-- 数量限制 limit 开始位置(开始为0),查询数量

-- 实际使用场景, 数据分页显示 一次只查询一部分数据 , 提高查询效率

SELECT * FROM student LIMIT 0,2 -- 1 查询页码

SELECT * FROM student LIMIT 2,2 -- 2

SELECT * FROM student LIMIT 4,2 -- 2

-- limit (n-1)*2,2

-- limit 在sql的最末尾

SELECT *FROM student WHERE num>0 ORDER BY height DESC LIMIT 0,2

-- 分组查询

-- 将某类数据分到一个组中进行处理 例如性别查询

-- 查询男生 女生各有多少人(统计数量) 例如按性别分组 每月增量

-- GROUP BY 分组条件(列名)

-- 出现分组group by ,分组查询 select 查询属性只能出现group by后面的分组条件(属性)

-- 否则报错

-- group by中出现的属性 select 中必须出现这个属性否则报错

SELECT COUNT(*) ,gender FROM student GROUP BY gender -- select后面只能出现分组属性(条件)

SELECT SUM(height),gender FROM student GROUP BY gender -- 男女的各个的总身高

SELECT AVG(height),gender FROM student GROUP BY gender -- 男女的各个平均升高

-- 统计每年出生的人数

SELECT COUNT(*),DATE_FORMAT (birthday,'%Y')FROM student GROUP BY DATE_FORMAT (birthday,'%Y')

SELECT COUNT(*),YEAR (birthday)FROM student GROUP BY YEAR (birthday)

SELECT COUNT(*) ,gender FROM student WHERE num> 0 GROUP BY gender -- 先筛选(条件)后分组

-- 分组统计名字数量, 查询哪些名字重复了

-- where 是对原始表中的数据进行过滤

-- HAVING 在group by 后面使用 给分组后的数据加过滤条件

SELECT COUNT(*) n,NAME FROM student GROUP BY NAME HAVING COUNT(*)>1

SELECT * FROM (SELECT COUNT(*)AS n,NAME FROM student GROUP BY NAME) AS t WHERE t.n>1

```

**多表设计****_****关联查询**

● 数据库设计范式

● 1.第一范式(确保每列保持原子性)

第一范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原子值,就

说明该数据库表满足了第一范式。

● 数据库设计范式

2. 第二范式就是要有主键,要求其他字段都依赖于主键。

• 没有主键就没有唯一性,没有唯一性在集合中就定位不到这行记录,所以要主键。

• 其他字段为什么要依赖于主键?因为不依赖于主键,就找不到他们。更重要的是,其

他字段组成的这行记录和主键表示的是同一个东西,而主键是唯一的,它们只需要依

赖于主键,也就成了唯一的。

● 数据库设计范式

3.第三范式,确保每列都和主键列直接相关,而不是间接相关,要求一个数据库表中不包含

已在其它表中包含的非主关键字信息

● 外键:引用另外一个数据表的某条记录。

外键列类型与主键列类型保持一致

数据表之间的关联/引用关系是依靠具体的主键(primary key)和外键

(foreign key)建立起来的。

create table student(

id int not null auto_increment primary key,

num int,

name varchar(10)

majorid int,

CONSTRAINT 约束名 foreign key(majorid ) references major(id)

);

约束名规则:

例:FK_ForeignTable_PrimaryTable_On_ForeignColumn

1、当主表中没有对应的记录时,不能将记录添加到从表

2、不能更改主表中的值而导致从表中的记录孤立

3、从表存在与主表对应的记录,不能从主表中删除该行

4、删除主表前,先删从表

关联查询

含义:又称多表查询,当查询的字段来自于多个表时,就会用到连接查询

笛卡尔乘积现象:表1有m行,表2有n行,结果=m*n

发生原因:没有有效的连接条件

如何避免:添加有效的连接条件

按功能分类:

自连接

内连接

外连接

左外连接

右外连接

● 关联查询

● 内连接(inner join)

● 把满足了条件的两张表中的交集数据查询出来

语法:Select 结果 from 表1,表2 where 表1.column1 = 表2.column2

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/8d392dac78064aa9842614bfb45f98ef.png)

● 多表关联

● 左外连接(left join)

select 结果 from

表1 left join 表2 on

表1.column1 = 表2.column2

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/ada039fbd12b4a8abf085914d221afd0.png)

多表关联

右外连接(right join)

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/54764e7c92524b168a6f2613bfdfeb64.png)

实例

```mysql

/*

数据库设计范式(范例)

好的数据库设计,事倍功半,不会有歧义

第一范式 : 列(属性)保证原子性(属性不可再分)

联系方式: 电话/邮箱/qq(可在分,不呈现原子性)

第二范式 : 要有主键 其他字段(属性) 必须依赖于某个列(主键)

通过主键可以精确定位到某行数据(元组)

第三范式:保每列都和主键列直接相关

就是在一个表中关联另一个表 ,这个表中加的是另一个表中的主键, 不添加另一个表中非主键的内容(否则会出现数据冗余)

因为可以根据外键找到另一个表中非主键的信息

如果两张表有关系的话,只需要在一张表放置另一个表的主键进行关联,关联表中其他的非主键信息不需要了(没必要加, 加上反而数据冗余浪费空间使表不美观)

学生关联专业

例如通过 专业编号可以找到 该专业编号对应的名称以及其他信息

*/

/*

专业信息 -- 专业表

学生关联专业

*/

CREATE TABLE major(

id INT PRIMARY KEY AUTO_INCREMENT ,

NAME VARCHAR(20) NOT NULL

)

-- 修改表, 添加列

ALTER TABLE student ADD majorid INT

-- majorid 称为外键(外码) 不是这个关系的主码是另一个关系的主码则称这个码为这个关系的外码(例如majorid)

-- 外键必须是与另一个表的主键关联 , 且数据类型一致

-- 通过学生表中的majorid(属性 )列 把学生与专业关联起来, 在学生表中只需要添加专业编号就行

-- 其他信息不需要添加

ALTER TABLE student ADD CONSTRAINT fk_student_major_on_majorid FOREIGN KEY (majorid)REFERENCES major(id)

-- 表与表关系 : 多对一关系 也可以称为一对多

-- 给student 添加外键约束 要给majorid添加 说明在major中是主键 不是student的主键是major的主键

-- 说明majorid 是student的外键 这样就让这两个表进行了关联

-- 添加外键约束, 为什么要添加约束, 如果没有添加约束,数据与数据之间,没有任何束缚,可以随意操作,

-- 例如删除专业, 但是专业还有学生关联, 此种场景删除专业就不太友好.(对不上号)

-- 对外建添加约束后, 操作时就不能随便操作了, 保证数据的完整性

CREATE TABLE course(

id INT PRIMARY KEY AUTO_INCREMENT,

NAME VARCHAR(20)

)

DROP TABLE course

/*

学生选课关系

多对多关系

课程表

由于一个学生可以选择多个课程,所以在学生表中添加课程外键就行不通了.

一个课程可以被多名学生选

需要再设计一个学生选课表(只要存储学生和课程的编号(主键)即可), 一般把这种表也称为关系表(联系表)

*/

CREATE TABLE student_course (

id INT PRIMARY KEY AUTO_INCREMENT,

student_num INT,

courseid INT,

CONSTRAINT fk_student_student_course_on_student_num FOREIGN KEY (student_num) REFERENCES student(num),

CONSTRAINT fk_couse_student_course_on_courseid FOREIGN KEY (courseid) REFERENCES course(id)

)

```

```mysql

-- 关联查询

-- 查询学生信息 学号,姓名,性别,生日,专业名称

-- select * from student,major 表与表没有添加任何的关联条件 ,导致出现笛卡尔乘积现象.

-- 内连接

SELECT * FROM student,major

-- 如何避免卡尔乘积现象? 为关联添加条件,只把满足条件数据过滤出来

SELECT * FROM student,major WHERE majorid= id

SELECT

s.num ,

s.name,

s.gender,

m.name,

m.id

FROM student s INNER JOIN major m ON s.majorid=m.id

WHERE gender ='男'

-- 外连接

-- 左外连接 把左边表的满足条件的和不满足条件的都查询出来, 右边表只把满足条件的查询出来这就是左外连接

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),

m.name

FROM

student s

RIGHT JOIN major m

ON s.majorid = m.id

GROUP BY m.name

-- group_concat(c.name) cname

-- 学号,姓名,性别,专业名,选择的课程名称

-- GROUP_CONCAT(c.name) 把同一个组中,多个课程名称连接起来

SELECT

s.num,

s.name,

s.gender,

m.name,

GROUP_CONCAT(c.name) cname

FROM student s LEFT JOIN major m ON s.majorid= m.id

LEFT JOIN student_course sc ON s.num = sc.student_num -- 学生表里面的学号与选课表里面的学号进行连接

LEFT JOIN course c ON c.id = sc.courseid -- 课程表里面的课程编号与选课表里面的课程编号进行连接

-- 课程表里面的课程编号与选课表里面的课程编号进行连接

GROUP BY s.num,s.name, s.gender,m.name

-- 查询结果可以看出学生 的专业以及学生选的课程

```

相关推荐
m0_571957581 小时前
Java | Leetcode Java题解之第543题二叉树的直径
java·leetcode·题解
C吴新科3 小时前
MySQL入门操作详解
mysql
魔道不误砍柴功3 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_2343 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
闲晨3 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
测开小菜鸟5 小时前
使用python向钉钉群聊发送消息
java·python·钉钉
Ai 编码助手5 小时前
MySQL中distinct与group by之间的性能进行比较
数据库·mysql
P.H. Infinity6 小时前
【RabbitMQ】04-发送者可靠性
java·rabbitmq·java-rabbitmq
生命几十年3万天6 小时前
java的threadlocal为何内存泄漏
java
陈燚_重生之又为程序员6 小时前
基于梧桐数据库的实时数据分析解决方案
数据库·数据挖掘·数据分析