MySQL
1.MySQL基础
(1).登录MySQL:(两种方法)
①在DOS命令中,==mysql -u+用户名 -p+密码;==(加号相当于紧挨着无空格) ②在DOS命令中,==mysql -u+用户名 -p----->回车----->输入密码==(可隐藏密码)
(2).修改密码:(两种方法)
①在DOS命令中,进入mysql>界面后,输入以下指令:==set password for 用户名@localhost=password('新密码在此处');== ②在DOS命令中,输入==mysql -u+用户名 -p+旧密码 password 新密码==
(3).退出mysql:
输入:==exit==或者==quit==或者 ==\q==
(4).mysql的卸载:(易遗漏)
①Windows10系统中,打开==文件==点击==选项==进入==文件夹选项==,进入==查看==的==高级设置==中找到==显示隐藏文件、文件夹及驱动器==,选中; ②点开mysql安装包卸载; ③进入安装目录卸载==MySQL==目录; ④进入==C盘==中隐藏的==ProgramData==目录找到MySQL,删除即可。 Tips:②、③、④三步缺一不可,走完三步走才算作删除干净。
2.SQL语言
(1)概念:
结构化查询语言,属于高级语言,同为先编译后运行。
(2)编译与执行操作:
DBMS(执行)-->SQL(操作)-->DB。
(3)数据库的组成:
①==表(table)==是数据库的基本组成单元; ②在表中,行叫 作==数据==,列叫作==字段==; ③在表中,每个字段都有相应的==字段名和数据类型等==。
(4)分类:
①==DQL==(DateQueryL):数据查询语言,例:select......; ②==DDL==(DataDefinition):数据定义语言,例:create,drop,alter...(对表结构的增删改); ③==DML==(DataManipulation):数据操作语言,例:insert,delete,update...(对表中数据的增删改); ④==TCL==(TransactionalControl):事务控制语言,例:commit(提交事务)... ⑤==DCL==(DataControl):数据控制语言,例:grant(授权),revoke(撤权)...;
(5)常用命令:(+处加空格)
①查看当前数据库:select database(); ②查看mysql版本号:select version(); ③结束一条语句:==\c==; ④查看创建表的语句:show create table+表名。
(6)导入数据的语句:(+处加空格)
①登录Mysql; ②查看全部数据库:==show databases;== ③创建数据库:==create database+数据库名;== ④使用数据库:==use+数据库名;== ⑤查看数据库中的表:==show tables;== ⑥初始化数据:==source+绝对路径\数据库名.sql;== ⑦查看表中的结构:==desc+表名;(describe)== ⑧查看表中的数据:==select * from+表名;== ⑨删除数据库:==drop database+数据库名;==
(7)查询语句(DQL语句):
<1>.简单查询:
①简单查询语法格式:
==select+字段名1,字段名2,...+from+表名;==
②字段重命名:
select 字段名1 (as)+重命名,字段名2 (as)+重命名 from 表名
③查询所有数据:
select * from+表名; Tips:使用*的缺点有: ①效率低;②可读性差。
④查询结果的去重:
select distinct+字段名 from 表名;
Tips:distinct关键字只能出现在字段最前面。
<2>.条件查询:
①条件查询语法格式:
select 字段1,字段2... from 表名 where 条件;
Tips:执行顺序from--->where--->select。
②查询介于两数之间的表达:
...... (例如,查xxx字段在1100-3000之间的数据) where xxx>=1100 and xxx<=3000; 或者⬇ where xxx between 1100 and 3000;
Tips:between ... and ...语句前后都为闭区间。
③某字段的定点查询or/in:
...... (例如,查xxx字段等于‘A’或者等于'B'的数据) where xxx ='A' or xxx ='B'; 或者⬇ where xxx in ('A','B');
Tips:==and==的优先级大于==or==; ==in==前可加==not==表示否定。
④模糊查询like:
... (例如,查xxx字段以‘a’开头的数据) where xxx like 'a%'
Tips:'%'代表任意多个字符,'_'代表任意一个字符。
⑤排序order by:
... (例如对xxx字段进行排序) order by 字段名 by+(asc/desc);
Tips:默认升序排列; by后面的==asc==代表升序,==desc==代表降序。 当同时对多个字段进行排序时,前字段相同时才会比较后字段。
<3>.分组查询:
①定义:
按照某个或某些字段进行分组;
②语法格式:
==select+分组函数 from+表名 (where+条件) group by+字段xxx having+条件。==
③group by与having:
A.有分组参与的查询各语句执行顺序: ==from找表->where初过滤->group by分组->having过滤->select查找->order by排序== B.一条语句中有group by 时,select后仅能跟==分组函数==或==参与分组的字段==; C.调用avg(xxx)函数时,不能使用where,会改变平均值,使用having; D.where后不能跟分组函数但having后可以。(执行顺序推论)
④分组函数:
A.count(字段xxx); //对字段进行==计数==(忽略null); B.sum(字段xxx); //对字段数据==求和==(忽略null); C.max(字段xxx); //求字段的==最大值==; D.min(字段xxx); //求字段的==最小值==; E.avg(字段xxx); //求字段的==平均值==;
⑤单行处理函数:
A.ifnull(字段xxx,0); //若xxx字段为NULL时,被当作0处理; B.count(*); //统计总记录条数
<4>.连接查询:
①笛卡尔积现象:
两张表连接查询时,无条件限制,查询结果条数是两表条数乘积;
Tips:笛卡尔积现象使查询效率降低,where后设置筛选条件可避免该现象;
②表的别名法连接查询:
select 表别名1.字段名1,表别名2.字段名2... from 表名1 表别名1,表名2 表别名2;
Tips:起别名的方法提高了程序执行效率且可读性高。
③内连接:
A.等值连接:条件1是等值关系;
语法格式:
select 字段1,字段2... from 表名1 (innner) join 表名2 on 条件1 where 条件2;
B.非等值连接:条件是不等值关系;
语法格式:
与等值连接相似,条件on处使用非等值语句即可,比如between...and...等;
C.自连接:一张表看作两张,我连我自己;
同分为等值与非等值连接;
实例:员工的领导表和领导的员工表。
select //一样的表的不同别名 e.name,m.name from //连接员工表e与m employee e join employee m on //设置条件e表的领导编号等于m表的员工编号 e.managerNo = m.employeeNo;
④外连接:
A.左连接:左边的表是主表;
语法格式:
select 字段 from 表名1 left (outer) join 表名2 on 条件;
B.右连接:右边的表是主表;
语法格式:
与左连接语法格式相似,将left关键字改为right即可。
⑤外内连接的区别:
①内连接两表平等,无主副之分; ②外连接分主副表,主要查询主表数据,若副表无与之匹配的数据,自动模拟为NULL; ③主表的数据无条件全部查出。(比如,领导King的领导名被模拟为NULL)
⑥全连接:左右两表均为主表;
<5>.三张表连接进行查询:
语法规则:
select 字段1,字段2,... from 表名1 (left/right) join 表名2 on 条件 (left/right) join 表名3 on 条件;
<6>.子查询:select语句嵌套,内部的select;
例如:
select employeeName,salary from employee where salary>(select min(salary) from employee);
Tips:a.从内而外一层一层看,将子查询结果当作一张临时表。 b.子查询嵌套的select只能返回一条,多于一条会报错。
<7>.union关键字:连接两条查询语句
例如:
select employeeName,job from employee where job = 'manager' or job = 'salesman';
可用union关键字改写为:
select employeeName,job from employee where job = 'manager' ==union== select employeeName,job from employee where job = 'salesman';
Tips: a.union有着连接两条查询语句的作用,效率更高,克服笛卡尔积现象; b.union使用时必须保证两个结果列数相同。
<8>.limit关键字:取出一部分结果
语法格式:
①limit //startIndex是起始下标,length是长度; startIndex,length; ②limit //numble是取前n个查询结果; numble;
Tips:limit在“order by”之后执行。
<9>.关于查询语句关键字执行顺序汇总:
语法规则:
select 字段名,... from 表名 where 条件 group by 字段名 having 条件 order by 字段名 (asc/desc) limit 过滤参数
执行顺序:
from找表-> where初筛-> group by分组-> having细筛-> select查找-> order by排序-> limit过滤。
(8)表的相关语句:
<1>.MySQL中的数据类型:
①字符串类:
varchar(10) 动态分配存储空间,节省空间;(姓名字段) char(10) 定长字符串,分配速度快;(性别字段)
最长可储存255位。
②整型数类:
int 常规整型类,等同于java中的int; bigint 长整型,等同于java中的long;
最长可储存11位。
③浮点型类:
float 常规浮点型,等同于java中的float; double 长浮点型,等同于java中的double;
④日期类:
date 短日期类型,存储年月日信息; datetime 长日期类型,存储年月日时分秒信息;
<2>.表的创建(DDL语句):
语法格式:
create table 表名(字段名 数据类型(default 'm'),字段名 数据类型,... );
Tips:①表名的命名规范:以t_或者tbl_开始,比如t_students; ②default 'm'作用为指定字段默认值为'm'。
<3>.表的删除:
语法格式:
①drop table 表名; 表不存在时会报错; ②drop table if exists 表名; 不会报错。
<4>.表中数据插入(DML语句):
①常规插入语法格式:
insert into 表名(字段名1,字段名2,...) values(值1,值2,...),(值1,值2,...),...;
Tips: A.insert语句一旦执行,必然多一条记录,未赋值元素为NULL; B.字段名在传入所有值情况下字段名可省略。
②日期的插入:
A.MySQL中的日期格式:
%Y %m %d %h %i %s 年 月 日 时 分 秒 date默认格式: %Y-%m-%d; datetime默认格式: %Y-%m-%d-%h-%i-%s;
B.字符串日期转换为日期类型函数:
str_to_date('字符串日期','日期格式'); //将字符串日期varchar类型转换为date类型;
Tips:当字符串为‘%Y-%m-%d’格式时,自动转换为date类型;
C.日期格式化函数:
date_format(日期类型数据,'日期格式'); //将日期格式转换为所需类型的字符串。
D.获取当前时间函数:
now(); //获得到当前时间的datetime类型数据。
<5>.表中数据修改(DML语句):
语法格式:
update 表名 set 字段名1=值1,字段名2=值2,...where 条件; //必须加where后的条件,否则会修改字段所有行。
<6>.表中数据删除:
①delete删除语法格式:(DML语句)
delete from 表名 where 条件; //切记加where后条件,否则会全部删除。 数据被删除,但存储空间不会被释放; 删除效率较低,但是可回滚
②truncate删除语法格式:(DDL语句)
truncate table 表名; 完全删除,删除效率高,但数据不可回滚。
<7>.表的复制:
①全部复制语法格式:
create table 新表名 as select * from 拷贝表名; //将拷贝表名中的所有数据拷贝到新表中。
②部分复制语法格式:
create table 新表名 as select 字段名1,字段名2,... from 拷贝表名 where 条件; //将拷贝表面的满足条件的某字段数据复制到新表中。
JDBC——Java语言连接数据库
1.所属类库与配置工作
类库:
所属于(java.sql.*)包下,该包下都是JDBC的接口。
准备工作:
①找到mysql-connector-java-bin.jar(mysql的驱动); ②配置环境变量:classpath = .;(jar包的绝对路径)。 注:“.”表示当前路径。
JDBC特点:
①降低程序耦合度,提高文件扩展力; ②面向接口编程。
2.JDBC的编程六步
(1).注册驱动(需要抛出SQLException异常)
方法1:
java.sql.Driver driver = new com.mysql.jdbc.Driver();
DraverManager.registerDriver(driver);
方法2:(常用)
//利用反射原理,Class类中的forName(完整包名)方法调用会使Driver类中的静态代码块执行(类加载)
Class forName("com.mysql.jdbc.Driver");
//此处需要处理Exception异常。
(2).获取数据库连接
方法1:手动赋值url,user和password参数
//url包括“协议+IP地址+port端口号+资源名”
String url = "jdbc:mysql://localhost:3306/(数据库名)";
String user = "(mysql用户名)";
String password = "(mysql登录密码)";
//获取数据库连接操作
Connection conn = DriverManager.getConnection(url,user,password);
方法2:资源绑定器控制属性文件: <1>.书写一个属性配置文件(XXX.properties):
driver = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/(数据库名)
user = (mysql用户名)
password = (mysql登陆密码)
<2>.在java程序中使用资源绑定器绑定属性配置文件:
//资源绑定器
ResourceBundle bundle = ResourceBundle.getBundle("(从src下的目录路径(不带后缀))");
String driver = bundle.getString("driver");
String url = bundle.getString("url");
String user = bundle.getString("user");
String password = bundle.getString("password");
//获取数据库连接操作
Connection conn = DriverManager.getConnection(url,user,password);
(3).获取数据库操作对象
情况1:需进行字符串拼接,但会发生SQL注入
Statement stmt = conn.createStatement();
SQL注入现象:
①在登录界面随意输入账号密码,登录成功; ②原因:输入的用户名与密码中有SQL关键字,其与原SQL语句发生字符串拼接而导致参与了SQL语句的编译,导致SQL语句被扭曲; ③本质是该种方式先进行字符串拼接,再编译SQL语句。 例如:密码输入('djalksd' or 'a'='a),登陆成功。
情况2:有效防止了SQL注入,但无法进行字符串的拼接
//原用户名与密码处用“?”代替
String sql = "(SQL语句)";
preparedStatement ps = conn.preparedStatement(sql);
//给预编译的“?”处传值(JDBC中下标均是从1开始的)
ps.setString(int index,String value);
//同理也可以使用ps.setDatatype(int index,datatype value);
(4).执行SQL语句
!!!注:当(3)步骤使用了情况2时,该步骤无需传入sql语句。以下采用(3)步骤中情况1的情况。!!! 情况1:执行增删改操作
String sql = "(SQL语句)";
//返回的count是被改动的条数
//该sql语句只能传入增删改操作语句
int count = stmt.executeUpdate(sql);
情况2:执行查询操作
String sql = "(SQL语句)";
//返回的rs是结果集,用于后续处理
//该sql语句只能传入查询操作语句
ResultSet rs = stmt.executeQuery(sql);
(5).处理查询结果集
相关方法简介:
(boolean) rs.next();
>//将数据库的光标初始化在表头,该方法使光标向下一位
>//若数据库光标位置存在数据,则返回true。
(String) rs.getString(int index);
>//取当前行的第index个数据
>//同理还有rs.getDatatype(int index);
(datatype) getDatatype(String name);
>//根据查询结果的列名纵向取值。
(6).释放资源(放入try...catch...语块的finally)
finally{
//释放资源
if (rs != null) {
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
3.JDBC的事务(transaction)
//手动开启或关闭事务(获取数据库连接后)
//isOpen为true时,说明开启了自动提交事务
conn.setAutoCommit(boolean isOpen);
//手动事务提交(放在处理结果集后)
conn.commit();
//手动事务回滚(放在catch语块中)
//由于如果程序执行失败会进入catch语块,回滚不至于数据丢失
if(conn!=null){
conn.rollback();
}
4.JDBC工具类的书写
代码:
import java.sql.*;
import java.util.ResourceBundle;
//JDBC的工具类
public class DBUtils {
//添加一个私有的构造方法,防止new对象。
private DBUtils(){}
//类加载时加载属性资源文件
public static ResourceBundle bundle = ResourceBundle.getBundle("Resource/login");
//注册驱动(写入静态代码块中,仅在类加载时执行一次)
static{
try {
Class.forName(bundle.getString("driver"));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//获得数据库连接
public static Connection getConnection() throws SQLException {
String url = bundle.getString("url");
String user = bundle.getString("user");
String password = bundle.getString("password");
Connection conn = DriverManager.getConnection(url,user,password);
return conn;
}
//释放资源
public static void closeAll(Connection conn, Statement stmt, ResultSet rs){
if (rs != null){
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (conn != null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
//释放资源方法重载
public static void closeAll(Connection conn,Statement stmt){
if (stmt != null) {
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}