前言
原本想把后面的章节不上,想想 如果大家是看视频 做了笔记,比我发现成的文档要强的多,强调下 我不是偷懒 不是偷懒
一、group by 的 Having子句
having子句在select语句里与group by子句联结应用时,用于通知group by子句在输入里蕴含哪些组,having对于group by的作用相当于where对于select的作用,即设定条件用的。应用having子句能够让后果集里蕴含或去除整组的数据
二、ALTER命令
1.新增表字段
ALTER TABLE [table_name] ADD [column_name] [dataType];
2.批改表字段
ALTER TABLE [table_name] MODIFY [column_name] varchar(200);ALTER TABLE [table_name] change [old_column_name] [new_column_name] varchar(200);
3.删除表字段
ALTER TABLE [table_name] DROP [column_name]
4.批改表名
ALTER TABLE [table_name] RENAME TO [new_table_name];
三、索引
1.索引原理:
拿汉语字典的目录页(索引)打比方,咱们能够按拼音、笔画、偏旁部首等排序的目录(索引)疾速查找到须要的字。
2.索引的数据结构:
任何一种数据结构都不是凭空产生的,肯定会有它的背景和应用场景,咱们当初总结一下,咱们须要这种数据结构可能做些什么,其实很简略,那就是:每次查找数据时把磁盘IO次数管制在一个很小的数量级,最好是常数数量级。那么咱们就想到如果一个高度可控的多路搜寻树是否能满足需要呢?就这样,b+树应运而生。
3.索引的类别:
3.1.INDEX(一般索引)
ALTER TABLE [table_name] ADD INDEX index_name ( [column] );
3.2.主键索引
ALTER TABLE [table_name] ADD PRIMARY KEY ( [column] );
3.3.UNIQUE(惟一索引)
ALTER TABLE [table_name] ADD UNIQUE ([column]);
3.4.FULLTEXT(全文索引)
ALTER TABLE [table_name] ADD FULLTEXT ([column]);
3.5.多列索引
ALTER TABLE [table_name] ADD INDEX index_name ( [columns...,]);
4.索引生效的几种状况
4.1 索引字段能够为null
应用is null或is not null时,可能会导致索引生效
4.2 like通配符可能会导致索引生效
like查问以%结尾时,会导致索引生效。
select * from [table_name] where [column_name] like '%name' ;
4.3 在索引列上应用内置函数,肯定会导致索引生效
select * from [table_name] where DATE_ADD(create_time, INTERVAL 1 DAY) = 7;
四、事务的特色
原子性( Atomicity ):一个事务(transaction)中的所有操作,要么全副实现,要么全副不实现,不会完结在两头某个环节。事务在执行过程中产生谬误,会被回滚(Rollback)到事务开始前的状态,就像这个事务素来没有执行过一样。
一致性(Consistency):在事务开始之前和事务完结当前,数据库的完整性没有被毁坏。这示意写入的材料必须完全符合所有的预设规定,这蕴含材料的精确度、串联性以及后续数据库能够自发性地实现预约的工作。
隔离性(Isolation):数据库容许多个并发事务同时对其数据进行读写和批改的能力,隔离性能够避免多个事务并发执行时因为穿插执行而导致数据的不统一。事务隔离分为不同级别,包含读未提交(Read uncommitted)、读提交(read committed)、可反复读(repeatable read)和串行化(Serializable)。
持久性(Durability):事务处理完结后,对数据的批改就是永恒的,即使系统故障也不会失落。
1. 事务的操作
五、InnoDB与MyISAM的区别
5.1 InnoDB 反对事务,MyISAM 不反对事务。这是 MySQL 将默认存储引擎从 MyISAM 变成 InnoDB 的重要起因之一
5.2 InnoDB 反对外键,而 MyISAM 不反对。对一个蕴含外键的 InnoDB 表转为 MYISAM 会失败
六、存储函数、存储过程、触发器、视图
6.1 罕用函数:
sum :求和
min :最小数
max :最大数count :统计个数group_concat([column_name]) :分组并合并此字段
substr([column_name],pos,len) :截取字符串函数
......
6.2 视图
定义:
存储的查问语句,当调用的时候,产生后果集,视图充当的是虚构表的角色.
CREATE VIEW myview AS <selectSql>;
6.3 存储函数
定义变量:
应用DECLARE定义局部变量,只能在存储过程和存储函数中应用
在流程语句的剖析中,咱们在存储过程中应用变量的申明与设置,因为这些变量也只能在存储过程中应用,因而也称为局部变量,变量的申明能够应用以下语法:
DECLARE 变量名[,变量名2...] 数据类型(type) [DEFAULT value];
DECLARE num INT DEFAULT 10 ;-- 定义变量num,数据类型为INT型,默认值为10
DECLARE mult_a,mult_b int; //定义多个变量
给变量赋值:
1、应用set
set var =value;
2、应用select
select var := value;
语法格局
CREATE FUNCTION 函数([参数类型 数据类型[,….]]) RETURNS 返回类型 BEGIN SQL语句..... RETURN (返回的数据) END
[](https://blog.csdn.net/jikuicu...)
6.4存储过程
输出参数、输入参数和输入输出参数
输出参数: IN 输出参数:OUT 输入输出参数: INOUT
查问存储过程:
show procedure STATUS where Db='数据库名称'SHOW PROCEDURE STATUS //查问所有的存储过程SHOW PROCEDURE STATUS LIKE 'pattern' //查问符号要求的存储过程如:SHOW PROCEDURE STATUS LIKE 'myuse' 查问的就是存储过程名称 为myuse 的信息
查询数据库字符编码状况
show variables where Variable_name like 'collation%';
删除存储过程:
DROP PROCEDURE IF EXISTS myuse //IF EXISTS最好带上 不然会报错
创立存储过程的根本款式:
存储函数与存储过程有些相似,简略来说就是封装一段sql代码,实现一种特定的性能,并返回后果。其语法如下:
create procedure 存储过程名称( 参数的品种 参数1 数据类型, 参数的品种 参数2数据类型...参数的品种 参数n 数据类型)BEGIN // 解决内容 其中能够用到函数和条件语句等END
语法
CREATE PROCEDURE 存储过程名称()BEGIN //sqlEND
与存储函数的区别
1.与存储过程不同的是,存储函数中不能指定输入参数( OUT)和输入输出参数( INOUT)类型。存储函数只能指定输出类型而且不能带IN。同时存储函数能够通过RETURN命令将解决的后果返回给调用方。
2.存储函数必须在参数列表后的RETURNS并指令返回的数据类型,存储函数必须要有返回值,而存储过程能够没有返回值。
3.调用形式不同,存储过程应用select ,存储函数应用 call
4.存储函数参数不能应用 in 、out 、inout
6.5 触发器
定义:
触发器是与表无关的数据库对象,在满足定义条件时触发,并执行触发器中定义的语句汇合。触发器的这种个性能够帮助利用在数据库端确保数据的完整性。
触发事件(tigger_event):
七、JDBC
6.1 名称解释
Java数据库连贯,(Java Database Connectivity,简称JDBC)是Java语言中用来标准客户端程序如何来拜访数据库的利用程序接口,提供了诸如查问和更新数据库中数据的办法。JDBC也是Sun Microsystems的商标。咱们通常说的JDBC是面向关系型数据库的。
6.2 JDBC 编程步骤
加载驱动程序:
Class.forName(driverClass) --->具体的应用Class.forName("com.mysql.jdbc.Driver") //加载MySql驱动 Class.forName("oracle.jdbc.driver.OracleDriver")//加载Oracle驱动
取得数据库连贯:
DriverManager.getConnection("<URL>", "账号", "明码");---- mysql具体的应用DriverManager.getConnection("jdbc:mysql://<Ip地址>:<port>/<databaseName>", "账号", "明码");
创立Statement\PreparedStatement对象:
conn.createStatement();conn.prepareStatement(sql);//获取预编译语句对象 [举荐]
6.2 jdbc重要的接口及api
PreparedStatement
办法 | 作用 | 返回后果 | 备注 | |
---|---|---|---|---|
setBytes(int parameterIndex, byte x[]); | 给参数列设置值,值类型为byte数组 | void | ||
setInt(int parameterIndex, int x); | 给参数列设置值,值类型为byte数组 | void | ||
setLong(int parameterIndex, long x); | 给参数列设置值,值类型为long类型 | void | ||
setString(int parameterIndex, String x); | void | |||
setBoolean(int parameterIndex, boolean x); | void | |||
setNull(int parameterIndex, int sqlType); | void | |||
setTime(int parameterIndex, java.sql.Time x) | void | |||
setObject(int parameterIndex, Object x) ; | 给参数列设置值,值类型为object类型 | |||
clearParameters() | 革除预处理的参数 | void | ||
addBatch(); | void | |||
addBatch( String sql ); | 将给定的SQL命令增加到此命令列表中。此列表中的命令能够是通过调用办法以批处理形式执行。 | void | ||
executeBatch(); | 执行批处理形式的语句 ,个别是新增 批改 删除 | void | ||
clearBatch() ; | 清空此批处理形式中所有对象 | void | ||
execute(); | 执行任何sql语句,CRUD都行,如果是新增 批改 删除语句能够应用getUpdateCount()查看影响行,如果是查问语句能够调用getMoreResults()失去检索的后果 | boolean | ||
execute(String sql); | 执行给定的SQL语句,该语句可能返回多个后果。在某些(不常见)状况下,单个SQL语句可能返回多个后果集和/或更新计数。 | boolean | ||
getUpdateCount(); | 获取影响的数量 | int | ||
getMoreResults(); | boolean | |||
executeQuery(); | 执行查问操作 | |||
#### ResultSet | ||||
executeUpdate(); | 执行更新操作 | boolean | ||
getResultSet(); | 获取查问后果集 | |||
#### ResultSet |
ResultSet
办法 | 作用 | 备注 | |
---|---|---|---|
next() | 将光标从以后地位向前挪动一行。一个ResultSet光标最后被定位在第一排之前;对该办法的第一次调用使第一行成为以后行;这个第二次调用使第二行成为以后行,依此类推。 | ||
getString(int columnIndex) | 以后行中指定列的值是String类型 | ||
getBoolean(int columnIndex) | 以后行中指定列的值是Bool类型 | ||
getByte(int columnIndex) | 以后行中指定列的值是byte类型 | ||
getBytes(int columnIndex) | 以后行中指定列的值是byte数组类型 | ||
getInt(int columnIndex) | |||
getLong(int columnIndex) | |||
getDouble(int columnIndex) | |||
getTime(int columnIndex) | 以后行中指定列的值是Time类型 | 返回的Time是属于java.sql.Time包外面 | |
getTimestamp(int columnIndex) | 以后行中指定列的值是Timestamp类型 | 返回的Time是属于java.sql.Time包外面 |
6.3 jdbc的封装
目标:
通过实体对象 反射生成插入语句 并执行插入语句
原材料:
0.数据库sql
CREATE TABLE `t_book_info` ( `id` int(20) NOT NULL, `name` varchar(100) DEFAULT NULL, `author` varchar(50) DEFAULT NULL, `push_time` datetime DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8
1.实体对象(TBookInfo)
package com.jdbc.demo;import java.util.Date;/** * <ul> * <li>Title: TBookInfo</li> * <li>Description: TODO </li> * </ul> * * @author 程序员ken * @date 2021-12-22 16:11 */@TableName("t_book_info")public class TBookInfo { @TableField(name = "id",autoIncrement=true) private int id; @TableField(name = "name") private String name; @TableField(name = "author") private String author; @TableField(name = "push_time") private Date pushTime; //get set 办法省略}
2.注解类(TableName 和 TableField 别离作用到类下面 和 字段下面)
TableName 类
package com.jdbc.demo;import java.lang.annotation.*;import static java.lang.annotation.ElementType.FIELD;import static java.lang.annotation.ElementType.TYPE;@Documented@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)public @interface TableName { String value();}
TableField类
package com.jdbc.demo;import java.lang.annotation.*;@Documented@Target({ElementType.FIELD})@Retention(RetentionPolicy.RUNTIME)public @interface TableField { String name(); boolean exist() default true; boolean autoIncrement() default false;}
3.理论代码(须要用到反射机制)
package com.jdbc.demo;import java.lang.annotation.Annotation;import java.lang.reflect.Field;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.SQLException;import java.util.ArrayList;import java.util.Date;import java.util.List;/** * <ul> * <li>Title: JdbcUtil</li> * <li>Description: TODO </li> * </ul> * * @author:程序员ken * @date 2021-12-22 15:55 */public class JdbcUtil { private static String url ="jdbc:mysql://127.0.0.1:3306/mytest?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true"; private static String user ="root"; private static String password ="123456"; //获取连贯的办法 private static Connection getConnect() { Connection con =null; try { con = DriverManager.getConnection(url, user, password); } catch (SQLException e) { e.printStackTrace(); } return con; } // 封装对立的新增 //实体类 =》 泛型 T =》生成须要sql语句 /** * 性能形容: * @param t * @return: void * @author:程序员ken * @date: 2021-12-22 16:08 */ public static <T> void insert(T t) { Class<?> aClass = t.getClass(); Field[] fields = aClass.getDeclaredFields(); String insertSqlTemp = "insert into #{tableName} (#{columns}) values(#{columnValues})"; StringBuffer columnsSbf = new StringBuffer(); StringBuffer columnValuesSbf = new StringBuffer(); TableName tableName = aClass.getAnnotation(TableName.class); if(tableName!=null){ insertSqlTemp = insertSqlTemp.replace(" #{tableName}",tableName.value()); } List<Field> fieldList =new ArrayList<Field>(); TableField tableField =null; for (Field field : fields) { tableField = field.getAnnotation(TableField.class); if(tableField!=null && tableField.exist() && !tableField.autoIncrement()){ columnsSbf.append(","+tableField.name()); columnValuesSbf.append(",?"); fieldList.add(field); } field.setAccessible(true); } if(columnsSbf.length()>0){ insertSqlTemp =insertSqlTemp.replace("#{columns}",columnsSbf.delete(0,1)).replace("#{columnValues}",columnValuesSbf.delete(0,1)); } Connection conn = null; PreparedStatement pst = null; try { conn = getConnect(); pst= conn.prepareStatement(insertSqlTemp); int ind =1; for (Field field : fieldList) { field.setAccessible(true); try { pst.setObject(ind,field.get(t)); } catch (IllegalAccessException e) { e.printStackTrace(); } ind++; } int row = pst.executeUpdate(); System.out.println("影响行数:"+row); } catch (SQLException e) { e.printStackTrace(); }catch (ClassNotFoundException e) { e.printStackTrace(); }finally { try { if(pst!=null){ pst.close(); } if(conn!=null){ conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } }}
其余示例
批量预编译语句
package com.ken.sys.common.util;import com.ken.sys.common.entity.DbSettingInfo;import com.ken.sys.common.ifs.PrepareFunction;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.sql.*;import java.util.List;import java.util.Properties;public class JdbcUtil { private static Connection conn = null; private static String finaUrl= "jdbc:mysql://192.168.0.118:3306/erp-sy?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true"; private static String finaUser = "root"; private static String finaPass = "123456"; //默认是 mysql private static String driver ="com.mysql.jdbc.Driver"; //默认最大提交数 private static final int COMMIT_MAX_COUNT = 20000; static { try { String rootPath = JdbcUtil.class.getClassLoader().getResource("").getPath(); //读取SQL配置文件 配置文件在src下 InputStream in = new FileInputStream( rootPath+"jdbc.properties"); Properties properties = new Properties(); properties.load(in); //获取参数 driver = properties.getProperty("jdbc.driver"); finaUrl = properties.getProperty("jdbc.url"); finaUser = properties.getProperty("jdbc.username"); finaPass = properties.getProperty("jdbc.password"); } catch (IOException e) { e.printStackTrace(); } } //建设连贯 依据属性文件的配置 public static Connection getConnection(){ return getConnection(driver,finaUrl,finaUser,finaPass); } //建设连贯 依据属性文件的配置 private static Connection getConnection(DbSettingInfo dbSettingInfo){ if(dbSettingInfo==null){ throw new Error("dbSettingInfo is not allowed to be null"); } return getConnection(dbSettingInfo.getDriver(),dbSettingInfo.getDbUrl(),dbSettingInfo.getUserName(),dbSettingInfo.getPassword()); } public static Connection getConnection(String driver,String url, String user, String pass){ try { Class.forName(driver); conn= DriverManager.getConnection(url,user,pass); } catch (ClassNotFoundException e) { e.printStackTrace(); }catch (SQLException e) { e.printStackTrace(); } return conn; } public static void closeConnection(Connection conn, PreparedStatement stmt, ResultSet rs){ try { if(rs!=null) { rs.close(); } if(stmt!=null) { stmt.close(); } if(conn!=null) { conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } /** * 性能形容: 批量执行sql * @param dbSettingInfo * @param executeSql * @param list * @return: void * @author:程序员ken * @date: 2021-12-09 10:44 */ public static <T> void executeBatch(DbSettingInfo dbSettingInfo ,String executeSql, List<T> list){ executeBatch(dbSettingInfo,executeSql,list,COMMIT_MAX_COUNT,null); } /** * 性能形容: 批量执行sql * @param dbSettingInfo * @param executeSql * @param list * @param commitMaxCount * @return: void * @author:程序员ken * @date: 2021-12-09 10:44 */ public static <T> void executeBatch(DbSettingInfo dbSettingInfo ,String executeSql, List<T> list, int commitMaxCount){ executeBatch(dbSettingInfo,executeSql,list,commitMaxCount,null); } /** * 性能形容: 批量执行sql * @param dbSettingInfo 数据库信息 * @param executeSql 执行sql * @param list 数据源 * @param commitMaxCount 最大提交数 * @param prepareFunction 个别能够预处理参数 能够做内部的干涉 * @return: void * @author:程序员ken * @date: 2021-12-09 10:44 */ public static <T> void executeBatch(DbSettingInfo dbSettingInfo ,String executeSql, List<T> list, int commitMaxCount, PrepareFunction prepareFunction){ PreparedStatement pstmt =null; Connection conn =null; try { commitMaxCount = commitMaxCount>0 && commitMaxCount<=COMMIT_MAX_COUNT ?commitMaxCount:COMMIT_MAX_COUNT;//默认最大提交2000条 conn = getConnection(dbSettingInfo); conn.setAutoCommit(false); pstmt = conn.prepareStatement(executeSql); int ind =0; boolean hand =true; for (T t : list) { if(prepareFunction!=null){ hand = prepareFunction.hand(t, pstmt);//参数在此设置 } //不执行此条数据 if(!hand){ continue; } pstmt.addBatch(); ind++; if(ind==commitMaxCount){ pstmt.executeBatch();//批量提交 pstmt.clearParameters();//革除参数 ind =0; } } //有余提交最大数 仍有插入数 进行提交 if(ind>0){ pstmt.executeBatch();//批量提交 pstmt.clearParameters();//革除参数 } //提交,设置事务初始值 conn.commit(); conn.setAutoCommit(true); } catch (Exception e) { //提交失败,执行回滚操作 try { if(conn!=null){ conn.rollback(); } } catch (SQLException e1) { e1.printStackTrace(); } e.printStackTrace(); }finally { try { if(pstmt!=null){ pstmt.close(); } if(conn != null){ conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } }}
八、数据库备份和还原
8.1 数据库备份(MySQL 导出数据)
8.1.1 应用 SELECT ... INTO OUTFILE 语句导出数据
语法:
select * from [table_name] INTO OUTFILE "[文件具体位置准确到文件名]";
1.留神文件反斜杠(\) 用双反斜杠 (\)
2.操作是在mysql中操作 ,而不是命令行中操作,所以能够嵌套在mybatis的xml中应用
<update id="selectExport" > SELECT * FROM [table_name] INTO OUTFILE "[具体导出文件全门路]";</update>
[
](https://blog.csdn.net/hanshim...)
遇到的谬误:
select * from t_project_info INTO OUTFILE "E:\\数据库备份\\backup_data.txt"> 1290 - The MySQL server is running with the --secure-file-priv option so it cannot execute this statement> 工夫: 0s
解决形式:
应用show VARIABLES like '%secure%'; 查问secure_file_priv是否设置值,这个值是导出文件的根目录,设置如图,代表导出的文件只能存在C盘上面。如果须要批改 参考这个,对mysql配置文件进行批改,配置文件名个别为my.ini 。
secure-file-priv的值有三种状况:
secure_file_prive=null ––限度mysqld 不容许导入导出secure_file_priv=/path/ – --限度mysqld的导入导出只能产生在默认的/path/目录下secure_file_priv='' – --不对mysqld 的导入 导出做限度
[
](https://blog.csdn.net/weixin_...)
8.1.2 应用[mysqldump ]命令行
如果你须要将数据拷贝至其余的 MySQL 服务器上, 你能够在 mysqldump 命令中指定数据库名及数据表。
语法
1.单个数据库 所有表数据导出
mysqldump -h [ipAddress] -u [user] -p[password] [database] --default-character-set=utf8 --hex-blob >[backUpPath][exportFileName]
示例
mysqldump -h 127.0.0.1 -u root -p123456 qrcode-beiyong --default-character-set=utf8 --hex-blob >E:\数据库备份\qrcode_2021.sql
2.单个数据库 所有表数据导出
mysqldump -u [user] -p[password] [database] --tables table_name1 table_name2 table_name3 >[backUpPath][exportFileName]
示例
mysqldump -u root -p123456 qrcode-beiyong --tables t_project_info t_bid_auth_peopel_info >E:\数据库备份\qrcode_2022.sql
2.所有数据库 所有表数据导出
mysqldump -u [user] -p[password] –all-databases >[backUpPath][exportFileName]
示例
mysqldump -u root -p123456 –all-databases>E:\数据库备份\qrcode_2021.sql
参数阐明
参数名 | 缩写 | 含意 |
---|---|---|
--host | -h | 服务器IP地址 |
--port | -P | 服务器端口号 |
--user | -u | MySQL 用户名 |
--pasword | -p | MySQL 明码 |
--databases | 指定要备份的数据库 | |
--all-databases | 备份mysql服务器上的所有数据库 | |
--compact | 压缩模式,产生更少的输入 | |
--comments | 增加正文信息 | |
--complete-insert | 输入实现的插入语句 | |
--lock-tables | 备份前,锁定所有数据库表 | |
--no-create-db/--no-create-info | 禁止生成创立数据库语句 | |
--force | 当呈现谬误时依然持续备份操作 | |
--default-character-set | 指定默认字符集 | |
--add-locks | 备份数据库表时锁定数据库表 |
留神:
1.--default-character-set=utf8 设置编码集为utf8 可自定义编码集 也能够不必
2.--hex-blob 用于导出零碎中存在二进制数据,如果没有能够二进制数据 能够去掉
3.-h [ipAddress] 代表这连贯近程地址 ,如果这块没有 默认是连贯主机
4.–all-databases 代表 导出所有数据库
5.主机-p[password] -p和password不要用空格,明码能够为空 但后一步命令行可能会验证明码
8.2 数据库还原[导入数据]
8.2.1 LOAD DATA 命令导入
语法:
LOAD DATA LOCAL INFILE '[文件具体位置]' INTO TABLE [table_name];
示例:
LOAD DATA LOCAL INFILE 'C:\\ProgramData\\MySQL\\MySQL Server 5.6\\Uploads\\backup_data.txt' INTO TABLE t_project_info
留神:
1.这个不是在mysql的命令行下执行,是作为mysql语句执行 ,所有能够嵌入到xml【map层】的标签中
2.经常是应用mysqldump 命令导出的数据作为数据源
8.2.2 mysql 命令导入
语法:
mysql -u[user] -p[password] < [backUpPath][exportFileName]
示例:
mysql -uroot -p123456 qrcode-backup< E:\数据库备份\qrcode_2021.sql
留神:
1.这个必须在mysql的命令行下执行
2.经常是应用SELECT ... INTO OUTFILE 语句导出的数据作为数据源
视频链接:
西瓜shiping /b站
欢送关注我的公众号:程序员ken,程序之路,让咱们一起摸索,共同进步。