diff --git a/JDBC/bin/Demo/DEMO_EmpManage_JDBC.rar b/JDBC/bin/Demo/DEMO_EmpManage_JDBC.rar new file mode 100644 index 0000000..91d61df Binary files /dev/null and b/JDBC/bin/Demo/DEMO_EmpManage_JDBC.rar differ diff --git a/JDBC/bin/JDBC_day01/demo/JDBCDemo01.class b/JDBC/bin/JDBC_day01/demo/JDBCDemo01.class new file mode 100644 index 0000000..60e6f54 Binary files /dev/null and b/JDBC/bin/JDBC_day01/demo/JDBCDemo01.class differ diff --git a/JDBC/bin/JDBC_day01/demo/JDBCDemo02.class b/JDBC/bin/JDBC_day01/demo/JDBCDemo02.class new file mode 100644 index 0000000..8c64bc6 Binary files /dev/null and b/JDBC/bin/JDBC_day01/demo/JDBCDemo02.class differ diff --git a/JDBC/bin/JDBC_day01/demo/JDBCDemo03.class b/JDBC/bin/JDBC_day01/demo/JDBCDemo03.class new file mode 100644 index 0000000..5fb45a4 Binary files /dev/null and b/JDBC/bin/JDBC_day01/demo/JDBCDemo03.class differ diff --git a/JDBC/bin/JDBC_day01/demo/JDBCDemo04.class b/JDBC/bin/JDBC_day01/demo/JDBCDemo04.class new file mode 100644 index 0000000..77ebcd7 Binary files /dev/null and b/JDBC/bin/JDBC_day01/demo/JDBCDemo04.class differ diff --git a/JDBC/bin/JDBC_day01/lib/ojdbc5.jar b/JDBC/bin/JDBC_day01/lib/ojdbc5.jar new file mode 100644 index 0000000..4c02ee3 Binary files /dev/null and b/JDBC/bin/JDBC_day01/lib/ojdbc5.jar differ diff --git "a/JDBC/bin/JDBC_day01/note/JDBC\345\216\237\347\220\206.jpg" "b/JDBC/bin/JDBC_day01/note/JDBC\345\216\237\347\220\206.jpg" new file mode 100644 index 0000000..131028f Binary files /dev/null and "b/JDBC/bin/JDBC_day01/note/JDBC\345\216\237\347\220\206.jpg" differ diff --git a/JDBC/bin/JDBC_day01/note/summary.txt b/JDBC/bin/JDBC_day01/note/summary.txt new file mode 100644 index 0000000..12daaeb --- /dev/null +++ b/JDBC/bin/JDBC_day01/note/summary.txt @@ -0,0 +1,49 @@ +JDBCDemo01: + 1.基本流程 + (1)连接数据库/加载驱动类(注册驱动): + 1)Class.forName("oracle.jdbc.driver.OracleDriver");//加载驱动类(注册驱动) + 或DriverManager.registerDriver(new OracleDriver()); + 2)Connection conn = DriverManager.getConnection(url, user, pwd);//创建连接对象 + (2)Statement statement = conn.createStatement();//通过Connection对象创建Statement对象 + (3)增删改/查询,都要传参。 + (4)释放资源 + 2.DML增删改:int rows = statement.executeUpdate(sql);//影响了多少行//执行sql语句(DML),要传参。 + 3.DQL查询: + (1)ResultSet rs = statement.executeQuery(sql);//执行sql语句(DQL)并获取结果集,要传参。 + (2)ResultSet的boolean next(); + (3)getInt(),getString(),getDouble(),getDate(),getObject();//getInt(1),getInt(empno);//获取第一列,或直接写列名。 + 4.规范写法; + +JDBCDemo02: + Java程序实现用户登录,验证用户名和密码. + 演示SQL注入攻击。 + 1.连接数据库 + 2.输入用户名和密码及sql语句拼接 + 3.通过Connection对象创建Statement对象 + 4.执行sql语句(例子是查询) + 5.获取结果集,并用next()进行数据判断用户是否登陆成功。 + 6.释放资源 + +JDBCDemo03: + 使用PrepareStatement,实现数据表的查询操作。 + PreparedStatement:预编译(sql是否合符规范),是Statement接口的子接口,防止SQL攻击(不是主要性能),提高代码的可读性,可维护性,提高效率。 + 1.连接数据库 + 2.输入用户名和密码及sql语句拼接(这里是用?进行拼接)//String sql = "select * from users where username=? and password=?"; + 3.创建PrepareStatement预编译对象,因为PrepareStatement是接口,其实现类为Statement对象 + 1)ps = conn.prepareStatement(sql);//会预编译sql.//调用Connection接口的方法prepareStatement,获取PrepareStatement接口的实现类。 + 2)ps.setString(1, name);//调用PrepareStatement对象setXXX()方法,给问号赋值。1和2是占位参数,表示第几个问号。 + 4.调用方法,执行sql语句,获取结果集 + rs = ps.executeQuery();//因为prepareStatement已经预编译过sql,所以statement.executeQuery()不需要传sql参数了。 + 5.遍历结果集 + 6.释放资源 + +JDBCDemo04: + 使用PrepareStatement,实现数据表的更新操作。 + 1.连接数据库 + 2.输入要修改的用编号和新用户名及sql语句拼接(这里是用?进行拼接) + 3.创建PrepareStatement预编译对象,因为PrepareStatement是接口,其实现类为Statement对象 + 1)ps = conn.prepareStatement(sql);//会预编译sql.//调用Connection接口的方法prepareStatement,获取PrepareStatement接口的实现类。 + 2)ps.setString(1, name);//调用PrepareStatement对象setXXX()方法,给问号赋值。1和2是占位参数,表示第几个问号。 + 4.执行sql语句 + int rows = ps.executeUpdate();//因为prepareStatement已经预编译过sql,所以statement.executeUpdate()不需要传sql参数了。 + 5.释放资源 \ No newline at end of file diff --git a/JDBC/bin/JDBC_day02/demo/JDBCDemo01.class b/JDBC/bin/JDBC_day02/demo/JDBCDemo01.class new file mode 100644 index 0000000..e1475da Binary files /dev/null and b/JDBC/bin/JDBC_day02/demo/JDBCDemo01.class differ diff --git a/JDBC/bin/JDBC_day02/demo/JDBCDemo02.class b/JDBC/bin/JDBC_day02/demo/JDBCDemo02.class new file mode 100644 index 0000000..21b3b99 Binary files /dev/null and b/JDBC/bin/JDBC_day02/demo/JDBCDemo02.class differ diff --git a/JDBC/bin/JDBC_day02/demo/JDBCDemo03.class b/JDBC/bin/JDBC_day02/demo/JDBCDemo03.class new file mode 100644 index 0000000..5c7fa13 Binary files /dev/null and b/JDBC/bin/JDBC_day02/demo/JDBCDemo03.class differ diff --git a/JDBC/bin/JDBC_day02/demo/bean/Users.class b/JDBC/bin/JDBC_day02/demo/bean/Users.class new file mode 100644 index 0000000..4f4be83 Binary files /dev/null and b/JDBC/bin/JDBC_day02/demo/bean/Users.class differ diff --git a/JDBC/bin/JDBC_day02/demo/util/DBUtil.class b/JDBC/bin/JDBC_day02/demo/util/DBUtil.class new file mode 100644 index 0000000..fd9782e Binary files /dev/null and b/JDBC/bin/JDBC_day02/demo/util/DBUtil.class differ diff --git a/JDBC/bin/JDBC_day02/note/summary.txt b/JDBC/bin/JDBC_day02/note/summary.txt new file mode 100644 index 0000000..8d8a551 --- /dev/null +++ b/JDBC/bin/JDBC_day02/note/summary.txt @@ -0,0 +1,62 @@ +锘緿BUtil锛 + 瀹炵幇JDBC鐨勫伐鍏风被 + 瀹氫箟闈欐佹柟娉曪紝鐩存帴杩斿洖鏁版嵁搴撶殑杩炴帴瀵硅薄 + 瀹氫箟闈欐佹柟娉曪紝鍏抽棴鎵鏈夎祫婧 + +JDBCDemo01锛 + 浣跨敤浜咲BUtil宸ュ叿绫 + 浣跨敤PrepareStatement锛屽疄鐜版ā绯婃煡璇細ps.setString(1, "%"+condition+"%"); + +JDBCDemo02锛 + JDBC璇诲彇鏁版嵁琛╱sers锛屾瘡琛屾暟鎹皝瑁呭埌USers绫荤殑瀵硅薄涓 + +JDBCDemo03锛 + 閾惰杞处 + conn.setAutoCommit(false);//灏嗕簨鍔$殑鑷姩鎻愪氦鍙栨秷銆 + conn.commit();//鎵嬪姩鎻愪氦浜嬪姟锛屽彲灏嗕笂闈㈢殑閫昏緫鍏ㄩ儴鎺у埗鍦ㄤ竴涓簨鍔′腑銆 + conn.rollback();//鍥炴粴浜嬪姟銆 + +EmpManage_JDBC锛 + 1.bean:瀹炰綋绫 + 2.dao:瀹炵幇绫(鍖)daoimpl锛屾帴鍙 + 3.test:娴嬭瘯绫 + 4.DBUtil: + 闈欐--杩炴帴鏁版嵁搴撶殑鏂规硶 + public static Connection getConnection (){ + Connection conn = null; + try{ + conn = Class.forName("jdbc.oracle.driver.OracleDriver"); + String url = 锛 + String username = 锛 + String password = 锛 + conn = DriverManager.getConnection(url, username, password); + }catch(Exception e){ + e.printStackTrace(); + } + return conn; + }; + 闈欐--鍏抽棴璧勬簮鐨勬柟娉 + public static void close(Connection conn,Statement ps,ResultSet rs) { + try { + if(rs != null) { + rs.close(); + } + if(ps != null) { + ps.close(); + } + if(conn != null) { + con.close(); + } + }catch(SQLException e) { + e.printStackTrace(); + } + } + +琛ュ厖锛 + 1.sql.date杞瑄til.date鍙互鑷姩杞崲銆 + util.date--->sql.date锛 java.sql.Date date = new java.sql.Date(emp.getHiredate().getTime()); + //sql.Date鐨勬瀯閫犲彲浠ヤ紶1970鐨勬绉掑硷紝util.Date鐨刧etTime()鍙互寰楀埌1970鐨勬绉掑笺 + 2.String--->util.Date + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + emp.setHiredate(sdf.parse(sc.next()));//灏哠tring--->util.date,浼氭姏鍑篜arseException寮傚父銆 + diff --git a/JDBC/bin/note/JDBC_day01/JDBC_day01_summary.txt b/JDBC/bin/note/JDBC_day01/JDBC_day01_summary.txt new file mode 100644 index 0000000..12daaeb --- /dev/null +++ b/JDBC/bin/note/JDBC_day01/JDBC_day01_summary.txt @@ -0,0 +1,49 @@ +JDBCDemo01: + 1.基本流程 + (1)连接数据库/加载驱动类(注册驱动): + 1)Class.forName("oracle.jdbc.driver.OracleDriver");//加载驱动类(注册驱动) + 或DriverManager.registerDriver(new OracleDriver()); + 2)Connection conn = DriverManager.getConnection(url, user, pwd);//创建连接对象 + (2)Statement statement = conn.createStatement();//通过Connection对象创建Statement对象 + (3)增删改/查询,都要传参。 + (4)释放资源 + 2.DML增删改:int rows = statement.executeUpdate(sql);//影响了多少行//执行sql语句(DML),要传参。 + 3.DQL查询: + (1)ResultSet rs = statement.executeQuery(sql);//执行sql语句(DQL)并获取结果集,要传参。 + (2)ResultSet的boolean next(); + (3)getInt(),getString(),getDouble(),getDate(),getObject();//getInt(1),getInt(empno);//获取第一列,或直接写列名。 + 4.规范写法; + +JDBCDemo02: + Java程序实现用户登录,验证用户名和密码. + 演示SQL注入攻击。 + 1.连接数据库 + 2.输入用户名和密码及sql语句拼接 + 3.通过Connection对象创建Statement对象 + 4.执行sql语句(例子是查询) + 5.获取结果集,并用next()进行数据判断用户是否登陆成功。 + 6.释放资源 + +JDBCDemo03: + 使用PrepareStatement,实现数据表的查询操作。 + PreparedStatement:预编译(sql是否合符规范),是Statement接口的子接口,防止SQL攻击(不是主要性能),提高代码的可读性,可维护性,提高效率。 + 1.连接数据库 + 2.输入用户名和密码及sql语句拼接(这里是用?进行拼接)//String sql = "select * from users where username=? and password=?"; + 3.创建PrepareStatement预编译对象,因为PrepareStatement是接口,其实现类为Statement对象 + 1)ps = conn.prepareStatement(sql);//会预编译sql.//调用Connection接口的方法prepareStatement,获取PrepareStatement接口的实现类。 + 2)ps.setString(1, name);//调用PrepareStatement对象setXXX()方法,给问号赋值。1和2是占位参数,表示第几个问号。 + 4.调用方法,执行sql语句,获取结果集 + rs = ps.executeQuery();//因为prepareStatement已经预编译过sql,所以statement.executeQuery()不需要传sql参数了。 + 5.遍历结果集 + 6.释放资源 + +JDBCDemo04: + 使用PrepareStatement,实现数据表的更新操作。 + 1.连接数据库 + 2.输入要修改的用编号和新用户名及sql语句拼接(这里是用?进行拼接) + 3.创建PrepareStatement预编译对象,因为PrepareStatement是接口,其实现类为Statement对象 + 1)ps = conn.prepareStatement(sql);//会预编译sql.//调用Connection接口的方法prepareStatement,获取PrepareStatement接口的实现类。 + 2)ps.setString(1, name);//调用PrepareStatement对象setXXX()方法,给问号赋值。1和2是占位参数,表示第几个问号。 + 4.执行sql语句 + int rows = ps.executeUpdate();//因为prepareStatement已经预编译过sql,所以statement.executeUpdate()不需要传sql参数了。 + 5.释放资源 \ No newline at end of file diff --git "a/JDBC/bin/note/JDBC_day01/JDBC\345\216\237\347\220\206.jpg" "b/JDBC/bin/note/JDBC_day01/JDBC\345\216\237\347\220\206.jpg" new file mode 100644 index 0000000..131028f Binary files /dev/null and "b/JDBC/bin/note/JDBC_day01/JDBC\345\216\237\347\220\206.jpg" differ diff --git a/JDBC/bin/note/JDBC_day02/JDBC_day02_summary.txt b/JDBC/bin/note/JDBC_day02/JDBC_day02_summary.txt new file mode 100644 index 0000000..9a00174 --- /dev/null +++ b/JDBC/bin/note/JDBC_day02/JDBC_day02_summary.txt @@ -0,0 +1,17 @@ +锘緿BUtil锛 + 瀹炵幇JDBC鐨勫伐鍏风被 + 瀹氫箟闈欐佹柟娉曪紝鐩存帴杩斿洖鏁版嵁搴撶殑杩炴帴瀵硅薄 + 瀹氫箟闈欐佹柟娉曪紝鍏抽棴鎵鏈夎祫婧 + +JDBCDemo01锛 + 浣跨敤浜咲BUtil宸ュ叿绫 + 浣跨敤PrepareStatement锛屽疄鐜版ā绯婃煡璇細ps.setString(1, "%"+condition+"%"); + +JDBCDemo02锛 + JDBC璇诲彇鏁版嵁琛╱sers锛屾瘡琛屾暟鎹皝瑁呭埌USers绫荤殑瀵硅薄涓 + +JDBCDemo03锛 + 閾惰杞处 + conn.setAutoCommit(false);//灏嗕簨鍔$殑鑷姩鎻愪氦鍙栨秷銆 + conn.commit();//鎵嬪姩鎻愪氦浜嬪姟锛屽彲灏嗕笂闈㈢殑閫昏緫鍏ㄩ儴鎺у埗鍦ㄤ竴涓簨鍔′腑銆 + conn.rollback();//鍥炴粴浜嬪姟銆 diff --git a/JDBC/bin/note/project/one/project_EmpManage_summary b/JDBC/bin/note/project/one/project_EmpManage_summary new file mode 100644 index 0000000..8a69bae --- /dev/null +++ b/JDBC/bin/note/project/one/project_EmpManage_summary @@ -0,0 +1,43 @@ +EmpManage_JDBC: + 1.bean:实体类 + 2.dao:实现类(包)daoimpl,接口 + 3.test:测试类 + 4.DBUtil: + 静态--连接数据库的方法 + public static Connection getConnection (){ + Connection conn = null; + try{ + conn = Class.forName("jdbc.oracle.driver.OracleDriver"); + String url = ? + String username = ? + String password = ? + conn = DriverManager.getConnection(url, username, password); + }catch(Exception e){ + e.printStackTrace(); + } + return conn; + }; + 静态--关闭资源的方法 + public static void close(Connection conn,Statement ps,ResultSet rs) { + try { + if(rs != null) { + rs.close(); + } + if(ps != null) { + ps.close(); + } + if(conn != null) { + con.close(); + } + }catch(SQLException e) { + e.printStackTrace(); + } + } + +补充: + 1.sql.date转util.date可以自动转换。 + util.date--->sql.date: java.sql.Date date = new java.sql.Date(emp.getHiredate().getTime()); + //sql.Date的构造可以传1970的毫秒值,util.Date的getTime()可以得到1970的毫秒值。 + 2.String--->util.Date + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + emp.setHiredate(sdf.parse(sc.next()));//将String--->util.date,会抛出ParseException异常。 diff --git "a/JDBC/bin/note/project/two/JAVA\345\237\272\347\241\200\345\256\236\350\256\255\347\273\203\344\271\240.docx" "b/JDBC/bin/note/project/two/JAVA\345\237\272\347\241\200\345\256\236\350\256\255\347\273\203\344\271\240.docx" new file mode 100644 index 0000000..1b1ea81 Binary files /dev/null and "b/JDBC/bin/note/project/two/JAVA\345\237\272\347\241\200\345\256\236\350\256\255\347\273\203\344\271\240.docx" differ diff --git a/JDBC/bin/note/project/two/carRent_JDBC.sql b/JDBC/bin/note/project/two/carRent_JDBC.sql new file mode 100644 index 0000000..f96570d --- /dev/null +++ b/JDBC/bin/note/project/two/carRent_JDBC.sql @@ -0,0 +1,52 @@ +--建表 +create table car( + brand varchar2(10) not null, + vehicleId varchar2(20) not null unique, + perRent number(4) not null, + type varchar2(20) not null +); +create table bus( + brand varchar2(10) not null, + vehicleId varchar2(20) not null unique, + perRent number(4) not null, + seat number(2) not null +); +create table truck( + brand varchar2(10) not null, + vehicleId varchar2(20) not null unique, + perRent number(4) not null, + tonnage number(2) not null +); +create table rented( + brand varchar2(10) not null, + vehicleId varchar2(20) not null unique, + perRent number(4) not null, + type varchar2(20), + seat number(2), + tonnage number(2) +); +--插入数据 +insert into car values('宝马','京NY28588',800,'X6'); +insert into car values('宝马','京CNY3284',600,'550i'); +insert into car values('别克','京NT37465',300,'林荫大道'); +insert into car values('别克','京NT96968',600,'GL8'); +insert into bus values('金杯','京6566754',800,16); +insert into bus values('金龙','京8696997',800,16); +insert into bus values('金杯','京9696996',1500,34); +insert into bus values('金龙','京8696998',1500,34); +insert into truck values('一汽解放','京MH98725',50,5); +insert into truck values('重庆红岩','京L593216',50,5); +insert into truck values('一汽解放','京NU98631',50,10); +insert into truck values('重庆红岩','京CY56312',50,10); +--查看表 +select * from car; +select * from bus; +select * from truck; +select * from rented; +--删除表 +drop table car; +drop table bus; +drop table truck; +drop table rented; + + diff --git "a/JDBC/bin/note/sql/Oracle\345\216\237\345\247\213\347\254\224\350\256\260.txt" "b/JDBC/bin/note/sql/Oracle\345\216\237\345\247\213\347\254\224\350\256\260.txt" new file mode 100644 index 0000000..d971d98 --- /dev/null +++ "b/JDBC/bin/note/sql/Oracle\345\216\237\345\247\213\347\254\224\350\256\260.txt" @@ -0,0 +1,810 @@ +软件的构成? +1、前端 HTML、CSS、JS、JQuery +2、后台 java +3、数据库 Oracle Mysql(甲骨文) + +1.安装Oracle + + 常用用户: + sys:超级用户 具有最高权限 具有sysdba角色 (数据库管理员) + 有创建数据库的权限 + system:管理操作员 权限仅次于超级管理员 + + scott:普通用户 一般用于练习 scott -- tiger + 解锁用户:alter user scott account unlock + 设置密码:alter user scott identified by tiger + +2.登录方式 + 1)sqlplus 回车 + 输入用户名 + 输入密码 + + 2)sqlplus/nolog + conn scott/tiger + +3. DB:DataBase 按照数据结构来管理数据的仓库 + 关系型数据库 + 以二维表形式存储数据(表的列:字段名 表的行:数据) + + + DBMS:数据库管理系统 + mysql、oracle、SqlServer +4.常用命令 + sqlplus 打开数据库 + conn 用户名/密码 连接数据库 + show user; 显示当前用户 + exit; 断开连接 + quit; 断开连接 +5.SQL:结构化查询语言 + SQL的分类:***** + DDL 数据定义语言 用于操作数据对象(表 视图 序列 索引) + DML 数据操作语言 用于增删改表中的数据(通常伴随事务) + TCL 事务控制语言 用于数据的提交和撤销 + DQL 数据查询语言 用于查询数据记录 + DCL 数据控制语言 用于执行权限分配 + + DDL:数据定义语言 + ---用于操作数据库对象(表 视图 序列 索引) + CREATE:用来创建表或其他对象 + ALTER:修改表或其他对象的结构 + DROP:删除表或其他对象的结构 + TRUNCATE:清空表(删除表中数据,保留表结构) + DML:数据操作语言 + ---用于增删改表中的数据(通常伴随事务) + INSERT INTO:将数据插入到表中 + DELETE:删除表中数据 ---- WHERE + UPDATE 表名 SET:更新表中数据 --- WHERE + + TCL:事务控制语言 + COMMIT:提交--保存 + ROLLBACK:回滚---后退 + + DQL:数据查询语言 + SELECT 查询***** + + DCL:数据控制语言 + 用来执行权限分配 GRANT REVOKE +6.DDL 数据定义语言 + 1、创建表 + 查看用户定义的表: + SELECT table_name FROM user_tables; + CREATE TABLE 表名 ( + 列名(字段名) 数据类型 [默认值 约束], + 列名(字段名) 数据类型 [默认值 约束], + 列名(字段名) 数据类型 [默认值 约束], + 列名(字段名) 数据类型 [默认值 约束] + ); + CREATE TABLE users( + id number(10) primary key, + name varchar2(20) not null unique, + salary number(10,2), + create_time date default sysdate + ); + id(主键) 特点:该列在整张表中每一行所保存的值都不相同,且必须有值(非空且唯一)PRIMARY KEY + 命名规则: + 表名和列名: + 1)必须以字母开头 + 2)必须在1-30个字符之间 + 3)必须只能包含A-Z,a-z,0-9,_,$,和# + 4)必须不能和用户定义的其他对象重名 + 5)必须不能是Oracle的保留字 + 数据类型: + 1)NUMBER:数值类型 + NUMBER(X):x代表位数 + NUMBER(3) 最多能存放3位数 + NUMBER(X,Y):x表示共几位 y表示其中有几位是小数 + NUMBER(6,2) 8888.88 + 2)CHAR:定长字符串 + CHAR(X):X表示共占多少字节 最多放2000字节 + 3)VARCHAR2:变长字符串 + VARCHAR2(X):X表示共占多少字节(根据其中保存的数据长度,占用的空间是变化的) 最多4000字节 + 4)DATE 时间日期 + SELECT SYSDATE FROM DUAL + 伪表:dual确实是一张表,是一张只有一个字段,一行记录的表,习惯上我们称之为伪表,因为它不存储 + 具体的数据 + 2、删除表: + DROP TABLE users; + 3、ALTER:修改表 + 修改表名: + RENAME 原表名 TO 新表名 + 修改表结构: + 向表中添加字段: + ALTER TABLE 表名 ADD(字段名 数据类型[默认值 约束]) + 列只能添加在最后,不能插入到现有的列中 + 删除表中已有字段: + ALTER TABLE 表名 DROP(字段名) + 修改表中已有字段的格式: + ALTER TABLE 表名 MODIFY(字段名 数据类型[默认值 约束]) +7、DML 数据操作语言 + 1、向表中添加数据 + 全字段插入数据: + INSERT INTO 表名 VALUES(1,'张三',8000,sysdate,'程序员'); + 注意:values中的数据顺序要和定义字段时一致 + 部分字段插入数据 + INSERT INTO 表名(想要插入数据的字段) VALUES(与字段顺序相对应的数据) + 2、修改表中已有数据 + 在修改表中数据时,通常添加where子句来限定要修改的记录,这样就只能修改满足where条件的记录, + 否则是全表修改 + UPDATE 表名 SET 字段名=数据,字段名=数据 WHERE 字段名=数据 + 3、删除表中数据 + 通常与where子句连用,否则的话是删除所有数据 + DELETE FROM 表名 WHERE 字段名=数据 + 在DDL语句中的TRUNCATE语句,同样有删除表数据的作用 + 和delete的区别: + --delete可以有条件删除,truncate将表数据全部删除 + --delete是DML,可以回退,truncate是DDL语句,立即生效,无法回退 + --如果是删除全部表记录,且数据量较大,delete语句效率比truncate语句低 + 删除全部记录: + delete from users; + 或者 + truncate table users; +8.TCL 事务控制语言 + commit 提交 + 显示:语句 按钮 + 隐式:正常关闭数据库工具 + rollback 回滚---后退 + 事务的四个特性:***** + 1.原子性:事务包含的所有操作要么全部成功,要么全部失败回滚;成功必须要完全应用到数据库,失败则不能对数据库 + 产生影响; + 2.一致性:事务执行前和执行后必须处于一致性状态, + 3.隔离性:当多个用户并发访问数据库时,数据库为每一个用户开启的事务,不被其他事务的操作所干扰,多个并 + 发事务之间要相互隔离; + 4.持久性:一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的 +9.DQL 数据查询语言 + 基本查询语句由SELECT子句和FROM子句组成 + SELECT:指定要显示的字段名称 + FROM:指定数据来源 + 1)查询所有 + SELECT * FROM 表名; + 2)查询部分数据信息 + SELECT 字段名称1,字段名称2 FROM 表名 WHERE 限定条件; + 注意:SELECT 可以显示字段、表达式、函数 + <>是不等于 + 若函数名称较长,不利于查询结果的列名显示,则可以给查询结果的列使用列别名 + 别名不能以数字开头,若以数字开头别名需要用""括上,同样不能以符号开头 + +10、常用函数 + 1)字符串函数 + CONCAT(c1,c2)连接字符串,将c1,c2两个字段拼接显示 + ||连接字符串符号(多个字符串连接,用||更直观) + SELECT ename || ':'|| sal as "姓名:工资" from EMP + + LENGTH(字段名)显示字符串长度 + SELECT length(ename) from emp + + UPPER(字段名)转大写 + LOWER(字段名)转小写 + INITCAP(字段名)首字母大写 + + TRIM() 去除字符串前后指定内容 + select trim('E' from 'EEEEEHELLO WORLDE') from dual + + 去除员工表中名字的首字母A + select ename,trim('A' FROM ename) from emp + + LTRIM('字符串','')去除字符串左侧指定内容 + RTRIM('字符串','')去除字符串右侧指定内容 + + LPAD(ch1,m,ch2) + RPAD(ch1,m,ch2) + 补位函数 + ch1要查询显示的内容 m指定位数 + ch2数据位数不足时由什么进行补位 + 在emp表中使用左补位,将sql用0补齐6位 + select ename,rpad(sal,6,'$') from emp + SUBSTR(ch,m,n):截取字符串--从1开始 + 截取ch这个字符串,从m开始截取,共截取n个 + 若m为负数,则是从后向前进行下标查询从而进行截取 + INSTR(ch1,ch2,m,n):查找ch1中ch2出现的位置,m代表从哪个位置开始检索,n代表第几次出现 + 不指定m和n,默认值都是1 + 2)数字函数 + ROUND(n,m):用于四舍五入 + 参数中的n可以是任何数字,指要被处理的数字 + m必须是整数,m取正数则四舍五入到小数点后第m位 + m取0则四舍五入到整数位 + m取负数,则四舍五入到小数点前m位 + m缺省,默认值是0 + TRUNC(n,m):截取数字,没有四舍五入 + select trunc(45.678,2),trunc(45.678,0),trunc(45.678,-1) from dual + MOD(m,n):返回m除以n后的余数,n为0则直接返回M + 薪水值按1000取余数 + select ename,sal,mod(sal,1000) from emp + CEIL(n):向上取整 大于该数的最小整数 + FLOOR(n):向下取整 小于该数的最大整数 + 3)日期函数 + sysdate:返回当前的系统时间,精确到秒 select sysdate from dual + systimestamp:返回当前系统日期和时间,精确到毫秒(时间戳) + 1)TO_DATE():相当于是SimpleDateFormat的parse()方法 + 作用:将给定的字符串按照给定的日期格式转换为Date + select to_date('2018-12-01 11:30','YYYY-MM-DD HH24:MI:SS') from dual + 2)TO_CHAR():用于将DATE按照给定的日期格式转换为字符串 + select ename,to_char(hiredate,'YYYY"年"MM"月"DD"日"') from emp + 日期常用函数: + 1)LAST_DAY(date):返回指定日期所在月的最后一天 + select last_day(sysdate) from dual + 2)ADD_MONTHS(date,i):返回日期date加上i个月后的日期值,若果i是负数,则获得的是减去i个月后的 + 日期值 + 查询员工入职20周年纪念日 + select ename,add_months(hiredate,20*12) "20周年" from emp + 3)MONTHS_BETWEEN(date1,date2):计算两个日期之间相差多少个月 + 实际运算的是date1-date2,如果date2时间比date1时间晚,会得到负值,除非两个日期间隔是整数月, + 否则会得到带小数位的结果 + 计算员工入职多少个月 + select ename,trunc(months_between(sysdate,hiredate)) from emp + date日期类型在数据库中可以进行减法操作,结果是相差的天数 + select ename,sysdate-hiredate from emp + 4)LEAST(date1,date2):显示两个时间中的最小值 + GREATEST(date1,date2):显示两个时间中的最大值 + 参数类型必须一致 + select LEAST(sysdate,to_date('2018-12-1','YYYY-MM-DD')) from dual + 5)EXTRACT(date from datetime):从参数datetime中提取参数date指定的数据,比如提取年、月、日 + select extract(day from sysdate) from dual + 查询1980年入职的员工有哪些 + select ename from emp where extract(year from hiredate) = 1980 + 4)空值函数 + null的含义: + 有时表中的某些字段值,数据未知或暂时不存在,取值null + 任何数据类型均可取值null + null条件查询: + null不等于任何值 + 判断一个字段的值是否为null,要使用is null或is not null + select * from emp where comm is null + 非空约束: + 非空(not null)约束用于确保字段值不为空 + 1)NVL(arg1,arg2):将null转变为非null值 + 如果arg1为null,返回arg2,否则返回arg1;arg1和arg2可以是任何数据类型,但两个参数的数据类型必 + 须是一致的 + 计算员工月收入 + select ename,sal,comm,sal+nvl(comm,0) from emp + 2)NVL2(arg,res1,res2):如果arg为null,则返回res2;arg不为null,则返回res1 + select ename,sal,comm,nvl2(comm,sal+comm,sal) from emp +11、基本查询语句: + 1)from子句: + select * from 表名 + select--用于指定要查询的列 + from--指定要从哪个表中查询 + 2)where子句: + 在select语句中,可以在where子句中使用比较操作符限制查询结果 + 查询部门10下的员工信息 + select * from emp where deptno=10 + 查询员工表中职位是'SALESMAN'的员工信息 + select * from emp where job='SALESMAN' --oracle中字符串区分大小写 +12、查询条件 + 1)使用>,<,>=,<=,!=,<>,= + 查询职员表中薪水低于2000的职员信息 + select ename,sal from emp where sal<2000 + 查询职员表中不属于部门10的员工信息 + select ename,sal,job from emp where deptno <> 10 + 查询职员表中在1981年1月1号以后入职的职员信息 + 2)使用AND,OR关键字 + AND 并且 + OR 或者 + 查询薪水大于1000并且职位是‘CLERK’的职员信息 + select ename,sal,job from emp where sal>1000 and job='CLERK' + 查询薪水大于1000或者职位是‘CLERK’的职员信息 + select ename,sal,job from emp where sal>1000 or job='CLERK' + 注意:AND优先级高于OR,可以使用()来提升优先级顺序 + select ename,sal,deptno from emp where deptno=20 or deptno=30 and sal>800 + 3)模糊查询***** + LIKE可以模糊匹配字符串 + select ename,job from emp where ename like 'A%' + _:任意一个字符 + %:任意多个字符 + 4)使用IN和NOT IN + IN(list):取出符合列表范围中的数据 + NOT IN(list):取出不符合此列表中的数据记录 + 查询职位是MANAGER或者CLERK的员工信息 + select * from emp where job in('MANAGER','CLERK') + 查询不是部门10或20的员工 + 5)BETWEEN...AND... + 用来查询符合某个值域范围条件的数据(闭区间) + 等价于>= AND <=的效果 + 查询薪水在1500-3000之间的职员信息 + select * from emp where sal between 1500 and 3000 + 6)使用ANY和ALL条件 + ALL和ANY不能单独使用,需要配合单行比较操作符>,>=,<,<=一起使用 + >ANY:大于最小 + ALL:大于最大 + ANY(select sal from emp where job='MANAGER') + 7)distinct过滤重复数据 + 查询员工的部门编号 + select distinct deptno from emp + 查询每个部门的职位 + select distinct deptno,job from emp +13、运算符优先级 + 1)() + 2)算术运算符:* / + - + 3)连接符:|| + 4)比较运算符:= > >= < <= <> is null,like,between...and...,in + 5)逻辑运算符:not and or + BETWEEN...AND与AND的区别? + 1、BETWEEN...AND:只能用来比较一个字段值 + 2、AND:可以用来比较不同的字段 +14、ORDER BY 排序 + 对结果集的排序,必须出现在select的最后一个子句 + 可以对结果集按照指定字段进行升序ASC或降序DESC + select ename,sal from emp order by sal asc + 注意:排序的字段中若包含NULL,则NULL被看做最大值 + select * from emp where deptno=10 order by mgr desc + 多个列排序: + 当以多列最为排序标准时,首先按照第一列进行排序,如果第一列数据相同,再以第二列排序,以此类推 + 多列排序不管正序还是倒序,每个列需要单独设置排序方式 + 对员工表中的职员排序,先按照部门编号正序排列,再按照薪水降序排列 + select ename,deptno,sal from emp order by deptno asc,sal desc +15、聚合函数(多行函数、分组函数) + 1)MAX和MIN:用来取得列或表达式的最大、最小值 + 可以用来统计任何数据类型,包括数字、字符和日期 + 获取机构下的最高薪水和最低薪水,参数是数字 + select max(sal),min(sal) from emp + 最早和最晚的入职时间,参数是日期 + select max(hiredate),min(hiredate) from emp + 2)AVG和SUM:用来统计列或表达式的平均值、和 + 只能操作数字类型,忽略NULL值 + 获取机构下全部职员的平均薪水和薪水总和 + select AVG(sal),SUM(sal) from emp + 3)COUNT:用来计算表中的记录条数,忽略NULL值 + 获取职员表中一共有多少名职员记录 + select count(*) from emp + 获得职员表中有多少人是有奖金的 + select count(comm) from emp + COUNT和SUM的区别? + COUNT是统计记录数,SUM是统计记录中值的总和,注意区分两者 + 4)聚合函数对空值的处理 + 聚合函数忽略NULL值 + select avg(comm) from emp + 如果不希望忽略null值,使用NVL函数 + select avg(nvl(comm,0)) from emp +16、GROUP BY 分组 + 将结果集按照指定字段进行分组 + 分组规则:该字段下的值一样的记录被看做一组 + 当希望得到每个部门的平均薪水,而不是整个机构的平均薪水 + select MAX(sal),MIN(sal),AVG(sal),SUM(sal) from emp group by deptno + select里面如果出现了聚合函数,同时又想出现某一字段时,那么该字段必须出现在group by子句中 + where后面不能使用聚合函数 + select MAX(sal),deptno from emp where MAX(sal)>4000 group by deptno(不能执行) + HAVING子句 + 用来对分组后的结果进一步限制,比如按部门分组后,得到每个部门的最高工资,可以继续限制输出结果 + 必须跟在group by后面,不能单独存在 + WHERE是非分组函数的过滤判断 + HAVING是分组(聚合)函数的过滤判断 + 查询部门中最大工资超过4000的部门以及最大工资 + select MAX(sal),deptno from emp group by deptno having MAX(sal)>4000 + 查看部门编号,以及该部门的平均工资,要求是该部门的平均工资要超过2000,职位是PRESIDENT的不参与统计 + select deptno,AVG(sal) from emp where job <> 'PRESIDENT' group by deptno having AVG(sal)>2000 +17、SELECT语句执行过程***** + 1、通过from子句中找到需要查询的表 + 2、通过where子句进行非分组函数筛选判断 + 3、通过group by子句完成分组操作 + 4、通过having子句完成组函数筛选判断 + 5、通过select子句选择要显示的列或表达式及组函数 + 6、通过order by子句进行排序操作 +18、函数总结***** + 单行函数和多行函数的分类并举例说明 + 单行函数: + 字符函数:substr() trim() length()... + 数值函数:round() trunc() mod()... + 日期函数:last_day() add_months()... + 转换函数: + 显示转换 to_char() to_date() + 隐式转换 其他类型与字符串连接通常会被转为字符串 + 通用函数:NVL() NVL2() + 注意:通常用于操作单行数据 可以任意嵌套多层,多层时由内向外依次执行 + 多行函数:MAX()最大值 MIN()最小值 SUM()求和 AVG()平均值 COUNT()统计 +19、关联查询 + 关联的概念: + 实际应用中所需要的数据,经常会需要查询两个或两个以上的表,这种查询叫做连接查询,连接查询通常建立存在 + 相互关 + 系的父子表之间 + 外键:保存另一张表主键的列称为外键 + 含有外键的表,在关联关系中属于多的一方 + 表与表之间的关系:一对多(通过外键建立关系),多对多(通过第三张表建立关系),一对一 + N张表的关联查询,最少需要N-1个连接条件,若不指定连接条件,会出现笛卡尔积(无意义的结果集) + 笛卡尔积: + 笛卡尔积指做关联操作的每个表的每一行和其他表的每一行做组合,假设两个表的记录条数分别是X和Y,笛卡尔积将 + 返回X*Y条记录 + select count(*) from emp--14条记录 + select count(*) from dept--4条记录 + select * from emp,dept--56条记录 + 等值连接 用法:外键=主键 + 查看员工名字、工资、部门名称 + select ename,sal,dname from emp e,dept d where e.deptno=d.deptno + select ename,sal,dname + from emp e,dept d + where e.deptno=d.deptno and d.loc='CHICAGO' + KING在哪里工作以及他的部门编号是多少 + select e.ename,e.deptno,d.loc + from emp e,dept d + where e.deptno=d.deptno and e.ename='KING' + 1.可以给表起别名,通过别名指定字段属于哪个表;若两个表字段名称相同,则必须指明数据来源 + 2.只有满足连接条件的结果,才会被查询出来 + 3.若有过滤条件,需同时满足连接条件和过滤条件的数据才会被查询出来 + 内连接: + 返回所有满足连接条件的记录,功能上和等值连接没有区别,只是写法不同 + 语法:表1 INNER JOIN 表2 ON 连接条件(INNER可以省略) + select ename,sal,dname from emp e INNER JOIN dept d ON e.deptno=d.deptno + 外连接 + 内连接返回满足连接条件的数据记录,有些情况下需要返回那些不满足连接条件的记录,需要使用外连接 + 将满足和不满足连接条件的结果全部查询出来 + 快速从已有表中复制数据 + create table empc as select * from emp + 向empc表中插入一条数据 部门号为50 + insert INTO empc(empno,ename,deptno) values(1000,'JACK',50) + 左外连接:(左表的全部,右表的部分) + 根据左表的记录,在被连接的右表中找出符合条件的记录与之匹配,如果找不到与左表匹配的,用null表示 + 语法:表1 LEFT OUTER JOIN 表2 ON 连接条件(OUTER可以省略) + 查询员工的编号,姓名,以及部门名称,包括不属于任何部门的员工 + select empno,ename,dname + from empc e + left join dept d + on e.deptno=d.deptno + 右外连接:(右表的全部,左表的部分) + 根据右表的记录,在被连接的左表中找出符合条件的记录与之匹配,如果找不到匹配的,用null补充 + 语法:表1 RIGHT OUTER JOIN 表2 ON 连接条件(OUTER可以省略) + 查询员工的编号,姓名,以及部门名称,包括没有员工的部门 + select empno,ename,dname + from empc e + right join dept d + on e.deptno=d.deptno + 全外连接 + 返回符合条件的所有表的记录,没有与之匹配的,用null表示(结果是左连接和右连接的并集) + 语法:表1 FULL OUTER JOIN 表2 ON 连接条件(OUTER可以省略) + 自连接 + 连接的两个表都是同一个表,表中的一个字段可以对应当前表的其它字段 + 查询每个员工的上级领导是谁 + select e.ename emp,m.ename mgr + from emp e,emp m + where e.mgr=m.empno + 查询SMITH的上司在哪个城市工作 + Oracle数据库自带语法:***** + 1)笛卡尔积 + 2)内连接:1.等值连接 + 2.非等值连接 + 输出员工编号、姓名、工资、工资等级 + select e.empno,e.ename,e.sal,s.grade + from emp e,salgrade s + where e.sal between s.losal and s.hisal + 3)外连接:1.左外连接: + 查询员工的编号,姓名,以及部门名称,包括不属于任何部门的员工 + select empno,ename,dname + from emp e,dept d + where e.deptno=d.deptno(+) + 2.右外连接: + 查询员工的编号,姓名,以及部门名称,包括没有员工的部门 + select empno,ename,dname + from empc e,dept d + where e.deptno(+)=d.deptno + 4)自连接 + 通用标准的SQL99语法 + 1.交叉连接 + 交叉连接和笛卡尔积的连接模式相同,都是表1中的每一行都与表2中的所有行建立一次连接 + select * from emp cross join dept + 2.自然连接 + 自然连接第一种情况:能够匹配到等值条件,那么就是等值连接的结果 + select * from emp natural join dept; --根据deptno进行等值连接 + 自然连接第二种情况:不能够匹配到等值的条件,那么查询结果就是交叉连接 + select * from emp natural join salgrade; --没有关系交叉连接 + 3.左外连接 + 4.右外连接 + 5.全外连接 + +20、子查询 + 为了给查询提供数据而首先执行的查询语句叫做子查询 + 子查询是嵌入在其它SQL语句中的SELECT语句,大部分时候出现在WHERE子句中,子查询嵌入的语句称作主查询或父查询 + 子查询需要注意: + 1.子查询需要写在括号中 + 2.子查询需要写在运算符的右端 + 3.子查询可以写在where,having,from子句中; + 4.子查询中通常不写order by子句 + 1)子查询在WHERE子句中 + 根据返回结果的不同,子查询分为单行子查询、多行子查询及多列子查询 + 1.单行子查询 + 返回一行一列数据,单行子查询要求使用单行操作符 > >= < <= <> = + select ename,sal from emp + where sal>(select MAX(sal) + from emp where deptno=20) + 查询与SCOTT同部门的员工信息 + select ename,job + from emp + where deptno=(select deptno from emp where ename='SCOTT') + 查找薪水比整个机构平均薪水高的员工 + select deptno,ename,sal + from emp + where sal>(select avg(sal) from emp) + 2.多行子查询 + 返回多行一列数据,使用多行操作符 in all any + select * from emp where deptno + in(select deptno from emp where job='SALESMAN') + and job <> 'SALESMAN' + >ANY:比子查询返回结果中的某个值大。即大于最小值 + 查询比10号部门某个员工工资高的员工信息 + select empno,ename,sal + from emp + where sal > any(select sal from emp where deptno=10) + =ANY:与子查询返回结果中的某个值相等 + 查询与10号部门某个员工工资相等的员工信息 + select empno,ename,sal + from emp + where sal = any(select sal from emp where deptno=10) + ALL:比子查询返回结果中的所有值都大 + 查询比30号部门所有员工工资高的员工信息 + select empno,ename,sal + from emp + where sal > ALL(select sal from emp where deptno=30) + (select min(sal) from emp where deptno=30) + 3)子查询在select部分 + 外连接的另一种写法,不推荐 + 查询每一个员工的同时,根据员工的部门编号查询部门的名称,若查询不到部门,该员工的部门信息就是null + select e.ename,e.sal, + (select d.dname from dept d where d.deptno=e.deptno) dname + from empc e +20、分页查询 + 找到员工表中工资最高的前三名(降序排序) + select * from emp order by sal desc + select rownum,e.* from emp e order by sal desc + --将上面的结果当作一张表处理,再查询 + select rownum,t1.* from (select e.* from emp e order by sal desc) t1 + --只要显示前三条记录 + select rownum,t1.* from (select e.* from emp e order by sal desc) t1 where rownum<4 + ROWNUM:伪列,系统自动生成的一列,用来表示行号 + rownum是ORACLE中特有的用来表示行号,默认值或起始值是1,在查询出结果之后,再加1 + 查询rownum大于2的所有记录 + select rownum,e.* from emp e where rownum>2--没有任何记录 + 查询rownum大于等于1的所有记录 + select rownum,e.* from emp e where rownum>=1 + 查询rownum小于6的所有记录 + select rownum,e.* from emp e where rownum<6 + 查询第6~第10条记录 + 第一种: + select * from (select rownum rn,e.* from emp e) t + where t.rn between 6 and 10 + 第二种: + select t1.* from (select emp.*,rownum rn from emp where rownum <=10) t1 where rn >=6; + 在oracle中只能使用子查询来做分页查询 + 页码:page + 每页最多条数:pageSize 5条 + 第一页:1~5 + 第二页:6~10 + 第三页:11~15 + start:(page-1)*pageSize+1 + end:pageSize*page +21、DECODE函数 + DECODE(参数1,值1,结果1,值2,结果2...[,默认值]) + 参数1依次与值进行匹配,与哪个匹配成功则显示对应的结果,若均未匹配,则显示最后一个默认值 + 查询职员表,根据职员的职位计算奖励金额,当职位分别是'MANAGER','SALESMAN','ANALYST'时, + 奖励金分别是薪水的1.2倍,1.1倍,1.05倍,如果不是这三个职位,则奖励金额取薪水值 + select ename,job,sal, + decode(job, + 'MANAGER',sal*1.2 + 'SALESMAN',sal*1.1 + 'ANALYST',sal*1.05 + sal + ) "奖金" from emp + 分组操作: + select decode(job, + 'MANAGER','VIP', + 'ANALYST','VIP', + 'OPERATION' + ) from emp group by + decode(job, + 'MANAGER','VIP', + 'ANALYST','VIP', + 'OPERATION' + ) + 排序: + select * from emp order by decode(job, + 'MANAGER',1 + 'SALESMAN',2 + 'ANALYST',3 + 4 + ) +22、集合函数 + UNION并集:将两个查询结果进行排序 + 所有的查询结果可能不是来自同一张表 + + 工资大于1500,或者20号部门下的员工 + select * from emp where sal>1500 or deptno=20 + --工资大于1500,或者20号部门下的员工 + select * from emp where sal>1500 + --20号部门下的员工 + select * from emp where deptno=20 + 并集运算:union、union all + union:去除重复的,并且排序 + union all:不会去除重复的 + select * from emp where sal>1500 + union + select * from emp where deptno=20 + INTERSECT交集:同时存在于两个结果集中的数据 + 工资大于1500并且在20号部门下的员工 + select * from emp where sal>1500 + INTERSECT + select * from emp where deptno=20 + MINUS差集:两个结果相减 + 1981年入职员工(不包括总裁和经理) + --1981年入职员工 + select * from emp where to_char(hiredate,'YYYY')='1981' + --总裁和经理 + select * from emp where where job='PRESIDENT' or job='MANAGER' + + select * from emp where to_char(hiredate,'YYYY')='1981' + MINUS + select * from emp where job='PRESIDENT' or job='MANAGER + 集合运算中的注意事项: + 1.列的类型要一致 + 2.按照顺序写 + 3.列的数量要一致,如果不足,用空值填充 + --列的类型不匹配 + select ename,sal from emp where sal>1500 + union + select sal,ename from emp where deptno=20 + --列的数量不匹配 + select ename,sal,deptno from emp where sal>1500 + union + select ename,sal from emp where deptno=20 +23、DDL语句管理表 + 1)创建表空间: + 逻辑单位,通常我们新建一个项目,就会新创建表空间,在表空间中创建用户来创建表 + 语法: + create tablespace 表空间的名称 + datafile '文件的路径' + size 大小 + autoextend on 自动扩展 + next 每次扩展的大小 + 切换到system账号下创建 + 删除表空间: + drop tablespace YYP + 2)创建用户: + create user 用户名 + identified by 密码 + default tablespace 表空间的名称 + 删除用户 + drop user yuanyipeng cascade; + 更改用户密码 + alter user 用户名 identified by 密码; + 授权 + grant connect to yuanyipeng + 分配角色 + grant dba to yuanyipeng + select * from scott.emp + 使用子查询的方式创建表: + create table 表名 as 查询语句 + create table emp as select * from scott.emp + 注意:只会复制表结构和表中数据,不会复制列的约束 + 如果查询语句有结果,就是复制表结构和数据 + 如果查询语句没有结果,就是复制表结构 + 只复制表数据(添加语句里可以没有values关键字) + insert into 表名 查询语句(表的结构与已有表结构一致) + 3)列的约束:约束主要是用来约束表中数据的规则 + 主键约束:primary key 不能为空,必须唯一 + 非空约束:not null + 唯一约束:unique + 检查约束:check(条件)在mysql中是可以写的,但是mysql直接忽略了检查约束 + 外键约束:主要是用来约束从表A中的记录,必须是存在于主表B中(保证数据完整性) + create table books( + book_id number(10) primary key, + book_name varchar2(20) not null, + price number(10,2), + cid number(10) not null references category(id)--外键约束 + ); + create table books( + book_id number(10) primary key, + book_name varchar2(20) not null, + price number(10,2), + cid number(10) not null, + foreign key(cid) references category(id)--外键约束 + ); + + create table category( + id number(10) primary key, + cname varchar2(10) + ); + alter table books add foreign key(cid) references category(id) +24、视图 + 数据库对象之一,视图在sql语句中体现的角色和表完全相同,但是视图并不是一个真实存在的表,它对应的是一 + 个查询语句的结果集(视图名跟表名不能一样) + 视图的作用:简化复杂查询、限制数据访问 + 1)创建简单视图(单表) + 若无权限,使用system用户授权 + 视图授权语句: + grant create view to 用户名; + 创建一个简单视图v_emp_10来显示部门10中的员工的编码、姓名和薪水 + create view v_emp_10 + as + select empno,ename,sal,deptno + from emp where deptno=10; + 2)修改视图 + 修改视图就是替换该视图的子查询,使用create or replace view 视图名即可,若视图不存在就创建,存在就替换 + 创建视图时,给列赋予别名 + create or replace view v_emp_10 + as + select empno id,ename name,sal salary,deptno + from emp where deptno=10; + 3)查询视图 + select * from v_emp_10 + 视图的列名和创建视图时的列名一致,不一定是原列名; + select id,name,salary from v_emp_10 + 4)视图的DML操作 + 对视图进行DML操作就是对视图数据来源的基础表进行操作 + 插入数据: + 1.注意视图中看不见的字段都被插入默认值,所以不能违反基础表中相应字段的约束条件,尤其是看不见的 + 字段的not null,否则会插入失败 + 2.为视图添加检查选项可以避免对视图进行DML操作时污染基础表,在创建语句后加with check option + 3.如果没有在视图上执行DML操作的必要,在建立视图时声明为只读来避免这种情况,保证视图对应的基础表 + 数据不会被非法修改with read only + 5)视图根据子查询的不同,分为简单视图和复杂视图,当子查询中包含单行函数、表达式或分组函数时,该视图是 + 一个复杂视图,复杂视图不能进行DML操作,必须为子查询中的表达式或函数定义别名 + 创建一个视图v_emp_salary,把职员表的数据按部门分组,获得每个部门的平均薪水、薪水总和、最低薪水 + create view v_emp_salary + as + select d.dname,avg(sal) avg_sal,sum(sal) sum_sal,min(sal) min_sal from emp e,dept d + where e.deptno=d.deptno group by d.dname + 6)删除视图 + DROP VIEW 视图名称 +25、序列:sequence 用来生成唯一数字值的数据库对象,通常作为表的主键值 + 序列是独立的数据库对象,序列并不依附于表 + 1)创建序列 + create sequence 序列名 + start with xx 起始数据 + increment by xx 步长(每次增加几) + maxvalue xx 最大值 + minvalue xx 最小值 + + create sequence users_seq + start with 100 + increment by 10 + + 序列中有两个伪列 + ---nextval:获取序列的下个值 + ---currval: 获取序列的当前值 + 当序列创建以后,必须先执行一次nextval,之后才能使用currval + 获取序列的第一个值,并且使用序列值为users表插入新的记录 + select users_seq.nextval from dual; + insert into users(id,name) values(users_seq.nextval,'马冬梅') + 2)删除序列:drop sequence users_seq +26、索引:一种提高查询效率的机制 + 经常作为过滤条件,去重,排序或链接条件的字段可以为其添加索引 + 1)创建索引: + create [unique] index 索引名称 + on 表名(列名) + 添加单列索引 + 在users表的name列上建立索引 + create index idx_users_name on users(name); + 添加多列索引 + create index idx_users_name_salary on users(name,salary); + 查询过程中自动应用索引,不需要我们制定,提高查询速度 + select * from users order by name,salary + 2)修改或删除索引 + 如果经常在索引列上执行DML操作,需要定期重建索引,提高索引的空间利用率 + alter index 索引名称 rebuild + 删除索引:drop index 索引名称 \ No newline at end of file diff --git a/JDBC/bin/note/sql/SQL.sql b/JDBC/bin/note/sql/SQL.sql new file mode 100644 index 0000000..f831846 --- /dev/null +++ b/JDBC/bin/note/sql/SQL.sql @@ -0,0 +1,460 @@ +--SQL.day.02 +--创建表 +CREATE TABLE users( + id number(10) primary key,--主键 + name varchar2(20) unique,--唯一标识 + salary number(10,2), + create_time date default sysdate +); + +--查看表结构(在command window里用,SQL window不能使用) +desc 表名 + +--修改表名 +RENAME users to userplus + +--向表中添加字段 +ALTER TABLE userplus ADD(school varchar2(20)) +ALTER TABLE userplus ADD(job varchar2(10)) + +--删除表中已有字段 +ALTER TABLE userplus DROP(school) + +--修改表中已有字段的格式 +ALTER TABLE userplus MODIFY(salary number(10)) +ALTER TABLE userplus MODIFY(username varchar2(20) unique) + +--修改表中字段名称 +ALTER TABLE userplus RENAME column name to username + +--向表中添加数据 + --全字段插入数据 +INSERT INTO userplus VALUES(1, '张三', 8000,sysdate, '程序员'); +INSERT INTO userplus VALUES(2, '张三', 8000,default, '程序员');--因为表中有default sysdate,所以这里可以直接写default +INSERT INTO userplus VALUES(3, '张三', 8000,to_date('2018-12-01','YYYY-MM-DD'), '程序员'); + --部分字段插入 +INSERT INTO userplus(id, username, job) VALUES(4,'王五','产品经理'); +INSERT INTO userplus(id, username, job, salary) VALUES(5,'王五','产品经理',5000) + +--更新表中已有数据 +UPDATE userplus SET salary=salary*10, job='总经理' WHERE id=1; + +--删除表中数据 +DELETE FROM userplus WHERE salary>5000; + +--提交事务 +commit; + +--回滚 +rollback; + +--查询表中所有数据 +SELECT * FROM userplus; + +--查询部分数据信息 +SELECT job, salary FROM userplus; +SELECT * FROM userplus WHERE job <> '架构师'; +SELECT salary*12 "年薪" FROM userplus WHERE username='王五';--别名 +SELECT salary*12 AS "年薪" FROM userplus WHERE username='王五';--别名 + +--10.(1)字符串函数 + --连接字符串 +SELECT CONCAT(ename, sal) from EMP; +SELECT CONCAT(CONCAT(ename, ': ') ,sal)from EMP; +SELECT ename||': '||sal as "姓名:工资" from EMP; + --显示字符串长度 +SELECT LENGTH(ename) from EMP; + --转大写 +SELECT UPPER(ename) from EMP; + --去除字符串前后指定内容 +SELECT TRIM('E' from 'EEHELLO WORLDEEE') from dual; +SELECT ename, trim('A' FROM ename) from emp; --去除员工名字前后的所有'A' +SELECT LTRIM('EEHELLO WORLDEEE', 'E') from dual;--去除EEHELLO的前面的E +SELECT ename, ltrim(ename,'A') from emp;--去除员工名字前面的所有'A' + --补位函数 +select * from emp +select ename, LPAD(sal, 6, 0) AS salary from emp + --substr截取字符串 +select substr('helloworldqqqqq',6,10) from dual; + --INSTR字符串检索 +select instr('thinking in java','in',4,2) from dual; + +--10.(2)数字函数 + --截取,用于四舍五入 +select round(321.123,1) from dual; + --截取,无四舍五入 +select trunc(45.678,2), trunc(45.678,0), trunc(45.678), trunc(45.678,-1) from dual; + --取余数 +select ename, sal, mod(sal,1000) from emp; + --向上取整 +select ceil(45.678) from dual; + --向下取整 +select floor(45.678) from dual; +--10.(3)日期函数 + --系统时间,精确到秒 +select sysdate from dual; + --时间戳,精确到毫秒 +select systimestamp from dual; + --TO_DATE(),日期转换函数 +select to_date('2018-12-01 11:30','YYYY-MM-DD HH:MI:SS') from dual; +select to_date('2018-12-01 13:30','YYYY-MM-DD HH24:MI:SS') from dual; + --TO_CHAR(),将DATE按照给定的日期格式转换为字符串 +select ename, to_char(hiredate,'YYYY-MM-DD HH:MI:SS') from emp; +select ename, to_char(hiredate,'YYYY"年"MM"月"DD"日"') from emp; + --LAST_DAY(date),返回指定日期所在月的最后一天 +select last_day(sysdate) from dual; +select last_day(to_date('2018-12-01 11:30','YYYY-MM-DD HH:MI:SS')) from dual; + --ADD_MONTHS(date,i),返回+-i个月之后的日期 +select ename, hiredate, add_months(hiredate, 12*20) AS "20周年" from emp; + --MONTHS_BETWEEN(date1,date2):计算两个日期之间相差多少个月 +select ename,trunc(months_between(sysdate, hiredate)) from emp; + --date日期类型在数据库中可以进行减法操作,结果是相差的天数: +select ename, sysdate-hiredate from emp; + --LEAST(date1,date2):显示两个时间中的最小值。参数类型必须一致。 +select least(sysdate,to_date('2018/12/09','YYYY-MM-DD')) from dual; + --GREATEST(date1,date2):显示两个时间中的最大值。参数类型必须一致。 +select greatest(sysdate,to_date('2018/12/09','YYYY-MM-DD')) from dual; + --EXTRACT(date from datetime):从参数datetime中提取参数date指定的数据,比如提取:年、月、日。 +select extract(year from sysdate),extract(month from sysdate),extract(day from sysdate) from dual; +select extract(hour from systimestamp),extract(minute from systimestamp),extract(second from systimestamp) from dual; +select ename from emp where extract(year from hiredate) = 1980; + +--10.(4)空值函数: +select * from emp where comm is not null and comm != 0; + --NVL(arg1,arg2):将null转变为非null值。如果arg1为null,返回arg2;否则返回本身。 +select ename,nvl(comm,0) from emp; +select * from emp where nvl(comm,0)>0; + --NVL(arg1,arg2),如果arg1为null,返回arg2;否则返回本身。计算员工月收入(月工资加奖金(奖金可能为null)) +select ename, sal, comm, sal+nvl(comm,0) as "月收入" from emp; + --NVL2(arg,res1,res2):如果arg为null,则返回res2,arg不为null则返回res1. +select ename, sal, comm, nvl2(comm,comm+sal,sal) as"月收入" from emp; + +--11.基本查询语句: + --查询部门10下的员工信息: +select * from emp where deptno = 10; + --查询员工表中职位是'SALESMAN'的员工信息 +select * from emp where job = 'SALESMAN'; + +--12.查询条件: + --查询职员表中薪水低于2000的职员信息 +select ename, sal from emp where sal < 2000; + --查询职员表中不属于部门10的员工信息 +select * from emp where deptno <>10; + --查询职员表中在1981年1月1号以后入职的职员信息 +select * from emp where hiredate > to_date('1981/01/01','YYYY/MM/DD'); + --查询薪水大于1000,并且职位是'CLERK'的职员信息 +select * from emp where sal>1000 and job='CLERK'; + --查询薪水大于1000,或者职位是'CLERK'的职员信息 +select * from emp where sal>1000 or job='CLERK'; + --NVL(arg1,arg2),NVL2(arg,res1,res2) + --查询薪水大于1000,并且奖金不为null的职员信息 +select * from emp where sal>1000 and comm>0; +select * from emp where sal>1000 and nvl(comm,0)>0; +select * from emp where (deptno=20 or deptno=30) and sal>800; + --模糊查询,LIKE + --查询员工表中姓名以'A'开头的员工信息 +select * from emp where ename like 'ALLEN'; + --查询员工表中姓名第二个字母是'A'的员工信息 +select * from emp where ename like '_A%'; + --IN和NOT IN: + --查询职位是经理或者职员的员工信息 +select * from emp where job in ('MANAGER','CLERK'); + --查询部门不是10或20的员工 +select * from emp where deptno not in (10,20); +select * from emp where deptno <> all(10,20); + --BETWEEN...AND...:是用来查询符合某个值域范围条件的数据。 + --查询薪水在1500~3000之间的职员信息 +select * from emp where sal between 1500 and 3000;--[1500,3000] + --查询比经理最低工资高的员工信息。 +select * from emp where sal > any(select sal from emp where job='MANAGER'); + --查询员工的部门编号 +select distinct(deptno) from emp; +select distinct deptno,job from emp; + +--14.ORDER BY 排序(写在所有子句最后) +select ename, sal from emp order by sal; +select ename, sal from emp order by sal asc; +select * from emp where sal>2000 order by mgr desc; + --多列排序,对员工表中的职员排序,先按照部门编号正序排列,再按照薪水降序排列。 +select ename, deptno, sal from emp order by deptno asc, sal desc; + +--15.聚合函数 + --MAX和MIN +select deptno,max(sal),min(sal) from emp group by deptno; +select max(hiredate),min(hiredate) from emp; +select ename from emp a where hiredate = (select max(hiredate) from emp); + --ERROR: +select ename from emp a where hiredate = (select max(hiredate),min(hiredate) from emp); + --RIGHT: +select ename from emp where hiredate in ((select min(hiredate) from emp), (select max(hiredate) from emp)); + --AVG和SUM +select avg(sal),sum(sal) from emp; +select avg(comm),sum(comm) from emp;--忽略null值 + --COUNT +select count(*) from emp; +select count(comm) from emp;--忽略null值 +select count(*) from emp where comm is not null; + --不希望聚合函数忽略NULL值时: +select avg(nvl(comm,0)) from emp; + +--16.GROUP BY +select max(sal),min(sal),avg(sal) from emp group by deptno; +select deptno,max(sal),min(sal),avg(sal) from emp group by deptno; +select deptno,ename,max(sal),min(sal),avg(sal) from emp group by deptno,ename; + --where后面不能使用聚合函数,不能执行. +select max(sal),deptno from emp where max(sal)>4000 group by deptno; + --查询部门中最大工资超过4000的部门以及最大工资。 +select max(sal),deptno from emp group by deptno having max(sal)>4000; + --查看部门编号,以及该部门的平均工资(要求是该本门的平均工资超过2000,职位是PRESIDENT的不能参与统计) +select deptno, avg(sal) from emp where job<>'PRESIDENT' group by deptno having avg(sal)>2000; + +--19.关联查询 + --查询每个员工所在部门名称 +select ename, dname from emp, dept where emp.deptno=dept.deptno; + --查看员工名字、工资、部门名称 +select ename, sal, dname from emp e, dept d where e.deptno=d.deptno and loc='CHICAGO'; + --KING在哪里工作以及他的部门编号是多少? +select ename, e.deptno, loc from emp e, dept d where e.deptno=d.deptno and ename='KING'; + +--20.连接种类 + --内连接 +select ename, dname from emp inner join dept on emp.deptno=dept.deptno; + --外连接 + --快速从一个表中复制数据 +create table empc as select * from emp; + --向empc表中插入一条数据,部门号为50 +insert into empc(empno, ename, deptno)values(1000,'JACK',50); +select * from empc; + --左外连接,查询员工的编号、姓名、以及部门名称,包括不属于任何部门的员工。 +select empno, ename, dname, empc.deptno from empc left outer join dept on empc.deptno=dept.deptno; + --右外连接,查询员工的编号、姓名、以及部门名称,包括任何没有员工的部门。 +select empno, ename, dname, c.deptno from empc c right outer join dept d on c.deptno=d.deptno; + --全外连接,查询员工的编号、姓名、以及部门名称,包括不属于任何部门的员工,也包括任何没有员工的部门。 +select empno, ename, dname, c.deptno from empc c full outer join dept d on c.deptno=d.deptno; + --自连接,查询每个员工的上级领导 +select e.ename, m.ename from emp e, emp m where e.mgr=m.empno; +select e.ename emp, m.ename mgr from emp e left outer join emp m on e.mgr=m.empno; + --查询SMITH的上司在哪个城市工作 + --等值连接 +select e.ename emp, m.ename mgr, d.loc mgrloc +from emp e, emp m, dept d +where e.mgr=m.empno and m.deptno=d.deptno and e.ename='SMITH'; + --内连接 +select e.ename emp, m.ename mgr, d.loc mgrloc +from emp e inner join emp m +on e.mgr=m.empno and e.ename='SMITH' +inner join dept d +on m.deptno=d.deptno; + +--(外连接的另一种写法):查询每一个员工的同时,根据员工的部门编号查询部门的信息,若查询不到部门,该员工的部门信息就是null +select e.ename, e.sal, e.deptno from empc e;--ERROR + --Solution 1. +select e.ename, e.sal, +(select d.deptno from dept d where d.deptno=e.deptno) deptno +from empc e;--RIGHT + --Solution 2.正常的外连接写法:为满足要求,要写成d.deptno +select e.ename, e.sal,d.deptno +from empc e left outer join dept d +on e.deptno=d.deptno; + --Solution 3.当三张表时(例子不是三张表),这种方法比较简单一些 +select e.ename, e.sal, +(select d.dname from dept d where d.deptno=e.deptno) dname, +(select d.loc from dept d where d.deptno=e.deptno) loc +from empc e; + +--21.子查询 + --WHERE: + --单行子查询:查询大于部门号20的最高工资的员工信息 +select ename, sal from emp where sal>(select max(sal) from emp where deptno=20); + --单行子查询:查询与SCOTT同部门的员工信息 +select ename, job from emp where deptno=(select deptno from emp where ename='SCOTT') + --单行子查询:查找薪水比整个机构平均薪水高的员工 +select ename, job, sal from emp where sal>(select avg(sal) from emp); + --多行子查询:查询部门有SALESMAN但职位不是SALESMAN的员工的信息。 +select * from emp where deptno in (select deptno from emp where job='SALESMAN') and job<>'SALESMAN'; + --多行子查询:查询比10号部门某个员工工资相等的员工信息 +select * from emp where sal = any (select sal from emp where deptno = 10); + --多列子查询:?????????????????????????????????????????????????????????????????????????? + --EXISTS关键字:列出来那些有员工的部门信息 +select deptno, dname from dept d where EXISTS (select * from emp e where e.deptno=d.deptno); + --HAVING: + --查询最低工资高于部门30的最低工资的部门信息 +select min(sal) from emp group by deptno having min(sal)<(select min(sal) from emp where deptno=30); + +--22.分页查询 + --查询rownum大于2的所有记录 +select rownum, e.* from emp e where rownum>2;--ERROR,因为没有任何记录。 +select rownum, e.* from emp e where rownum>=1; +select rownum, e.* from emp e where rownum<6; + --找到员工表中工资最高的前三名(降序排序): + --ERROR +select rownum, e.* from emp e order by sal desc where rownum<=3; + --RIGHT +select * from emp order by sal desc;--先降序,再把它当成一张表,再去选rownum小于等于3的行。 +select rownum, t1.* from (select * from emp order by sal desc) t1 where rownum <=3; + --查询第6~10条记录(两种方法) +select * from (select rownum rn, e.* from emp e) t where t.rn between 6 and 10; +select t1.* from (select rownum rn, emp.* from emp where rownum<=10) t1 where rn between 6 and 10; + --工资降序后选6~10条记录:原表先降序,再加伪列,再当新表选范围。 +select * from (select rownum rn, e.* from (select * from emp order by sal desc) e) t where t.rn between 6 and 10; + +--23.DECODE(参数1,值1,结果1,值2,结果2...[,默认值]); + --查询职员表,根据职员的职位计算奖励金额,当职位分别是'MANAGER','SALESMAN','ANALYST'时,奖励金分别是薪水的1.2,1.1,1.05倍,其它为原本的薪水值。 +select ename, job, sal, decode(job,'MANAGER',sal*1.2,'SALESMAN',sal*1.1,'ANALYST',sal*1.05,sal) "奖金" from emp; +select decode(job,'MANAGER','VIP','ANALYST','VIP','OPERATION') from emp; + --分组操作,不能起别名 +select decode(job,'MANAGER','VIP','ANALYST','VIP','OPERATION') job, count(*) from emp group by decode(job,'MANAGER','VIP','ANALYST','VIP','OPERATION'); + --自定义排序 +select * from emp order by decode(job,'MANAGER','1','SALESMAN','2','ANALYST','3'); + +--24 + --union + --工资大于1500或20号部门下的员工 +select * from emp where sal>1500 or deptno=20; + --工资大于1500的 +select * from emp where sal>1500;--7条记录 + --20号部门下的员工 +select * from emp where deptno=20;--5条记录 + --并集运算:union(忽略重复数据,9条记录,并排序), union all(不忽略重复数据,12条记录,不排序) +select * from emp where sal>1500 union select * from emp where deptno=20;--并集之后,总共9条记录 + --INTERSECT,交集 +select * from emp where sal>1500 INTERSECT select * from emp where deptno=20; + --MINUS差集:两个结果相减。 + --1981年入职员工(不包括总裁和经理) +select * from emp where to_char(hiredate,'YYYY')='1981'; +select * from emp where job in ('PRESIDENT','MANAGER'); +select * from emp where to_char(hiredate,'YYYY')='1981' MINUS select * from emp where job in ('PRESIDENT','MANAGER'); + --注意事项: +select empno,ename from emp where to_char(hiredate,'YYYY')='1981' MINUS select null,ename from emp where job in ('PRESIDENT','MANAGER'); + +--25.DDL语句管理表: +CREATE tablespace YYP datafile 'e:/YYP.dbf' size 100m autoextend on next 10m;--创建 +drop tablespace YYP;--删除(取消和文件的关联,不会删除文件)(取消关联之后,可以手动删除)。 +create user zicheng identified by qqq default tablespace YYP;--创建用户 +drop user zicheng cascade;--删除用户 +alter user zicheng identified by eee;--修改密码 +grant connect to zicheng;--授权 +grant dba to zicheng;--分配角色 + --使用子查询的方式创建表: +create table emp as select * from scott.emp;--只复制表结构和表数据,不会复制列的约束。 +create table dept as select * from scott.dept where 1=2;--只复制表结构,无数据,因为1=2为false。 +insert into dept select * from scott.dept;--只复制表数据,但前提是表的结构与已有表结构一致。 +select * from dept; + +--26.列的约束 + --检查约束 +CREATE TABLE users( + id number(10) primary key,--主键 + name varchar2(20) unique,--唯一标识 + sex varchar2(2) check(sex in ('男' ,'女')),--检查约束 + salary number(10,2) check(salary>3000), + create_time date default sysdate +); +insert into users values(1,'admin','男',3500,default); + --外键约束 +create table category( + id number(10) primary key, + cname varchar2(10) +); +create table books( + book_id number(10) primary key, + book_name varchar2(20) not null, + price number(10,2) check(price>100),--检查约束 + cid number(10) not null references category(id)--外键约束 + --foreign key(cid) references category(id)--另一种外键约束的方式 +); + --可以不在定义表中建立外键约束,单独用此语句也可实现外键约束。 +alter table books add foreign key(cid) references category(id); + --例子: +insert into category values(1,'小说'); +insert into category values(2,'文学'); +insert into category values(3,'传记'); +select * from category; +insert into books values(1,'西游记',101,1); +select * from books; + --不能删除外键,因为从表中有相关的已建立关联的外键约束 +delete from category where id=1; +delete from books where cid=1;--删除外键关联的两种方法 +update books set cid=null where cid=1;--然后再删除主表中的数据就ok。 + +--27.视图 + --创建一个简单视图v_emp_10来显示部门10中的员工的编码、姓名和薪水。 +create view v_emp_10 as select empno,ename,sal,deptno from emp where deptno=10; + --修改视图就是替换该视图的子查询,使用create or replace view 视图名 即可,若视图不存在就创建,存在就替换。创建视图时,可以给列赋予别名。 +create or replace view v_emp_10 as select empno id,ename name,sal,deptno from emp where deptno=10; + --查询视图 +select * from v_emp_10; + --视图的DML操作,会修改原表的数据 +insert into v_emp_10 values(1,'Tony',8888,50) +select * from emp; + --with check option +create or replace view v_emp_10 as select empno id,ename name,sal,deptno from emp where deptno=10 with check option + --with read only只读,不能对视图进行DML操作。 +create or replace view v_emp_10 as select empno,ename,sal,deptno from emp where deptno=10 with read only; + --创建一个视图v_emp_salary,把职员表中的数据按部门分组,获得每个部门的平均薪水、薪水总和、最低薪水。 +create view v_emp_salary as select d.dname, avg(sal) avg_sal,sum(sal) sum_sal,min(sal) min_sal,max(sal) max_sal from emp e, dept d where e.deptno=d.deptno group by d.deptno, d.dname; +select * from v_emp_salary; + --drop view 视图名称:删除视图 +drop view v_emp_slary; + +--28.序列 + --建表、建立序列、插入基表、删除序列 +CREATE TABLE users( + id number(10) primary key,--主键 + name varchar2(20), --unique,--唯一标识 + salary number(10,2), + create_time date default sysdate +); + --建立序列:create sequence 序列名 start with **(起始数据) increment by **(步长,每次增加几,可正可负) maxvalue **(最大值) / minvalue **(最小值); +create sequence users_seq start with 100 increment by 10;--建立序列,第一次一定要用nextval,不能用currval +insert into users(id,name)values(users_seq.nextval,'马冬梅');--插入基表 +select users_seq.currval from dual;--查看当前序列值。 +drop sequence users_seq;--删除序列 + --循环插入 +begin + for i in 1..10000 + loop + insert into users(id,name,salary) values( users_seq.nextval,'瞬间爆炸',8888); + end loop; + commit; +end; + +--29.索引 + --创建索引:create [unique] index 索引名称 on 表名(列名) +create index idx_users_name on users(name);--在users表的ename列上建立索引 + --添加多列索引: +create index idx_users_salary on users(name,salary); + --查询过程中自动应用索引,不需要单独去制定,提高查询速度。 +select users.* from users order by name, salary; + --重构索引(索引是平衡二叉树,修改表后,最好重构一下索引的平衡二叉树) +alter index 索引名称 rebuild;--经常修改数据的表,不建议建立索引。 + --删除索引: +drop index idx_users_salary; + + + + + + + + + +--练习 +create table student( + id number(10) not null, + name varchar2(20), + hobby varchar2(100), + school varchar2(20), + create_time date +); +--修改表名student_t +rename student to student_t; +--添加字段:科目project,成绩score +alter table student_t add(project varchar2(20), score number(3)); +--删除学校字段 +alter table student_t drop(school); +--修改字段格式 +alter table student_t modify(create_time varchar2(20) default sysdate); +--修改表中字段名称,name改为stu_name +alter table student_t rename column name to stu_name; + diff --git a/JDBC/bin/note/sql/SQLNote.sql b/JDBC/bin/note/sql/SQLNote.sql new file mode 100644 index 0000000..a18543f --- /dev/null +++ b/JDBC/bin/note/sql/SQLNote.sql @@ -0,0 +1,422 @@ +数据库//297,308,415 +一、 使用sqlplus连接数据库 + 1. 方式: + 1) sqlplus,回车,输出用户名和密码 + 2) sqlplus/nolog ------conn scott/tiger + 3) 使用可视化界面,developer。注意:使用窗口连接可视化工具却不能连接,会出现无服务或无监听错误,需要重新配置监听。(a.关闭服务。 b.根据配置监听文件修改HOST为当前IP,或修改为localhost,或127.0.0.1,或主机名。 c.再开启服务重新连接登陆即可。) + 2. 命令窗口注意事项: + 1) 所有sql语句以“;”结尾,回车执行。 + 2) sql语句不区分大小写,字符串除外。 + 3. Oracle用户(oracle安装后会自动生成4个账户): + 1) sys用户:超级用户,具有最高权限,具有sysdba(数据库管理员)角色,有数据字典和视图权限,能创建数据库,默认密码manager。 + 2) system用户:操作员,仅次于超级用户,具有sysoper(系统操作员)角色。不能创建库。 + 4. DB:Database数据库,关系型数据库,按照数据结构来管理数据的仓库,以二维表(列:字段; 行:数据)的形式存储数据。 + DBMS:数据库管理系统(Oracle, mysql, sqlserver…) +二、 sql语句 + 1. SQL (Structed Query Language,结构化查询语言) + 2. SQL分类: + DDL:数据定义语言,用于操作数据对象(表,视图,序列,索引)。 + CREATE:创建表或其它对象。 + ALTER:修改表或其它对象结构。 + DROP:删除表或其它对象。 + TRUNCATE:删除表数据,保留表结构。清空表的操作。 + DML:数据操作语言(通常需要伴随TCL),用于增删改表中的数据。 + INSERT INTO:将数据插入表中。 + DELETE:删除表中数据。 + UPDATE SET:更新表中数据。 + TCL:事务控制语言。 + COMMIT:提交。 + ROLLBACK:回滚。 + DQL:数据查询语言 + SELECT:查询数据。 + DCL:数据控制语言。 + GRANT:授予权限。 + grant…create…view…to…scott; + 3. 数据类型: + char(n):定长字符串,n是字节数。最多2000字节。 + varchar2(n):变长字符串,n是字节数。最多4000字节。 + number(n,m):n共多少位数字,m是其中几位小数。 + date:时间日期,select sysdate from dual; +三.SQL(DDL, DML,TCL,DQL) +软件的构成? + 1.前端:HTML,CSS,JS,JQuery + 2.后台:Java + 3.数据库:Oracle, Mysql(被甲骨文收购) + +1.安装Oracle + + 常用用户: + sys:超级用户 具有最高权限 具有sysdba角色 (数据库管理员) + 有创建数据库的权限 + system:管理操作员 权限仅次于超级管理员 + + scott:普通用户 一般用于练习 scott -- tiger + 解锁用户:alter user scott account unlock + 设置密码:alter user scott identified by tiger + +2.登录方式 + 1)sqlplus 回车 + 输入用户名 + 输入密码 + + 2)sqlplus/nolog + conn scott/tiger + +3. DB:DataBase 按照数据结构来管理数据的仓库(关系型数据库),以二维表形式存储数据(表的列:字段名 表的行:数据) + DBMS:数据库管理系统(mysql、oracle、SqlServer) + +4.常用命令 + sqlplus 打开数据库 + conn 用户名/密码 连接数据库 + show user; 显示当前用户 + exit; 断开连接 + quit; 断开连接 + +5.SQL:结构化查询语言 + SQL的分类: + DDL 数据定义语言 用于操作数据对象(表 视图 序列 索引) + DML 数据操作语言 用于增删改表中的数据(通常伴随事务) + TCL 事务控制语言 用于数据的提交和撤销 + DQL 数据查询语言 用于查询数据记录 + DCL 数据控制语言 用于执行权限分配 + + DDL:数据定义语言 + ---用于操作数据库对象(表 视图 序列 索引) + CREATE:用来创建表或其他对象 + ALTER:修改表或其他对象的结构 + DROP:删除表或其他对象的结构 + TRUNCATE:清空表(删除表中数据,保留表结构) + DML:数据操作语言 + ---用于增删改表中的数据(通常伴随事务控制语言) + INSERT INTO:将数据插入到表中 + DELETE:删除表中数据 ---- WHERE + UPDATE 表名 SET:更新表中数据 --- WHERE + + TCL:事务控制语言 + COMMIT:提交--保存 + ROLLBACK:回滚---后退 + + DQL:数据查询语言 + SELECT 查询***** + + DCL:数据控制语言 + 用来执行权限分配 GRANT REVOKE +6.DDL 数据定义语言 + 查看用户定义的表: + SELECT table_name FROM user_tables;--用户定义的所有表都会被列出来 + (1)创建表 + CREATE TABLE 表名 ( + 列名(字段名) 数据类型 [默认值 约束], + 列名(字段名) 数据类型 [默认值 约束], + 列名(字段名) 数据类型 [默认值 约束], + 列名(字段名) 数据类型 [默认值 约束] + ); + CREATE TABLE users( + id number(10) primary key, + name varchar2(20) not null unique, + salary number(10,2), + create_time date default sysdate + ); + id(主键) 特点:该列在整张表中每一行所保存的值都不相同,且必须有值(非空且唯一) + 命名规则: + 表名和列名: + 1)必须以字母开头 + 2)必须在1-30个字符之间 + 3)必须只能包含A-Z,a-z,0-9,_,$,和# + 4)必须不能和用户定义的其他对象重名 + 5)必须不能是Oracle的保留字 + 数据类型: + 1)NUMBER:数值类型 + NUMBER(X):x代表位数 + NUMBER(3) 最多能存放3位数 + NUMBER(X,Y):x表示共几位 y表示其中有几位是小数 + NUMBER(6,2) 8888.88 + 2)CHAR:定长字符串 + CHAR(X):X表示共占多少字节 最多放2000字节 + 3)VARCHAR2:变长字符串 + VARCHAR2(X):X表示共占多少字节(根据其中保存的数据长度,占用的空间是变化的) 最多4000字节 + 4)DATE 时间日期 SELECT SYSDATE FROM DUAL; + 伪表:dual确实是一张表,是一张只有一行一列的表,习惯上称为伪表,因为它不存储具体的数据。 + 查看表结构(在command window):DESC table_name; + (2)删除表: + DROP TABLE users;--删除表数据和结构 + TRUNCATE TABLE users;--删除表数据,保留表和表结构 + (3)修改表(ALTER): + 修改表名:RENAME old_name TO new_name + 修改表结构: + 向表中添加字段(只能添加到最后,不能插入到现有的序列中):ALTER TABLE table_name ADD(字段名,数据类型[默认值 约束]), 例如:ALTER TABLE usersplus ADD(school varchar2(20)) + 删除表中已有字段: ALTER TABLE biaoming DROP(字段名),例如:ALTER TABLE userplus DROP(school) + 修改表中已有字段的格式:ALTER TABLE 表名 MODIFY(字段名,数据类型[默认值 约束]),例如:ALTER TABLE userplus MODIFY(salary number(10)) + 修改表中字段名称:ALTER TABLE userplus RENAME column name to username +7.DML 数据操作语言 + (1)向表中添加数据: + 全字段插入数据:INSERT INTO 表名 VALUES(1, '张三', 8000,sysdate, '程序员'); 注意:values中的数据顺序要和定义字段时一致。 + 部分字段插入数据:INSERT INTO 表名(想要插入数据的字段)VALUES(与字段顺序相对应的数据)。 + (2)修改表中已有数据: + 在修改表中数据时,通常添加where子句来限定要修改的记录,这样就只能修改满足where条件的记录。否则修改全表。 + UPDATE 表名 SET 字段名=数据 WHERE 字段名=数据 + (3)删除表中数据: + DELETE FROM 表名 WHERE 字段名=数据。通常与where子句连用,否则删除表中所有数据。 + 在DDL语句中的TRUNCATE语句同样有删除表数据的作用。 + TRUNCATE和DELETE的区别:DELETE可以有条件的删除数据,但TRUNCATE将表中的数据全部删除;DELETE是DML语言,可以rollback,TRUNCATE是事务控制语言,立即生效,无法rollback. + 删除全部记录:DELETE FROM userplus(效率低); TRUNCATE TABLE userplus(效率高). +8.TCL:事务控制语言 + (1)commit:提交; 可以通过语句或按钮去提交,或者正常关闭数据库时会默认提交。 + (2)rollback:回滚; + 事务的四个特性: + 原子性(Atomicity): +    原子性是指事务包含的所有操作要么全部成功全部应用,要么全部失败回滚。因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。 + 一致性(Consistency): + 一致性是指一个事务执行之前和执行之后都必须处于一致性状态。拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性。 + 隔离性(Isolation): +   隔离性是指多个并发事务之间要相互隔离。当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰。 + 持久性(Durability): +   持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。 +9.DQL:数据查询语言 + 基本查询语句由SELECT子句和FROM子句组成。 + SELECT:指定显示的字段名称; FROM:指定数据来源。 + (1)查询所有:SELECT * FROM 表名; + (2)查询部分数据信息:SELECT field1, field2 FROM table_name where 限定条件; + 注意:SELECT可以显示字段,表达式,函数, <>是不等于。若函数名称较长,不利于查询结果的列名显示,可以起列别名。 + SELECT salary*12 "年薪" FROM userplus WHERE username='王五';--别名 + SELECT salary*12 AS "年薪" FROM userplus WHERE username='王五';--别名 + 别名不能以数字开头,若以数字或符号开头,别名需要用""括上。 +10.常用函数(单行函数):4 + (1)字符串函数:13 + CONCAT(c1,c2),连接字符串,将c1,c2两个字段拼接显示。例如:SELECT CONCAT(CONCAT(ename, ': ') ,sal)from EMP; + ||连接多个字符串符号。例如:SELECT ename||': '||sal as "姓名:工资" from EMP; + LENGTH(ch):显示字符串长度, 例如:SELECT LENGTH(ename) from EMP; + UPPER(字段名):转大写 + LOWER(字段名): 转小写 + INITCAP(字段名): 只有首字母大写 + TRIM():去除字符串前后指定内容。例如(右侧写字符串):SELECT TRIM('E' from 'EEHELLO WORLDEEE') from dual; SELECT ename, trim('A' FROM ename) from emp; --去除员工名字前后的'A' + LTRIM('',''):去除字符回串左侧指定内容。例如(左侧写字符串):SELECT LTRIM('EEHELLO WORLDEEE', 'E') from dual; + RTRIM('',''):去除字符串右侧指定内容。 + LPAD(ch1, m, ch2): 左补位函数,ch1是要查询显示的内容,m指定位数,数据位数不足时由ch2进行补位。在emp表中使用左补位,将sql用0补齐6位。例如:select ename, LPAD(sal, 6, 0) AS salary from emp + RPAD(ch1, m, ch2): 右补位函数。 + SUBSTR(ch,m,n):截取字符串,截取ch这个字符串,从m开始截取,共截取n个,若m为负数,则是从后向前进行下标查询,从而进行截取。 + INSTR(ch1,ch2,m,n):查找ch1中ch2出现的位置,m代表从哪个位置开始检索,n代表第几次出现,不指定m和n,默认值都是1。下标从1开始,无匹配数据的时候返回0. + (2)数字函数:5 + ROUND(n,m):用于四舍五入,参数中的n可以是任何数字(要被处理的数字);m必须是整数,m取整数则四舍五入到小数点后第m位,m取0则四舍五入到整数位(m缺省,默认是0),m取负数则四舍五入到小数点前m位。 + TRUNC(n,m):截取数字没有四舍五入 + MOD(m,n):返回m除以n后的余数,n为0则直接返回m。 + CEIL(n):向上取整,大于该数的最小整数。 + FLOOR(n):向下取整,小于该数的最大整数。 + (3)日期函数:11 + sysdate:返回当前的系统时间,精确到秒。 + systimestamp:时间戳,返回当前系统日期和时间,精确到毫秒。 + (1)TO_DATE():日期转换函数,相当于Java中的SimpleDateFormat的parse()方法,将给定的字符串按照给定的日期格式转换为Date。 + select to_date('2018-12-01 11:30','YYYY-MM-DD HH:MI:SS') from dual; + select to_date('2018-12-01 13:30','YYYY-MM-DD HH24:MI:SS') from dual; + (2)TO_CHAR():用于将DATE按照给定的日期格式转换为字符串。 + select ename, to_char(hiredate,'YYYY-MM-DD HH:MI:SS') from emp; + select ename, to_char(hiredate,'YYYY"年"MM"月"DD"日"') from emp; + (3)LAST_DAY(date):返回指定日期所在月的最后一天。 + (4)ADD_MONTHS(date,i):返回日期date加上i个月后的日期值,若i是负数,则获得的是减去i个月后的日期值。 + (5)MONTHS_BETWEEN(date1,date2):计算两个日期之间相差多少个月;若date2时间比date1时间晚,会得到负值,除非两个日期间隔是整数月,否则会得到带小数位的结果。 + (6)date日期类型在数据库中可以进行减法操作,结果是相差的天数:select ename, sysdate-hiredate from emp; + (7)LEAST(date1,date2):显示两个时间中的最小值。参数类型必须一致。 + (8)GREATEST(date1,date2):显示两个时间中的最大值。参数类型必须一致。 + (9)EXTRACT(date from datetime):从参数datetime中提取参数date指定的数据,比如提取:年、月、日。 + (4)空值函数:2 + null的含义:有时表中的某些字段值数据未知或暂时不存在,取值null。在Java中引用类型的默认值为null,在sql中,任何数据类型均可取值为null。 + null条件查询:不等于任何值, is null 和 is not null. + NVL(arg1,arg2):将null转变为非null值。如果arg1为null,返回arg2;否则返回本身。arg1和arg2可以是任何参数类型,但两个参数的数据类型必须是一致的。 + NVL2(arg,res1,res2):如果arg为null,则返回res2,arg不为null则返回res1. +11.基本查询语句 + (1)from子句:select * from table_name;select用于指定要查询的列,from指定要从哪个表中查询。 + (2)where子句:在select语句中可以在where子句中使用比较操作符限制查询结果。 +12.查询条件 + (1)比较运算符:>,<,>=,<=,<>,= + (2)关键字:AND(并且),OR(或),AND优先级高于OR,可以使用()来提高OR的优先级顺序。 + (3)模糊查询 + LIKE:可以模糊匹配字符串; + _代表任意一个字符,%代表任意0~n个字符。 + (4)IN和NOT IN: + IN(list):取出列表范围中的数据。 + NOT IN(list):取出不符合此列表中的数据记录。 + (5)BETWEEN...AND...:是用来查询符合某个值域范围条件的数据。 + (6)ALL和ANY: ALL和ANY不能单独使用,需要配合单行比较操作符(>,<,>=,<=,<>,=)一起使用。 + >ANY:大于最小 + ALL:大于最大 + , <, >=, <=, <>, !=, is null(is not null), between...and..., in; + 逻辑运算符not, and, or + BETWEEN...AND...和AND的区别: + BETWEEN...AND...:只能用来比较一个字段值 + AND:可以用来比较不同的字段 +14.ORDER BY:排序,对结果集的排序,必须出现在select的最后一个子句。 + asc或不写:升序;desc:降序。若排序的字段中包含null,则看作是最大值。 + 当以多列作为排序标准时,首先按照第一列进行排序,如果第一列数据相同,再以第二列排序,以此类推。 +15.聚合函数(多行函数,分组函数) + (1)MAX和MIN:用来取得列或表达式的最大、最小值。可以用来统计任何数据类型,包括数字、字符和日期。忽略NULL值。 + (2)AVG和SUM:用来统计列或表达式的平均值和总和,只能操作数字类型,忽略NULL值。 + (3)COUNT:用来计算表中的记录条数。忽略NULL值。 + (4)聚合函数对NULL值的处理:聚合函数忽略NULL值,select count(comm),avg(comm) from emp;--自动忽略comm为null的记录; + 如果不希望忽略NULL值,则需要使用NVL或NVL2:select count(nvl(comm,0)), avg(nvl(comm,0)) from emp; +16.GROUP BY:分组。将结果集按照指定字段进行分组。分组规则:该字段下的值一样的记录被看做一组。 + 如果select里面出现了聚合函数,同时又出现了某一字段时,那么该字段必须出现在group by子句中。 + where后面不能使用聚合函数,因为where是非分组函数的过滤判断。select max(sal),deptno from emp where max(sal)>4000 group by deptno;--不能执行 + HAVING:是分组(聚合)函数的过滤判断;必须跟在GROUP BY之后,不能单独存在;用来对分组后的结果进一步限制;比如按部门分组后,得到每个部门的最高工资,可以继续限制输出结果。 + 查询部门中最大工资超过4000的部门以及最大工资:select max(sal),deptno from emp group by deptno having max(sal)>4000; +17.SELECT语句执行过程: + (1)通过FROM子句中找到需要查询的表。 + (2)通过WHERE进行非分组函数的筛选判断。 + (3)通过GROUP BY子句完成分组操作。 + (4)通过HAVING子句完成组函数筛选判断。 + (5)通过SELECT子句选择要显示的列或表达式及组函数。 + (6)通过ORDER BY子句进行排序操作。 +18.函数总结 + 单行函数和多行函数的分类并举例说明: + 单行函数: + 字符函数13:CONCAT(c1,c2), LENGTH(ch), UPPER(字段名), LOWER(字段名), INITCAP(字段名), TRIM('e'FROM'ee'), LTRIM('ee','e'), RTRIM('ee','e'), LPAD(ch1, m, ch2), RPAD(ch1, m, ch2), SUBSTR(ch,m,n), INSTR(ch1,ch2,m,n) + 数值函数5:ROUND(n,m), TRUNC(n,m), MOD(m,n), CEIL(n), FLOOR(n) + 日期函数9:sysdate, systimestamp, LAST_DATE(date), ADD_MONTHS(date,i), MONTHS_BETWEEN(date1,date2), LEAST(date1,date2), GREATEST(date1,date2), EXTRACT(date from datetime) + 转换函数: + 显示转换:TO_DATE(), TO_CHAR() + 隐式转换:其它类型与字符串连接通常会转换为字符串。 + 通用函数2:NVL(), NVL2() + 注意:通常用于操作单行数据,可以任意嵌套多层,多层时由内向外依次执行。 + 多行函数(聚合函数)5:MAX()最大值, MIN()最小值, SUM()求和, AVG()平均值, COUNT()统计 +19.关联查询: + (1)概念:实际应用中所需要的数据,经常会需要查询两个或两个以上的表,这种查询叫做连接查询,连接查询通常建立存在相互关系的父子关系。 + (2)外键:保存另一张表主键的列称为外键。含有外键的表,在关联关系中属于多的一方。 + (3)表与表之间的关系:一对多(外键),多对多(通过第三张表建立关系),一对一。 + (4)N张表的关联查询最少需要(N-1)个连接条件;等值连接:外键=主键;若不指定连接条件,会出现笛卡尔积(指做关联操作的每个表的每一行和其它表的每一行做组合,是无意义的结果集)。 + (5)总结: + 可以给表起别名,通过别名指定字段属于哪个表;若两个表字段名称相同则必须指明数据来源。 + 只有满足连接条件的结果,才会被查询出来。(比如deptno40里没有人,因此不会被显示出来)。 + 若有过滤条件,需同时满足连接条件和过滤条件的数据才会被查询出来。 +20.连接种类: + ?内连接:返回所有满足连接条件的记录,功能上和等值连接没有区别,只是写法不同。 + 语法:表1 INNER JOIN 表2 ON 连接条件;(INNER可以省略) + 外连接:返回满足连接条件的数据记录,有些情况下需要返回那些不满足连接条件的记录,需要使用外连接。将满足和不满足连接条件的结果全部查询出来。 + create table empc as select * from emp;--快速从一个表中复制数据 + insert into empc(empno, ename, deptno)values(1000,'JACK',50); + 左外连接:(左表的全部,右表的部分)根据左表的记录,在被连接的右表中找出符合条件的记录与之匹配,如果找不到与左表匹配的用null表示。 + 语法:表1 LEFT OUTER JOIN 表2 ON 连接条件;(OUTER可以省略) + 右外连接:(右表的全部,左表的部分)根据右表的记录,在被连接的左表中找出符合条件的记录与之匹配,如果找不到与右表匹配的用null表示。 + 语法:表1 RIGHT OUTER JOIN 表2 ON 连接条件;(OUTER可以省略) + 全外连接:返回符合条件的所有表的记录,没有与之匹配的,用null表示(结果是左连接和右连接的并集)。 + 语法:表1 FULL OUTER JOIN 表2 ON 连接条件;(OUTER可以省略) + ?自连接:连接的两个表都是同一个表,表中的一个字段可以对应当前表的其它字段。 + Oracle数据库自带语法: + (1)笛卡儿积: + (2)内连接:a.等值连接 + b.非等值连接:输出员工编号、姓名、工资、工资等级:select e.empno, e.ename, e.sal, s.grade from emp e, salgrade s where e.sal between s.losal and s.hisal; + c.左外连接:select empno, ename, dname from emp e, dept d where e.deptno=d.deptno(+);--查询员工的编号,姓名,部门名称,包括不属于任何部门的员工。 + d.右外连接:select empno, ename, dname from emp e, dept d where e.deptno(+)=d.deptno;--查询员工的编号,姓名,部门名称,包括没有员工的部门。 + e.自连接: + 通用标准的SQL99语法: + (1)交叉连接:交叉连接和笛卡尔积的连接模式相同,都是表1中的每一行都与表2中的所有行建立一次连接。select * from emp cross join dept; + (2)自然连接:select * from emp natural join dept;--若能够匹配到等值条件(外键约束或相同的列),那么就是等值连接的结果.根据dept进行等值连接。 + select * from emp natural join salgrade;--若不能匹配到等值条件,那么结果就是交叉连接。 + (3)左外连接:left outer join + (4)右外连接:right outer join + (5)全外连接:full outer join +21.子查询: + 为了给查询提供数据而首先执行的查询语句叫做子查询。子查询是嵌入在其它SQL语句中的SELECT语句。子查询嵌入的语句称作主查询或父查询。 + 注意事项: + (1)子查询需要写在括号中。 + (2)子查询需要写在运算符的右端。 + (3)子查询可以写在WHERE,HAVING,FROM子句中。 + (4)子查询中通常不写ORDER BY。 + 子查询在WHERE子句中:根据返回结果的不同,子查询分为单行子查询,多行子查询及多列子查询。 + (1)单行子查询:返回一行一列数据,要求使用单行操作符(>,>=,<,<=,<>,=) + (2)多行子查询:返回多行数据,使用多行操作符(in,all,any) + (3)多列子查询: 通常用于建立在二次查询,常出现在FROM子句中。 + 统计低于自己工资低于所在部门平均工资的员工信息: + a.分组统计部门平均工资:select avg(sal) aa, deptno from emp group by deptno + b.员工工资小于<部门平均工资:select sal, ename, e.deptno from emp e, (select avg(sal) aa, deptno from emp group by deptno) t where e.deptno=t.deptno and e.sal=6; + 页码:page,每页最多pageSize为5,第一页1~5,第二页6~10,第三页11~15. start=(page-1)pageSize+1; end=pageSize*page; +23.DECODE函数 + DECODE(参数1,值1,结果1,值2,结果2...[,默认值]);用参数依次去和值匹配,匹配到了则显示相应的结果;无匹配则显示默认值,默认值不存在则显示null(相当于Java中的switch)。 + --查询职员表,根据职员的职位计算奖励金额,当职位分别是'MANAGER','SALESMAN','ANALYST'时,奖励金分别是薪水的1.2,1.1,1.05倍,其它为原本的薪水值。 + select ename, job, sal, decode(job,'MANAGER',sal*1.2,'SALESMAN',sal*1.1,'ANALYST',sal*1.05,sal) "奖金" from emp; + select * from emp order by decode(job,'MANAGER','1','SALESMAN','2','ANALYST','3');--自定义排序 +24.集合函数 + (1)UNION并集:将两个查询结果进行排序。union(忽略重复数据,并排序), union all(不忽略重复数据,不排序); + select * from emp where sal>1500 union select * from emp where deptno=20;--并集之后,总共9条记录 + (2)INTERSECT交集:同时存在于两个结果集中的数据。 + (3)MINUS差集:两个结果相减。 + (4)使用集合函数的原因:所有的查询结果可能不是来自同一张表,并且表与表之间无关联。 + (5)注意事项:a.对应的列的类型需要匹配。 + b.列的类型要按照顺序写。 + c.列的数量要一致,如果不一致时,用null去补充不匹配的列。 +25.DDL语句管理表: + (1)创建表空间:逻辑单位,通常我们新建一个项目,就会新创建表空间,在表空间中创建用户来创建表。 + 先切换到system,语法:CREATE tablespace 表空间名称 datafile '文件的路径' size 大小 autoextend on 自动拓展 next 每次扩展的大小; + (2)删除表空间:drop tablespace 表空间名称 + (3)创建用户:create user 用户名 identified by 密码 default tablespace 表空间的名称; + (4)删除用户:drop user 用户名 cascade; + (5)更改用户密码:alter user 用户名 identified by 密码; + (6)授权:grant connect to 用户名; + (7)分配角色:grant dba to 用户名; + (8)使用子查询的方式创建表(切换完了新创建的用户之后): + 只复制表结构和表数据,不会复制列的约束:create table emp as select * from scott.emp;-- + 如果查询语句有结果,就是复制表结构和数据,如果没有结果,就是复制表结构:create table dept as select * from scott.dept where 1=2;--只复制表结构,无数据,因为1=2为false。 + 只复制表数据(添加语句里可以没有values关键字):insert into 表名 查询语句 (表的结构与已有表结构一致):insert into dept select * from scott.dept; +26.列的约束:约束主要是用来约束表中数据的规则。 + 主键约束:primary key 不能为空,必须唯一。 + 非空约束:not null + 唯一约束:unique + 检查约束:check(条件) 在MySql中是可以写的,但MySql会直接忽略检查。price number(10,2) check(price>100),--检查约束,在创建表的时候直接写(和primary key, not null, unique一个位置或之后) + 外键约束:主要是用来约束从表A中的记录必须是存在于主表B中(保证数据完整性)。 + (1)references 外表名(外表的列名), --在创建表的时候直接写(和primary key, not null, unique, check一个位置或之后) + (2)foreign key(自己的列名) references 外表名(外表的列名)--另一种外键约束的方式,写在最后一个括号的前面 + (3)alter table books add foreign key(cid) references category(id);--可以不在定义表中建立外键约束,单独用此语句也可实现外键约束。 +27.视图:数据库对象之一,视图在sql语句中体现的角色和表完全相同,但视图并不是一个真实存在的表,它对应的是一个查询语句的结果集(视图名和表名不能一样)。 + 作用:简化复杂查询,可以限制数据访问。 + (1)创建简单视图(单表):若无权限,使用system用户授权,视图授权语句:grant create view to 用户名。 + create view v_emp_10 as select empno,ename,sal,deptno from emp where deptno=10; + (2)修改视图就是替换该视图的子查询,使用create or replace view 视图名 即可,若视图不存在就创建,存在就替换。创建视图时,可以给列赋予别名。 + create or replace view v_emp_10 as select empno id,ename name,sal,deptno from emp where deptno=10; + (3)查询视图:列名若有别名,以别名为准,不是原列名。select * from v_emp_10; + (4)视图的DML操作(不建议):对视图进行DML操作就是对视图数据来源的基础表进行操作。 + a.插入数据:视图中看不见的字段都被插入默认值,所以不能违反基础表中相应字段的约束(比如看不见的字段的not null等约束,否则会插入失败)。 + b.为视图添加检查选项可以避免对视图进行DML操作时污染基础表的情况,在创建语句后加with check option + create or replace view v_emp_10 as select empno id,ename name,sal,deptno from emp where deptno=10 with check option;--不能对基础表中deptno10以外的数据进行DML操作。 + c.with read only:只读,不能对视图进行DML操作。如果没有在视图上执行DML操作的必要,在建立视图时声明为只读来避免这种情况,保证视图对应的基础表数据不会被非法修改。 + create or replace view v_emp_10 as select empno,ename,sal,deptno from emp where deptno=10 with read only;--with read only只读,不能对视图进行DML操作。 + (5)视图根据子查询的不同,分为简单视图和复杂视图,当子查询中包含单行函数、表达式或分组函数时,该视图是一个复杂视图。复杂视图不能进行DML操作,并且必须被子查询中的表达式或函数定义别名。 + (6)删除视图:DROP VIEW 视图名称。 +28.序列:sequence是用来生成唯一数字值的数据库对象,通常作为表的主键值。序列是独立的数据库对象,序列并不依附于表。 + (1)创建序列:create sequence 序列名 [start with **(起始数据) increment by **(步长,每次增加几,可正可负) maxvalue **(最大值) / minvalue **(最小值)]; + (2)序列中有两个伪列:nextval/*获取序列的下个值*/ ,currval/*获取序列的当前值*/ + 当序列创建以后必须先执行nextval,之后才能使用currval。获取序列的第一个值,并使用序列值为users表插入新的记录。 + select users_seq.currval from dual;--查看当前序列值。 + (3)删除序列:drop sequence users_seq; + (4)例子: + create sequence users_seq start with 100 increment by 10;--建立序列,第一次一定要用nextval,不能用currval + insert into users(id,name)values(users_seq.nextval,'Tony');--插入基表 + select users_seq.currval from dual;--查看当前序列值。 + drop sequence users_seq;--删除序列 + +29.索引:一种提高查询效率的机制(类似于字典的目录),经常作为过滤条件、去重、排序或链接条件的字段,可以为其添加索引。 + ?(1)创建索引:create [unique] index 索引名称 on 表名(列名) + create index idx_users_name on users(ename);--在users表的ename列上建立索引 + (2)添加多列索引:create index idx_users_salary on users(name,salary); + (3)查询过程中自动应用索引,不需要单独去制定,提高查询速度。 + select users.* from users order by name, salary; + (4)重构索引(索引是平衡二叉树,修改表后,最好重构一下索引的平衡二叉树) + alter index 索引名称 rebuild;--经常修改数据的表,不建议建立索引。 + (5)删除索引:drop index idx_users_salary; \ No newline at end of file diff --git a/JDBC/bin/note/sql/SQLPractice.sql b/JDBC/bin/note/sql/SQLPractice.sql new file mode 100644 index 0000000..ad16146 --- /dev/null +++ b/JDBC/bin/note/sql/SQLPractice.sql @@ -0,0 +1,233 @@ +1~10 homework: +--1、向USERS表中插入性别字段,并指定默认值为男 +alter table userplus add(sex char(2) default '男'); +--2、删除名字是张三的人的信息 +delete from userplus where username='张三'; +--3、查询USERS表中用户的姓名 +select username from userplus; +--4、查询每个用户的工资是多少 +select username, salary from userplus; +--5、查看阿三的工资 +select salary from userplus where username='阿三'; +--6、查询每个用户的年薪 +select salary*12 as "年薪" from userplus; +--7、查询用户工资大于2000的用户信息 +select * from userplus where salary > 2000; +--8、将 姓名 工资 连接显示 +select username||': '||salary as "姓名:工资" from userplus; +--9、查询USERS表中每个用户的名字长度 +select username,length(username) from userplus; +--10、查询名字3位以上的用户编号、姓名、工资、工作 +select id, username, salary, job from userplus where length(username)>=3; + +10~12 homework: +--1、请查询表DEPT中所有部门的情况。 +select * from dept; +--2、查询表DEPT中的部门号、部门名称两个字段的所有信息。 +select deptno, dname from dept; +--3、请从表EMP中查询10号部门工作的雇员姓名和工资。 +select ename, sal from emp where deptno=10; +--4、请从表EMP中查找工种是职员CLERK或经理MANAGER的雇员姓名、工资。 +select ename, sal from emp where job in ('CLERK','MANAGER'); +--5、请在EMP表中查找部门号在10-30之间的雇员的姓名、部门号、工资、工作。 +select ename, deptno, sal, job from emp where deptno between 10 and 30; +--6、请从表EMP中查找姓名以J开头所有雇员的姓名、工资、职位。 +select ename, sal, job from emp where ename like 'J%'; +--7、请从表EMP中查找工资低于2000的雇员的姓名、工作、工资,并按工资降序排列。 +select ename, job, sal from emp where sal<2000 order by sal desc; +--8、在表EMP中查询所有工资高于JONES的所有雇员姓名、工作和工资。 +select ename, job, sal from emp where sal>(select sal from emp where ename='JONES'); +--9、列出没有对应部门表信息的所有雇员的姓名、工作以及部门号。 +select ename, job, deptno from emp where deptno not in(select deptno from dept); +--10、查找工资在1000~3000之间的雇员所在部门的所有人员信息 +select * from emp where deptno in (select distinct deptno from emp where sal between 1000 and 3000); +--11、查询所有雇员的姓名、SAL与COMM之和。 +select ename, sal, comm, NVL2(comm,comm+sal,sal) from emp; +--12、查询所有在CHICAGO工作的经理MANAGER和销售员SALESMAN的姓名、工资 +select ename, sal from emp where deptno=(select deptno from dept where loc='CHICAGO') and job in('MANAGER','SALESMAN'); +select a.ename, a.sal from emp a, dept b where a.deptno=b.deptno and b.loc='CHICAGO' and a.job in('MANAGER','SALESMAN'); +--13、查询显示每个雇员加入公司的准确时间,按××××年××月××日 时分秒显示。 +select ename, to_char(hiredate,'YYYY"年"MM"月"DD"日" HH:MI:SS') from emp; + +13~18 homework: +select * from dept +select * from emp +--1.列出至少有一个员工的所有部门。 +select deptno from emp group by deptno having count(empno)>=1; +--2.列出薪金比“SMITH”多的所有员工。 +select * from emp where sal>(select sal from emp where ename='SMITH'); +--3.列出最低薪金大于1500的各种工作。 +select distinct(job) from emp group by job having min(sal)>1500; +--4.查询部门20,30 中的岗位不是"CLERK"或"SALESMAN"的所有员工信息 +select * from emp where deptno in (20,30) and job not in('CLERK','SALESMAN'); +--5.查询比平均员工工资高的员工信息 +select * from emp where sal > (select avg(sal) from emp); +--6.找出部门10中所有经理和部门20中所有办事员的详细资料。 +select * from emp where (deptno=10 and job='MANAGER') or (deptno=20 and job='CLERK'); +--7.显示不带有“R”的雇员姓名。 +select ename from emp where ename not like '%R%'; +--8.显示雇员姓名,根据其服务年限,将最老的雇员排在最前面。 +select ename, hiredate from emp order by hiredate asc; +--9.对于每个雇员,显示其加入公司的天数 +select ename, trunc(sysdate-hiredate+1) as "天数" from emp; +--10.查询各个职位的平均工资是多少? +select job, avg(sal) from emp group by job; +--11.查看每个部门有多少人 +select deptno, count(*) from emp group by deptno; +--12.查看每个职位的平均工资与工资总和 +select job, avg(sal),sum(sal) from emp group by job; +--13.查出emp表中所有部门的最高薪水和最低薪水,部门编号为10的部门不显示。 +select deptno, max(sal), min(sal) from emp where deptno<>10 group by deptno; +--14.查询出名字中有“A”字符,并且薪水在1000以上(不包括1000)的所有员工信息。 +select * from emp where ename like '%A%' and sal>1000; +--15.显示薪水最高人的职位。 +select job from emp where sal=(select max(sal) from emp); +select job from emp where sal>=all(select sal from emp); +--16.列出所有员工的年工资,按年薪从低到高排序。 +select ename, sal*12 as "年薪" from emp order by sal; + +19~21 homework: +select * from emp; +select * from salgrade; +--1.显示员工表中的不重复的岗位job +select distinct(job) from emp; +--2.查询10部门工资大于3000的员工信息,要求按员工的入职时间由前到后排序 +select * from emp where deptno=10 and sal>3000 order by hiredate; +--3.列出各个部门的MANAGER 的最低薪金 +select deptno,min(sal) from emp where job='MANAGER' group by deptno; +--4.查询所有员工的工作地点,包括没有员工的地点也要显示 +select ename,loc from dept d left outer join emp e on d.deptno=e.deptno; +--5.查询所有的员工信息和部门名称,包括不属于任何部门的员工 +select empno, ename, dname, e.deptno from emp e left outer join dept d on e.deptno=d.deptno; +--6.列出和"SCOTT"从事相同工作的所有员工及部门名称 +select empno, ename, job, dname from emp e,dept d where e.deptno=d.deptno and job=(select job from emp where ename='SCOTT'); +--7.列出受雇日期早于直接上级的所有员工的编号,姓名,部门名称 +select empno, ename, e.deptno, dname from emp e,dept d where e.deptno=d.deptno and hiredate<(select hiredate from emp m where e.mgr=m.empno); +--8.列出职位为“CLERK”的员工姓名和其所在部门名称,部门人数 +select ename, dname, t.b from emp e, dept d, (select deptno,count(*) b from emp group by deptno) t where e.deptno=d.deptno and e.deptno=t.deptno and job='CLERK'; +--9.查询至少有4个员工的部门的部门名称 +select e.deptno, count(*),dname from emp e, dept d where e.deptno=d.deptno group by e.deptno,dname having count(*)>4; +select d.dname from dept d where deptno in (select deptno from emp group by deptno having count(*)>4); + --自己写的 +select d.deptno, d.dname, t.count from emp e, dept d, (select count(*) count from emp a group by deptno) t where e.deptno=d.deptno and t.count>4; +--10.查询工资高于30号部门的所有员工的工资的员工姓名、工资及部门名称 +select ename, sal, e.deptno, dname from emp e,dept d where sal>(select max(sal) from emp where deptno=30); +--11.查询出“KING”所在部门的部门编号、部门名称以及该部门里的员工人数 +select e.deptno, dname, count(*) from emp e,dept d where e.deptno=d.deptno and e.deptno=( select deptno from emp where ename='KING') group by e.deptno,dname; + --自己写的,不太好: +select e.deptno, dname, e.deptno,(select count(*) count from emp where deptno= (select deptno from emp where ename='KING')) from emp e, dept d where e.deptno=d.deptno and ename='KING'; +--12.查询平均工资最高的部门的部门编号、部门名称和该部门的平均工资 +select e.deptno, d.dname, avg(sal) from emp e, dept d where e.deptno=d.deptno group by e.deptno,d.dname having avg(sal)>=all(select avg(sal) from emp group by deptno); + --自己写的 +select deptno from emp group by deptno having avg(sal)>=all(select avg(sal) from emp group by deptno); +--13.工资等级为2等级的 员工信息及其所在部门的信息 +select * from emp e,dept d, salgrade s where e.deptno=d.deptno and s.grade=2 and e.sal between s.losal and s.hisal; + --自己写的 +select e.ename, e.sal from emp e,dept d, (select losal, hisal from salgrade where grade=2) t where e.deptno=d.deptno and e.sal between t.losal and t.hisal; +--14.10号部门的部门信息 人员信息 工资等级 +select d.*,e.*,s.grade from emp e,dept d, salgrade s where e.deptno=d.deptno and e.deptno=10 and e.sal between s.losal and s.hisal; + --自己写的 +select ename, sal, (select t.grade from salgrade t where e.sal between t.losal and t.hisal) grade from emp e where deptno=10; +--15.查询最高领导者的薪水等级 +select grade from salgrade where (select sal from emp where mgr is null) between losal and hisal + --自己写的 +select ename, sal, (select t.grade from salgrade t where e.sal between t.losal and t.hisal) grade from emp e where mgr is null; +--16.SQL语句的执行过程及其每条子句的作用? +FROM,WHERE,GROUP BY,HAVING,SELECT,ORDER BY +--17.数据库的运算符类型及优先级? +();算术运算符*,/,+,-;连接符||;比较运算符=, >, <, >=, <=, <>, !=, is null(is not null), between...and..., in;逻辑运算符not, and, or +--18.数据库的函数分类? +DDL,DML,TCL,DQL,DCL +字符,数值,日期,转换 +--19.事务的四个特性 +原子性 +一致性 +隔离性 +持久性 + +--小总结: +--SQL语句的执行过程及其每条子句的作用? +(1)通过FROM子句中找到需要查询的表。 +(2)通过WHERE进行非分组函数的筛选判断。 +(3)通过GROUP BY子句完成分组操作。 +(4)通过HAVING子句完成组函数筛选判断。 +(5)通过SELECT子句选择要显示的列或表达式及组函数。 +(6)通过ORDER BY子句进行排序操作。 + +--数据库的运算符类型及优先级? +(); +算术运算符*,/,+,-; +连接符||; +比较运算符=, >, <, >=, <=, <>, !=, is null(is not null), between...and..., in; +逻辑运算符not, and, or + +--数据库的函数分类? +单行函数:CONCAT(c1,c2), LENGTH(ch), UPPER(字段名), LOWER(字段名), INITCAP(字段名), TRIM('e'FROM'ee'), LTRIM('ee','e'), RTRIM('ee','e'), LPAD(ch1, m, ch2), RPAD(ch1, m, ch2), SUBSTR(ch,m,n), INSTR(ch1,ch2,m,n) +数值函数:ROUND(n,m), TRUNC(n,m), MOD(m,n), CEIL(n), FLOOR(n) +日期函数:sysdate, systimestamp, LAST_DATE(date), ADD_MONTHS(date,i), MONTHS_BETWEEN(date1,date2), LEAST(date1,date2), GREATEST(date1,date2), EXTRACT(date from datetime)聚合函数:count(),avg(),sum(),max(),min(), +转换函数: + 显示转换:TO_DATE(), TO_CHAR() + 隐式转换:其它类型与字符串连接通常会转换为字符串。 +通用函数:NVL(), NVL2() +多行函数(聚合函数):MAX()最大值, MIN()最小值, SUM()求和, AVG()平均值, COUNT()统计 + +--结构化查询语言分类和作用? +SQL分类: + DDL:数据定义语言,用于操作数据对象(表,视图,序列,索引)。 + CREATE:创建表或其它对象。 + ALTER:修改表或其它对象结构。 + DROP:删除表或其它对象。 + TRUNCATE:删除表数据,保留表结构。清空表的操作。 + DML:数据操作语言(通常需要伴随TCL),用于增删改表中的数据。 + INSERT INTO:将数据插入表中。 + DELETE:删除表中数据。 + UPDATE SET:更新表中数据。 + TCL:事务控制语言。 + COMMIT:提交。 + ROLLBACK:回滚。 + DQL:数据查询语言 + SELECT:查询数据。 + DCL:数据控制语言。 + GRANT:授予权限。 + grant…create…view…to…scott; + +--事务的特性? +原子性(Atomicity): +  原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚。因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。 +一致性(Consistency): + 一致性是指一个事务执行之前和执行之后都必须处于一致性状态。拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性。 +隔离性(Isolation): +  隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。 +持久性(Durability): +  持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。 + +--Oracle数据库自带语法和通用标准的SQL99语法? +Oracle数据库自带语法: + (1)笛卡儿积: + (2)内连接:a.等值连接 + b.非等值连接:输出员工编号、姓名、工资、工资等级:select e.empno, e.ename, e.sal, s.grade from emp e, salgrade s where e.sal between s.losal and s.hisal; + c.左外连接:select empno, ename, dname from emp e, dept d where e.deptno=d.deptno(+);--查询员工的编号,姓名,部门名称,包括不属于任何部门的员工。 + d.右外连接:select empno, ename, dname from emp e, dept d where e.deptno(+)=d.deptno;--查询员工的编号,姓名,部门名称,包括没有员工的部门。 + e.自连接: +通用标准的SQL99语法: + (1)交叉连接:交叉连接和笛卡尔积的连接模式相同,都是表1中的每一行都与表2中的所有行建立一次连接。select * from emp cross join dept; + (2)自然连接:select * from emp natural join dept;--若能够匹配到等值条件(外键约束或相同的列),那么就是等值连接的结果.根据dept进行等值连接。 + select * from emp natural join salgrade;--若不能匹配到等值条件,那么结果就是交叉连接。 + (3)左外连接:left outer join + (4)右外连接:right outer join + (5)全外连接:full outer join + +--数据中的约束? +主键约束:primary key 不能为空,必须唯一。 +非空约束:not null +唯一约束:unique +检查约束:check(条件) 在MySql中是可以写的,但MySql会直接忽略检查。price number(10,2) check(price>100),--检查约束,在创建表的时候直接写(和primary key, not null, unique一个位置或之后) +外键约束:主要是用来约束从表A中的记录必须是存在于主表B中(保证数据完整性)。 + (1)references 外表名(外表的列名), --在创建表的时候直接写(和primary key, not null, unique, check一个位置或之后) + (2)foreign key(自己的列名) references 外表名(外表的列名)--另一种外键约束的方式,写在最后一个括号的前面 + (3)alter table books add foreign key(cid) references category(id);--可以不在定义表中建立外键约束,单独用此语句也可实现外键约束。 + +--用一条sql语句查出emp表中工资从大到小排在4,5,6位工资? +select * from (select rownum rn, e.* +from (select ename, sal from emp order by sal desc) e where rownum<=6)t +where t.rn >=4; \ No newline at end of file diff --git "a/JDBC/bin/note/sql/\345\244\232\350\241\250\346\237\245\350\257\242\347\273\203\344\271\240\357\274\210\347\255\224\346\241\210\357\274\211.txt" "b/JDBC/bin/note/sql/\345\244\232\350\241\250\346\237\245\350\257\242\347\273\203\344\271\240\357\274\210\347\255\224\346\241\210\357\274\211.txt" new file mode 100644 index 0000000..ca083df --- /dev/null +++ "b/JDBC/bin/note/sql/\345\244\232\350\241\250\346\237\245\350\257\242\347\273\203\344\271\240\357\274\210\347\255\224\346\241\210\357\274\211.txt" @@ -0,0 +1,97 @@ +锘1.鍒楀嚭閮ㄩ棬鍚嶇О鍜岃繖浜涢儴闂ㄧ殑鍛樺伐淇℃伅锛屽悓鏃跺垪鍑洪偅浜涙病鏈夊憳宸ョ殑閮ㄩ棬 +select dept.dname,emp.* from dept +left outer join emp +on dept.deptno=emp.deptno; + +2.鍒楀嚭鍦ㄦ瘡涓儴闂ㄥ伐浣滅殑鍛樺伐鏁伴噺銆佸钩鍧囧伐璧勩 +select dept.deptno,count(emp.empno),avg(sal) +from dept +left outer join emp +on dept.deptno=emp.deptno +group by dept.deptno; + +3.鍒楀嚭鎵鏈夊憳宸ョ殑濮撳悕銆侀儴闂ㄥ悕绉板拰宸ヨ祫銆 +select emp.ename, dept.dname,emp.sal +from emp, dept +where emp.deptno=dept.deptno; + +4.鏌ヨ姣忎釜閮ㄩ棬鐨勯儴闂ㄧ紪鍙凤紝閮ㄩ棬鍚嶇О锛岄儴闂ㄤ汉鏁帮紝鏈楂樺伐璧勶紝鏈浣庡伐璧勶紝宸ヨ祫鎬诲拰锛屽钩鍧囧伐璧 +select d.deptno,d.dname,count(e.ename), +max(e.sal),min(e.sal),sum(sal),avg(sal) +from dept d join emp e on e.deptno=d.deptno +group by d.deptno,d.dname + +5.鏌ヨ姣忎釜缁忕悊鎵绠$悊鐨勪汉鏁帮紝缁忕悊缂栧彿锛岀粡鐞嗗鍚嶏紝瑕佹眰鍖呮嫭娌℃湁缁忕悊鐨勪汉鍛樹俊鎭 +select count(e.empno),m.empno,m.ename +from emp e +left join emp m +on e.mgr = m.empno +group by m.empno,m.ename; + +6.鏌ヨ閮ㄩ棬浜烘暟澶т簬2鐨勯儴闂ㄧ紪鍙凤紝閮ㄩ棬鍚嶇О锛岄儴闂ㄤ汉鏁 +select d.deptno,d.dname,count(e.ename) +from dept d +join emp e on d.deptno=e.deptno +group by d.dname,d.deptno +having(count(e.ename)>2); + +7.鏌ヨ閮ㄩ棬骞冲潎宸ヨ祫鍦2500鍏冧互涓婄殑閮ㄩ棬鍚嶇О鍙婂钩鍧囧伐璧勩 +select d.dname ,avg(e.sal) +from dept d +join emp e on d.deptno=e.deptno +group by d.dname +having(avg(e.sal)>2500); + +8.鏌ヨ鍛樺伐宀椾綅涓笉鏄互"SA"寮澶村苟涓斿钩鍧囧伐璧勫湪 2500鍏冧互涓婄殑宀椾綅鍙婂钩鍧囧伐璧勶紝骞舵寜骞冲潎宸ヨ祫闄嶅簭鎺掑簭銆 +select e.job,avg(e.sal) +from emp e +where e.job not like 'SA%' +group by e.job +having avg(e.sal)>2500 +order by avg(e.sal) desc + +9.鏄剧ず缁忕悊鍙风爜鍜岀粡鐞嗗鍚嶏紝杩欎釜缁忕悊鎵绠$悊鍛樺伐鐨勬渶浣庡伐璧勶紝娌℃湁缁忕悊鐨凨ING涔熻鏄剧ず锛屼笉鍖呮嫭鏈浣庡伐璧勫皬浜 +3000鐨勶紝鎸夋渶浣庡伐璧勭敱楂樺埌浣庢帓搴忋 +select m.empno,m.ename,min(e.sal) +from emp e +left join emp m +on e.mgr = m.empno +group by m.empno,m.ename +having min(e.sal)>=3000 +order by min(e.sal) desc; + +10.鏌ヨ閮ㄩ棬骞冲潎宸ヨ祫澶т簬2000锛屼笖浜烘暟澶т簬2鐨勯儴闂ㄧ紪鍙凤紝閮ㄩ棬鍚嶇О锛岄儴闂ㄤ汉鏁帮紝閮ㄩ棬骞冲潎宸ヨ祫锛屽苟鎸夌収閮ㄩ棬浜烘暟鍗囧簭鎺掑簭銆 +select d.deptno,d.dname,count(e.ename),avg(e.sal) +from dept d +join emp e on d.deptno=e.deptno +group by d.dname,d.deptno +having(count(e.ename)>2) and (avg(e.sal)>2000) +order by count(e.ename) ; + +11.鏌ヨ閮ㄩ棬鏈浣庡伐璧 楂樹簬10鍙烽儴闂 鏈浣庡伐璧勭殑閮ㄩ棬鐨勭紪鍙枫佸悕绉板強閮ㄩ棬鏈浣庡伐璧勩 +SELECT e.deptno,d.dname,MIN(e.sal) +FROM emp e,dept d +WHERE e.deptno=d.deptno +GROUP BY deptno,dname +HAVING MIN(e.sal)>(SELECT MIN(sal) from emp WHERE deptno=10) + +12.鏄剧ず30鍙烽儴闂ㄧ殑闆囧憳鎵浠庝簨鐨勪笉閲嶅鐨勫伐浣滃悕绉帮紝骞舵樉绀30閮ㄩ棬鐨勬墍鍦ㄥ湴銆 +SELECT DISTINCT e.job,d.loc +FROM emp e,dept d +WHERE e.deptno=d.deptno AND e.deptno=30; + +13.鏌ヨ宸ヤ綔鍦ㄥ箍宸炵殑鍛樺伐浜烘暟锛屾渶楂樺伐璧勫強鏈浣庡伐璧勩 +select count(*) 鍛樺伐浜烘暟, +max(e.sal) 鏈楂樺伐璧勶紝 +min(e.sal) 鏈浣庡伐璧 +from emp e, dept d +where e.deptno = d.deptno +and d.loc = '骞垮窞'; + +14.缁熻鍚勪釜閮ㄩ棬涓嶅悓鑱屽姟鐨勫憳宸ヨ柂姘寸殑鎬诲拰锛屽钩鍧囧伐璧,閮ㄩ棬缂栧彿锛岄儴闂ㄥ悕绉,閮ㄩ棬浣嶇疆锛岃亴鍔 +SELECT dept.deptno,dname,loc,JOB,sum(sal),avg(sal) +FROM emp,dept +WHERE emp.deptno=dept.deptno +GROUP BY dept.deptno,dname,loc,JOB; + + diff --git "a/JDBC/bin/note/sql/\345\244\232\350\241\250\346\237\245\350\257\242\347\273\203\344\271\240\357\274\210\350\207\252\345\267\261\357\274\211.sql" "b/JDBC/bin/note/sql/\345\244\232\350\241\250\346\237\245\350\257\242\347\273\203\344\271\240\357\274\210\350\207\252\345\267\261\357\274\211.sql" new file mode 100644 index 0000000..2c215cd --- /dev/null +++ "b/JDBC/bin/note/sql/\345\244\232\350\241\250\346\237\245\350\257\242\347\273\203\344\271\240\357\274\210\350\207\252\345\267\261\357\274\211.sql" @@ -0,0 +1,33 @@ +--1.列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门 +select dname, e.* from dept d left outer join emp e on d.deptno=e.deptno; +--2.列出在每个部门工作的员工数量、平均工资。 +select count(ename), avg(sal) from emp e right outer join dept d on d.deptno=e.deptno group by d.deptno; +--3.列出所有员工的姓名、部门名称和工资。 +select ename, dname, sal from emp e, dept d where e.deptno=d.deptno; +--4.查询每个部门的部门编号,部门名称,部门人数,最高工资,最低工资,工资总和,平均工资 +select d.deptno, dname, count(*), max(sal), min(sal), sum(sal), avg(sal) from emp e, dept d where d.deptno=e.deptno group by d.deptno, dname; +--5.查询每个经理所管理的人数,经理编号,经理姓名,要求包括没有经理的人员信息。 +select count(e.ename), m.empno,m.ename from emp e left join emp m on e.mgr=m.empno group by m.empno,m.ename +--6.查询部门人数大于2的部门编号,部门名称,部门人数 +select d.deptno, d.dname, count(*) from emp e, dept d where e.deptno=d.deptno group by d.deptno, d.dname having count(*)>2; +--7.查询部门平均工资在2500元以上的部门名称及平均工资。 +select d.dname, avg(sal) from emp e, dept d where e.deptno=d.deptno group by d.dname having avg(sal)>2500; +--8.查询员工岗位中不是以"SA"开头并且平均工资在 2500元以上的岗位及平均工资,并按平均工资降序排序。 +select job, avg(sal) from emp where job not like 'SA%' group by job having avg(sal)>2500 order by avg(sal) desc +--9.显示经理号码和经理姓名,这个经理所管理员工的最低工资,没有经理的KING也要显示, +--不包括最低工资小于3000的,按最低工资由高到低排序。 +select m.empno, m.ename, min(e.sal) from emp e left outer join emp m +on e.mgr=m.empno group by m.empno, m.ename having min(e.sal)>=3000 order by min(e.sal) desc; +--10.查询部门平均工资大于2000,且人数大于2的部门编号,部门名称,部门人数,部门平均工资,并按照部门人数升序排序。 +select d.deptno, d.dname, count(*), avg(sal) from emp e, dept d +where e.deptno=d.deptno group by d.deptno, d.dname +having count(*)>2 and avg(sal)>2000 order by count(*); +--11.查询部门最低工资 高于10号部门 最低工资的部门的编号、名称及部门最低工资。 +select d.deptno, dname, min(sal) from emp e, dept d where d.deptno=e.deptno group by d.deptno, dname +having min(sal)>(select min(sal) from emp where deptno = 10); +--12.显示30号部门的雇员所从事的不重复的工作名称,并显示30部门的所在地。 +select distinct job, d.loc from emp e, dept d where d.deptno=e.deptno and e.deptno=30; +--13.查询工作在'CHICAGO'的员工人数,最高工资及最低工资。 +select count(empno),max(sal),min(sal) from emp e, dept d where d.deptno=e.deptno and loc='CHICAGO'; +--14.统计各个部门不同职务的员工薪水的总和,平均工资,部门编号,部门名称,部门位置,职务 +select sum(sal),avg(sal),d.deptno,dname,loc, job from emp e, dept d where d.deptno=e.deptno group by d.deptno,dname,loc, job; diff --git a/JDBC/bin/project/EmpManage_JDBC/bean/Dept.class b/JDBC/bin/project/EmpManage_JDBC/bean/Dept.class new file mode 100644 index 0000000..3194607 Binary files /dev/null and b/JDBC/bin/project/EmpManage_JDBC/bean/Dept.class differ diff --git a/JDBC/bin/project/EmpManage_JDBC/bean/Emp.class b/JDBC/bin/project/EmpManage_JDBC/bean/Emp.class new file mode 100644 index 0000000..b54c3ca Binary files /dev/null and b/JDBC/bin/project/EmpManage_JDBC/bean/Emp.class differ diff --git a/JDBC/bin/project/EmpManage_JDBC/dao/EmpDao.class b/JDBC/bin/project/EmpManage_JDBC/dao/EmpDao.class new file mode 100644 index 0000000..098774f Binary files /dev/null and b/JDBC/bin/project/EmpManage_JDBC/dao/EmpDao.class differ diff --git a/JDBC/bin/project/EmpManage_JDBC/dao/impl/EmpDaoImpl.class b/JDBC/bin/project/EmpManage_JDBC/dao/impl/EmpDaoImpl.class new file mode 100644 index 0000000..39c5605 Binary files /dev/null and b/JDBC/bin/project/EmpManage_JDBC/dao/impl/EmpDaoImpl.class differ diff --git a/JDBC/bin/project/EmpManage_JDBC/test/Test.class b/JDBC/bin/project/EmpManage_JDBC/test/Test.class new file mode 100644 index 0000000..c121b49 Binary files /dev/null and b/JDBC/bin/project/EmpManage_JDBC/test/Test.class differ diff --git a/JDBC/bin/project/EmpManage_JDBC/util/DBUtil.class b/JDBC/bin/project/EmpManage_JDBC/util/DBUtil.class new file mode 100644 index 0000000..322350c Binary files /dev/null and b/JDBC/bin/project/EmpManage_JDBC/util/DBUtil.class differ diff --git a/JDBC/bin/project/carRent_JDBC/bean/Bus.class b/JDBC/bin/project/carRent_JDBC/bean/Bus.class new file mode 100644 index 0000000..cd62ddd Binary files /dev/null and b/JDBC/bin/project/carRent_JDBC/bean/Bus.class differ diff --git a/JDBC/bin/project/carRent_JDBC/bean/Car.class b/JDBC/bin/project/carRent_JDBC/bean/Car.class new file mode 100644 index 0000000..008bc86 Binary files /dev/null and b/JDBC/bin/project/carRent_JDBC/bean/Car.class differ diff --git a/JDBC/bin/project/carRent_JDBC/bean/Truck.class b/JDBC/bin/project/carRent_JDBC/bean/Truck.class new file mode 100644 index 0000000..d374fa0 Binary files /dev/null and b/JDBC/bin/project/carRent_JDBC/bean/Truck.class differ diff --git a/JDBC/bin/project/carRent_JDBC/bean/Vehicle.class b/JDBC/bin/project/carRent_JDBC/bean/Vehicle.class new file mode 100644 index 0000000..26cf782 Binary files /dev/null and b/JDBC/bin/project/carRent_JDBC/bean/Vehicle.class differ diff --git a/JDBC/bin/project/carRent_JDBC/dao/Operation.class b/JDBC/bin/project/carRent_JDBC/dao/Operation.class new file mode 100644 index 0000000..75c0afc Binary files /dev/null and b/JDBC/bin/project/carRent_JDBC/dao/Operation.class differ diff --git a/JDBC/bin/project/carRent_JDBC/dao/impl/OperationImpl.class b/JDBC/bin/project/carRent_JDBC/dao/impl/OperationImpl.class new file mode 100644 index 0000000..3c5b181 Binary files /dev/null and b/JDBC/bin/project/carRent_JDBC/dao/impl/OperationImpl.class differ diff --git a/JDBC/bin/project/carRent_JDBC/test/Test.class b/JDBC/bin/project/carRent_JDBC/test/Test.class new file mode 100644 index 0000000..ca752aa Binary files /dev/null and b/JDBC/bin/project/carRent_JDBC/test/Test.class differ diff --git a/JDBC/bin/project/carRent_JDBC/util/DBUtil.class b/JDBC/bin/project/carRent_JDBC/util/DBUtil.class new file mode 100644 index 0000000..8d7efef Binary files /dev/null and b/JDBC/bin/project/carRent_JDBC/util/DBUtil.class differ diff --git a/JDBC/src/Demo/DEMO_EmpManage_JDBC.rar b/JDBC/src/Demo/DEMO_EmpManage_JDBC.rar new file mode 100644 index 0000000..91d61df Binary files /dev/null and b/JDBC/src/Demo/DEMO_EmpManage_JDBC.rar differ diff --git a/JDBC/src/JDBC_day01/demo/JDBCDemo01.java b/JDBC/src/JDBC_day01/demo/JDBCDemo01.java new file mode 100644 index 0000000..ae3caa0 --- /dev/null +++ b/JDBC/src/JDBC_day01/demo/JDBCDemo01.java @@ -0,0 +1,149 @@ +package JDBC_day01.demo; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +import org.junit.Test; + +import oracle.jdbc.driver.OracleDriver; + +/** + * 1.什么是JDBC? + * JDBC(Java DataBase Connection)是一种用于执行SQL语句的Java的API,可以为多种关系型数据库提供统一访问,它由一组用Java语言编写的类和接口组成,是Java访问数据库的标准规范。 + * 2.JDBC入门: + * (1)导入jar包:连接数据库的驱动。 + * (2)加载驱动类:Class.forName("类名"); + * (3)创建连接:DriverManager(驱动管理器),提供一个静态方法,建立与数据库的连接,getConnection(url(连接数据库地址),username,password) + */ +public class JDBCDemo01 { + /** + * JDBC所需四个参数: + * 1.driverClassName:oracle.jdbc.driver.OracleDriver + * 2.url:连接数据库地址,jdbc:oracle:thin:@localhost:1521:orcl + * 3.username: zicheng + * 4.password: qqq + */ + @Test + public void fun() throws ClassNotFoundException, SQLException{ + //1.加载驱动类(注册驱动) + Class.forName("oracle.jdbc.driver.OracleDriver");//会优先加载静态代码块中的内容,因为OracleDriver的静态代码块中有DriverManager.registerDriver(new OracleDriver()); + //DriverManager.registerDriver(new OracleDriver());//也可以单独用这行代替Class.forName("oracle.jdbc.driver.OracleDriver"); + String url="jdbc:oracle:thin:@localhost:1521:orcl"; + String user="zicheng"; + String pwd="qqq"; + //2.创建连接对象 + Connection conn = DriverManager.getConnection(url, user, pwd); + //System.out.println(conn); + /* + * 3.通过Connection对象创建Statement对象 + * (1)通过COnnection对象创建的Statement,它的功能就是向数据库发送sql语句。 + * (2)调用int executeUpdate(String sql)//对数据库进行增删改操作,执行给定的SQL语句,这可能是 INSERT , UPDATE ,或 DELETE语句,或者不返回任何内容,如SQL DDL语句的SQL语句。 + */ + Statement statement = conn.createStatement(); + //4.执行sql语句(DML) + String sql="insert into emp(empno,ename,job)values(888,'Tony','boss')";//添加语句 + //int rows = statement.executeUpdate(sql);//影响了多少行 + String sql1="update emp set job='big boss' where empno=888"; + //int rows1 = statement.executeUpdate(sql1); + String sql2 = "delete from emp where job='big boss'"; + //int rows2 = statement.executeUpdate(sql2); + //5.释放资源 + statement.close(); + conn.close();//必须要关的,有连接数量上限,否则数据库会崩溃。 + } + + /** + * 查询 + * 1.得到Connection + * 2.得到Statement对象,发送SQL语句 + * 3.对查询返回的结果集进行解析 + * @throws ClassNotFoundException + * @throws SQLException + */ + @Test + public void query() throws ClassNotFoundException, SQLException{ + //1.加载驱动类(注册驱动) + Class.forName("oracle.jdbc.driver.OracleDriver");//会优先加载静态代码块中的内容,因为OracleDriver的静态代码块中有DriverManager.registerDriver(new OracleDriver()); + //DriverManager.registerDriver(new OracleDriver());//也可以单独用这行代替Class.forName("oracle.jdbc.driver.OracleDriver"); + String url="jdbc:oracle:thin:@localhost:1521:orcl"; + String user="zicheng"; + String pwd="qqq"; + //2.创建连接对象 + Connection conn = DriverManager.getConnection(url, user, pwd); + //3.通过Connection对象创建Statement对象 + Statement statement = conn.createStatement(); + /* + * 4.执行sql语句 + * ResultSet executeQuery(String sql)//执行给定的SQL语句,该语句返回单个 ResultSet对象。 + */ + String sql ="select * from emp"; + ResultSet rs = statement.executeQuery(sql); + /* + * 5.解析ResultSet + * 可以调用ResultSet的boolean next()把行光标移动到第下一行. + * 在ResultSet结果集中有一个行光标(只能上下移动,不能左右移动),对表中所有数据进行遍历。起始行位于第一行之前,终止行位于最后一行之后。 + * ResultSet提供一系列的getXXX()方法,getInt(),getString(),getDouble(),getDate(),getObject(). + * getInt(1),getInt(empno);//获取第一列,或直接写列名。 + */ + while(rs.next()){//将光标向下移动一行并判断是否存在。若存在则返回true,否则返回false。 + int empno = rs.getInt(1);//通过列编号来获取该列的值 + String ename = rs.getString("ename");//通过列名来获取该列的值。 + double sal = rs.getDouble("sal"); + String job = rs.getString("job"); + System.out.println(empno+"\t"+ename+"\t"+sal+"\t"+job); + } + //6.释放资源 + rs.close(); + statement.close(); + conn.close();//必须要关的,有连接数量上限,否则数据库会崩溃。 + } + + /** + * 规范写法 + */ + public static void main(String[] args) { + Connection conn = null; + Statement statement = null; + ResultSet rs = null; + try { + Class.forName("oracle.jdbc.driver.OracleDriver");//会优先加载静态代码块中的内容,因为OracleDriver的静态代码块中有DriverManager.registerDriver(new OracleDriver()); + String url="jdbc:oracle:thin:@localhost:1521:orcl"; + String user="zicheng"; + String pwd="qqq"; + conn = DriverManager.getConnection(url, user, pwd); + System.out.println("连接成功!"); + String sql = "select * from emp where ename like '%A%'"; + statement = conn.createStatement(); + rs = statement.executeQuery(sql); + while(rs.next()){//将光标向下移动一行并判断是否存在。若存在则返回true,否则返回false。 + int empno = rs.getInt(1);//通过列编号来获取该列的值 + String ename = rs.getString("ename");//通过列名来获取该列的值。 + double sal = rs.getDouble("sal"); + String job = rs.getString("job"); + System.out.println(empno+"\t"+ename+"\t"+sal+"\t"+job); + } + } catch (Exception e) { + // TODO: handle exception + }finally{ + try { + if(rs!=null){ + rs.close(); + } + if(statement!=null){ + statement.close(); + } + if(conn!=null){ + conn.close(); + } + } catch (SQLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } +} + + diff --git a/JDBC/src/JDBC_day01/demo/JDBCDemo02.java b/JDBC/src/JDBC_day01/demo/JDBCDemo02.java new file mode 100644 index 0000000..438f229 --- /dev/null +++ b/JDBC/src/JDBC_day01/demo/JDBCDemo02.java @@ -0,0 +1,73 @@ +package JDBC_day01.demo; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Scanner; + +import org.junit.Test; + +/** + * Java程序实现用户登录,验证用户名和密码。 + * 演示SQL注入攻击。 + */ +public class JDBCDemo02 { + + @Test + public void login() { + Connection conn = null; + Statement statement = null; + ResultSet rs = null; + try { + //1.连接数据库 + Class.forName("oracle.jdbc.driver.OracleDriver");// 会优先加载静态代码块中的内容,因为OracleDriver的静态代码块中有DriverManager.registerDriver(new OracleDriver()); + String url = "jdbc:oracle:thin:@localhost:1521:orcl"; + String user = "zicheng"; + String pwd = "qqq"; + conn = DriverManager.getConnection(url, user, pwd); + System.out.println("连接成功!"); + + //2.输入用户名和密码及sql语句拼接 + Scanner scanner = new Scanner(System.in); + System.out.print("请输入用户名: "); + String name = scanner.next(); + System.out.print("请输入密码: "); + String password = scanner.next();// SQL注入:select * from users where username='张三'and password='123456'or'a'='a';截取(两个单引号之间)123456'or'a'='a + // String sql = "select * from users where username='张三丰' and + // password='123456' or 1=1";//SQL注入 + String sql = "select * from users where username='" + name + "'and password='" + password + "'"; + System.out.println(sql); + + //3.通过Connection对象创建Statement对象 + statement = conn.createStatement(); + //4.执行sql语句(例子是查询) + rs = statement.executeQuery(sql); + //5.获取结果集,并用next()进行数据判断用户是否登陆成功。 + if (rs.next()) { + System.out.println("登陆成功!"); + } else { + System.out.println("用户名或密码错误!"); + } + } catch (Exception e) { + e.printStackTrace(); + } finally {//6.释放资源 + try { + if (rs != null) { + rs.close(); + } + if (statement != null) { + statement.close(); + } + if (conn != null) { + conn.close(); + } + } catch (SQLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + } +} diff --git a/JDBC/src/JDBC_day01/demo/JDBCDemo03.java b/JDBC/src/JDBC_day01/demo/JDBCDemo03.java new file mode 100644 index 0000000..c17dcc0 --- /dev/null +++ b/JDBC/src/JDBC_day01/demo/JDBCDemo03.java @@ -0,0 +1,83 @@ +package JDBC_day01.demo; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Scanner; + +import org.junit.Test; + +/** + * PreparedStatement:Statement的子接口。 + * 预编译(sql是否合符规范),是Statement接口的子接口,防止SQL攻击(不是主要性能),提高代码的可读性,可维护性,提高效率。 + */ +public class JDBCDemo03 { + @Test + public void login() { + Connection conn = null; + PreparedStatement ps = null; + ResultSet rs = null; + try { + //1.加载驱动类(注册驱动) + Class.forName("oracle.jdbc.driver.OracleDriver");//会优先加载静态代码块中的内容,因为OracleDriver的静态代码块中有DriverManager.registerDriver(new OracleDriver()); + //DriverManager.registerDriver(new OracleDriver());//也可以单独用这行代替Class.forName("oracle.jdbc.driver.OracleDriver"); + String url = "jdbc:oracle:thin:@localhost:1521:orcl"; + String user = "zicheng"; + String pwd = "qqq"; + conn = DriverManager.getConnection(url, user, pwd); + System.out.println("连接成功!"); + + //2.获取连接 对象,输入用户名和密码 + Scanner scanner = new Scanner(System.in); + System.out.print("请输入用户名: "); + String name = scanner.next(); + System.out.print("请输入密码: "); + String password = scanner.next();// SQL注入:select * from users where username='张三'and password='123456'or'a'='a';截取(两个单引号之间)123456'or'a'='a + // String sql = "select * from users where username='张三丰' and + // password='123456' or 1=1";//SQL注入 + String sql = "select * from users where username=? and password=?"; + + /* + * 3.创建PrepareStatement预编译对象 + * 调用Connection接口的方法prepareStatement,获取PrepareStatement接口的实现类。 + * SQL语句中的参数全部采用问号占位符。 + * 调用PrepareStatement对象setXXX()方法,给问号赋值。 + */ + ps = conn.prepareStatement(sql);//会预编译sql + ps.setString(1, name);//1和2是占位参数,表示第几个问号。 + ps.setString(2, password); + //4.调用方法,执行sql语句,获取结果集。 + rs = ps.executeQuery();//因为prepareStatement已经预编译过sql,所以statement.executeQuery()不需要传sql参数了。 + //5.遍历结果集 + if (rs.next()) { + System.out.println("登陆成功!"); + } else { + System.out.println("用户名或密码错误!"); + } + } catch (Exception e) { + e.printStackTrace(); + } finally {//6.释放资源 + try { + if (rs != null) { + rs.close(); + } + if (ps != null) { + ps.close(); + } + if (conn != null) { + conn.close(); + } + } catch (SQLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + } + + + +} diff --git a/JDBC/src/JDBC_day01/demo/JDBCDemo04.java b/JDBC/src/JDBC_day01/demo/JDBCDemo04.java new file mode 100644 index 0000000..9f0873a --- /dev/null +++ b/JDBC/src/JDBC_day01/demo/JDBCDemo04.java @@ -0,0 +1,72 @@ +package JDBC_day01.demo; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Scanner; + +import org.junit.Test; + +/** + * 使用PrepareStatement,实现数据表的更新操作。 + */ +public class JDBCDemo04 { + @Test + public void login() { + Connection conn = null; + PreparedStatement ps = null; + try { + //1.加载驱动类(注册驱动) + Class.forName("oracle.jdbc.driver.OracleDriver");//会优先加载静态代码块中的内容,因为OracleDriver的静态代码块中有DriverManager.registerDriver(new OracleDriver()); + //DriverManager.registerDriver(new OracleDriver());//也可以单独用这行代替Class.forName("oracle.jdbc.driver.OracleDriver"); + String url = "jdbc:oracle:thin:@localhost:1521:orcl"; + String user = "zicheng"; + String pwd = "qqq"; + conn = DriverManager.getConnection(url, user, pwd); + System.out.println("连接成功!"); + + //2.获取连接对象,输入用户名和密码 + Scanner scanner = new Scanner(System.in); + System.out.print("请输入要修改的用户编号: "); + int id = scanner.nextInt(); + System.out.print("请输入新用户名: "); + String name = scanner.next(); + String sql = "update users set username=? where id=?"; + + /* + * 3.创建PrepareStatement预编译对象 + * 调用Connection接口的方法prepareStatement,获取PrepareStatement接口的实现类。 + * SQL语句中的参数全部采用问号占位符。 + * 调用PrepareStatement对象setXXX()方法,给问号赋值。 + */ + ps = conn.prepareStatement(sql);//会预编译sql + ps.setString(1, name);//1和2是占位参数,表示第几个问号。 + ps.setInt(2, id); + + int rows = ps.executeUpdate();//因为prepareStatement已经预编译过sql,所以statement.executeUpdate()不需要传sql参数了。 + System.out.println(rows); + + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + if (ps != null) { + ps.close(); + } + if (conn != null) { + conn.close(); + } + } catch (SQLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + } + + + +} diff --git a/JDBC/src/JDBC_day01/lib/ojdbc5.jar b/JDBC/src/JDBC_day01/lib/ojdbc5.jar new file mode 100644 index 0000000..4c02ee3 Binary files /dev/null and b/JDBC/src/JDBC_day01/lib/ojdbc5.jar differ diff --git "a/JDBC/src/JDBC_day01/note/JDBC\345\216\237\347\220\206.jpg" "b/JDBC/src/JDBC_day01/note/JDBC\345\216\237\347\220\206.jpg" new file mode 100644 index 0000000..131028f Binary files /dev/null and "b/JDBC/src/JDBC_day01/note/JDBC\345\216\237\347\220\206.jpg" differ diff --git a/JDBC/src/JDBC_day01/note/summary.txt b/JDBC/src/JDBC_day01/note/summary.txt new file mode 100644 index 0000000..12daaeb --- /dev/null +++ b/JDBC/src/JDBC_day01/note/summary.txt @@ -0,0 +1,49 @@ +JDBCDemo01: + 1.基本流程 + (1)连接数据库/加载驱动类(注册驱动): + 1)Class.forName("oracle.jdbc.driver.OracleDriver");//加载驱动类(注册驱动) + 或DriverManager.registerDriver(new OracleDriver()); + 2)Connection conn = DriverManager.getConnection(url, user, pwd);//创建连接对象 + (2)Statement statement = conn.createStatement();//通过Connection对象创建Statement对象 + (3)增删改/查询,都要传参。 + (4)释放资源 + 2.DML增删改:int rows = statement.executeUpdate(sql);//影响了多少行//执行sql语句(DML),要传参。 + 3.DQL查询: + (1)ResultSet rs = statement.executeQuery(sql);//执行sql语句(DQL)并获取结果集,要传参。 + (2)ResultSet的boolean next(); + (3)getInt(),getString(),getDouble(),getDate(),getObject();//getInt(1),getInt(empno);//获取第一列,或直接写列名。 + 4.规范写法; + +JDBCDemo02: + Java程序实现用户登录,验证用户名和密码. + 演示SQL注入攻击。 + 1.连接数据库 + 2.输入用户名和密码及sql语句拼接 + 3.通过Connection对象创建Statement对象 + 4.执行sql语句(例子是查询) + 5.获取结果集,并用next()进行数据判断用户是否登陆成功。 + 6.释放资源 + +JDBCDemo03: + 使用PrepareStatement,实现数据表的查询操作。 + PreparedStatement:预编译(sql是否合符规范),是Statement接口的子接口,防止SQL攻击(不是主要性能),提高代码的可读性,可维护性,提高效率。 + 1.连接数据库 + 2.输入用户名和密码及sql语句拼接(这里是用?进行拼接)//String sql = "select * from users where username=? and password=?"; + 3.创建PrepareStatement预编译对象,因为PrepareStatement是接口,其实现类为Statement对象 + 1)ps = conn.prepareStatement(sql);//会预编译sql.//调用Connection接口的方法prepareStatement,获取PrepareStatement接口的实现类。 + 2)ps.setString(1, name);//调用PrepareStatement对象setXXX()方法,给问号赋值。1和2是占位参数,表示第几个问号。 + 4.调用方法,执行sql语句,获取结果集 + rs = ps.executeQuery();//因为prepareStatement已经预编译过sql,所以statement.executeQuery()不需要传sql参数了。 + 5.遍历结果集 + 6.释放资源 + +JDBCDemo04: + 使用PrepareStatement,实现数据表的更新操作。 + 1.连接数据库 + 2.输入要修改的用编号和新用户名及sql语句拼接(这里是用?进行拼接) + 3.创建PrepareStatement预编译对象,因为PrepareStatement是接口,其实现类为Statement对象 + 1)ps = conn.prepareStatement(sql);//会预编译sql.//调用Connection接口的方法prepareStatement,获取PrepareStatement接口的实现类。 + 2)ps.setString(1, name);//调用PrepareStatement对象setXXX()方法,给问号赋值。1和2是占位参数,表示第几个问号。 + 4.执行sql语句 + int rows = ps.executeUpdate();//因为prepareStatement已经预编译过sql,所以statement.executeUpdate()不需要传sql参数了。 + 5.释放资源 \ No newline at end of file diff --git a/JDBC/src/JDBC_day02/demo/JDBCDemo01.java b/JDBC/src/JDBC_day02/demo/JDBCDemo01.java new file mode 100644 index 0000000..906b63a --- /dev/null +++ b/JDBC/src/JDBC_day02/demo/JDBCDemo01.java @@ -0,0 +1,62 @@ +package JDBC_day02.demo; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.List; +import java.util.Scanner; + +import org.junit.Test; + +import JDBC_day02.demo.util.DBUtil; + +/** + * 使用PrepareStatement,实现模糊查询。 + */ +public class JDBCDemo01 { + @Test + public void fuzzyQuery() { + Connection conn = null; + PreparedStatement ps = null; + ResultSet rs = null; + try { + //1.连接数据库 + conn = DBUtil.getConnection(); + + //2.获取连接对象,输入用户名和密码 + Scanner scanner = new Scanner(System.in); + System.out.print("请输入查询条件: "); + String condition = scanner.next(); + String sql = "select * from emp where ename like ?"; + + /* + * 3.创建PrepareStatement预编译对象 + * 调用Connection接口的方法prepareStatement,获取PrepareStatement接口的实现类。 + * SQL语句中的参数全部采用问号占位符。 + * 调用PrepareStatement对象setXXX()方法,给问号赋值。 + */ + ps = conn.prepareStatement(sql);//会预编译sql + ps.setString(1, "%"+condition+"%"); + + rs = ps.executeQuery(); + while(rs.next()){ + int empno = rs.getInt("empno"); + String ename = rs.getString("ename"); + String job = rs.getString("job"); + System.out.println(empno+"\t"+ename+"\t"+job); + } + + } catch (Exception e) { + e.printStackTrace(); + } finally { + DBUtil.close(conn, ps, rs); + } + + } + + + +} diff --git a/JDBC/src/JDBC_day02/demo/JDBCDemo02.java b/JDBC/src/JDBC_day02/demo/JDBCDemo02.java new file mode 100644 index 0000000..3c5a164 --- /dev/null +++ b/JDBC/src/JDBC_day02/demo/JDBCDemo02.java @@ -0,0 +1,51 @@ +package JDBC_day02.demo; + +import java.sql.*; +import java.util.*; +import org.junit.Test; + +import JDBC_day02.demo.bean.Users; +import JDBC_day02.demo.util.DBUtil; + +/** + * JDBC读取数据表users,每行数据封装到USers类的对象中。 + */ +public class JDBCDemo02 { + @Test + public void fuzzyQuery() { + Connection conn = null; + PreparedStatement ps = null; + ResultSet rs = null; + try { + conn = DBUtil.getConnection(); + + String sql = "select * from users"; + + ps = conn.prepareStatement(sql);//会预编译sql + + rs = ps.executeQuery(); + + List list = new ArrayList();//创建集合对象 + + while(rs.next()){//获取结果集中每行的数据,封装到Users对象中 + int id = rs.getInt("id"); + String username = rs.getString("username"); + String password = rs.getString("password"); + Users user = new Users(id,username,password); + list.add(user); + } + for(Users user: list){ + System.out.println(user.toString()); + } + + } catch (Exception e) { + e.printStackTrace(); + } finally { + DBUtil.close(conn, ps, rs); + } + + } + + + +} diff --git a/JDBC/src/JDBC_day02/demo/JDBCDemo03.java b/JDBC/src/JDBC_day02/demo/JDBCDemo03.java new file mode 100644 index 0000000..8e4e3fb --- /dev/null +++ b/JDBC/src/JDBC_day02/demo/JDBCDemo03.java @@ -0,0 +1,42 @@ +package JDBC_day02.demo; + +import java.sql.*; + +import org.junit.Test; + +import JDBC_day02.demo.util.DBUtil; + +/* + * 银行转账 + */ +public class JDBCDemo03 { + @Test + public void account(){ + Connection conn = null; + Statement s = null; + try{ + conn = DBUtil.getConnection(); + s = conn.createStatement(); + + String sql1 = "update t_account set balance=balance+20000 where id=1"; + String sql2 = "update t_account set balance=balance-20000 where id=2"; + + conn.setAutoCommit(false);//将事务的自动提交取消。 + s.executeUpdate(sql1); + s.executeUpdate(sql2); + conn.commit();//手动提交事务,可将上面的逻辑全部控制在一个事务中。 + + System.out.println("转账成功!"); + }catch(Exception e){ + try { + System.out.println("出错了!"); + conn.rollback();//回滚事务。 + } catch (SQLException e1) { + e1.printStackTrace(); + } + e.printStackTrace(); + }finally { + DBUtil.close(conn, s, null); + } + } +} diff --git a/JDBC/src/JDBC_day02/demo/bean/Users.java b/JDBC/src/JDBC_day02/demo/bean/Users.java new file mode 100644 index 0000000..f8902ca --- /dev/null +++ b/JDBC/src/JDBC_day02/demo/bean/Users.java @@ -0,0 +1,53 @@ +package JDBC_day02.demo.bean; + +public class Users { + + private int id; + private String username; + private String password; + + public Users() { + + } + + public Users(int id, String username, String password) { + this.id = id; + this.username = username; + this.password = password; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + @Override + public String toString() { + return "Users [id=" + id + ", username=" + username + ", password=" + password + "]"; + } + + + + + + +} diff --git a/JDBC/src/JDBC_day02/demo/util/DBUtil.java b/JDBC/src/JDBC_day02/demo/util/DBUtil.java new file mode 100644 index 0000000..63ca751 --- /dev/null +++ b/JDBC/src/JDBC_day02/demo/util/DBUtil.java @@ -0,0 +1,46 @@ +package JDBC_day02.demo.util; + +import java.sql.*; + +/* + * 实现JDBC的工具类 + * 定义方法,直接返回数据库的连接对象 + * 关闭所有资源 + */ +public class DBUtil { + //链接数据库的封装方法 + public static Connection getConnection(){ + Connection conn = null; + try { + //加载驱动 + Class.forName("oracle.jdbc.driver.OracleDriver"); + String url = "jdbc:oracle:thin:@localhost:1521:orcl"; + String user = "zicheng"; + String password = "qqq"; + //获取连接对象 + conn = DriverManager.getConnection(url, user, password); + System.out.println("使用DBUtil连接Oracle成功!"); + } catch (Exception e) { + e.printStackTrace(); + } + return conn; + } + + //关闭所有内容 + public static void close(Connection conn, Statement statement, ResultSet rs){//Statement + try { + if(rs != null){ + rs.close(); + } + if (statement != null) { + statement.close(); + } + if (conn != null) { + conn.close(); + } + } catch (SQLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } +} diff --git a/JDBC/src/JDBC_day02/note/summary.txt b/JDBC/src/JDBC_day02/note/summary.txt new file mode 100644 index 0000000..8d8a551 --- /dev/null +++ b/JDBC/src/JDBC_day02/note/summary.txt @@ -0,0 +1,62 @@ +锘緿BUtil锛 + 瀹炵幇JDBC鐨勫伐鍏风被 + 瀹氫箟闈欐佹柟娉曪紝鐩存帴杩斿洖鏁版嵁搴撶殑杩炴帴瀵硅薄 + 瀹氫箟闈欐佹柟娉曪紝鍏抽棴鎵鏈夎祫婧 + +JDBCDemo01锛 + 浣跨敤浜咲BUtil宸ュ叿绫 + 浣跨敤PrepareStatement锛屽疄鐜版ā绯婃煡璇細ps.setString(1, "%"+condition+"%"); + +JDBCDemo02锛 + JDBC璇诲彇鏁版嵁琛╱sers锛屾瘡琛屾暟鎹皝瑁呭埌USers绫荤殑瀵硅薄涓 + +JDBCDemo03锛 + 閾惰杞处 + conn.setAutoCommit(false);//灏嗕簨鍔$殑鑷姩鎻愪氦鍙栨秷銆 + conn.commit();//鎵嬪姩鎻愪氦浜嬪姟锛屽彲灏嗕笂闈㈢殑閫昏緫鍏ㄩ儴鎺у埗鍦ㄤ竴涓簨鍔′腑銆 + conn.rollback();//鍥炴粴浜嬪姟銆 + +EmpManage_JDBC锛 + 1.bean:瀹炰綋绫 + 2.dao:瀹炵幇绫(鍖)daoimpl锛屾帴鍙 + 3.test:娴嬭瘯绫 + 4.DBUtil: + 闈欐--杩炴帴鏁版嵁搴撶殑鏂规硶 + public static Connection getConnection (){ + Connection conn = null; + try{ + conn = Class.forName("jdbc.oracle.driver.OracleDriver"); + String url = 锛 + String username = 锛 + String password = 锛 + conn = DriverManager.getConnection(url, username, password); + }catch(Exception e){ + e.printStackTrace(); + } + return conn; + }; + 闈欐--鍏抽棴璧勬簮鐨勬柟娉 + public static void close(Connection conn,Statement ps,ResultSet rs) { + try { + if(rs != null) { + rs.close(); + } + if(ps != null) { + ps.close(); + } + if(conn != null) { + con.close(); + } + }catch(SQLException e) { + e.printStackTrace(); + } + } + +琛ュ厖锛 + 1.sql.date杞瑄til.date鍙互鑷姩杞崲銆 + util.date--->sql.date锛 java.sql.Date date = new java.sql.Date(emp.getHiredate().getTime()); + //sql.Date鐨勬瀯閫犲彲浠ヤ紶1970鐨勬绉掑硷紝util.Date鐨刧etTime()鍙互寰楀埌1970鐨勬绉掑笺 + 2.String--->util.Date + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + emp.setHiredate(sdf.parse(sc.next()));//灏哠tring--->util.date,浼氭姏鍑篜arseException寮傚父銆 + diff --git a/JDBC/src/note/JDBC_day01/JDBC_day01_summary.txt b/JDBC/src/note/JDBC_day01/JDBC_day01_summary.txt new file mode 100644 index 0000000..12daaeb --- /dev/null +++ b/JDBC/src/note/JDBC_day01/JDBC_day01_summary.txt @@ -0,0 +1,49 @@ +JDBCDemo01: + 1.基本流程 + (1)连接数据库/加载驱动类(注册驱动): + 1)Class.forName("oracle.jdbc.driver.OracleDriver");//加载驱动类(注册驱动) + 或DriverManager.registerDriver(new OracleDriver()); + 2)Connection conn = DriverManager.getConnection(url, user, pwd);//创建连接对象 + (2)Statement statement = conn.createStatement();//通过Connection对象创建Statement对象 + (3)增删改/查询,都要传参。 + (4)释放资源 + 2.DML增删改:int rows = statement.executeUpdate(sql);//影响了多少行//执行sql语句(DML),要传参。 + 3.DQL查询: + (1)ResultSet rs = statement.executeQuery(sql);//执行sql语句(DQL)并获取结果集,要传参。 + (2)ResultSet的boolean next(); + (3)getInt(),getString(),getDouble(),getDate(),getObject();//getInt(1),getInt(empno);//获取第一列,或直接写列名。 + 4.规范写法; + +JDBCDemo02: + Java程序实现用户登录,验证用户名和密码. + 演示SQL注入攻击。 + 1.连接数据库 + 2.输入用户名和密码及sql语句拼接 + 3.通过Connection对象创建Statement对象 + 4.执行sql语句(例子是查询) + 5.获取结果集,并用next()进行数据判断用户是否登陆成功。 + 6.释放资源 + +JDBCDemo03: + 使用PrepareStatement,实现数据表的查询操作。 + PreparedStatement:预编译(sql是否合符规范),是Statement接口的子接口,防止SQL攻击(不是主要性能),提高代码的可读性,可维护性,提高效率。 + 1.连接数据库 + 2.输入用户名和密码及sql语句拼接(这里是用?进行拼接)//String sql = "select * from users where username=? and password=?"; + 3.创建PrepareStatement预编译对象,因为PrepareStatement是接口,其实现类为Statement对象 + 1)ps = conn.prepareStatement(sql);//会预编译sql.//调用Connection接口的方法prepareStatement,获取PrepareStatement接口的实现类。 + 2)ps.setString(1, name);//调用PrepareStatement对象setXXX()方法,给问号赋值。1和2是占位参数,表示第几个问号。 + 4.调用方法,执行sql语句,获取结果集 + rs = ps.executeQuery();//因为prepareStatement已经预编译过sql,所以statement.executeQuery()不需要传sql参数了。 + 5.遍历结果集 + 6.释放资源 + +JDBCDemo04: + 使用PrepareStatement,实现数据表的更新操作。 + 1.连接数据库 + 2.输入要修改的用编号和新用户名及sql语句拼接(这里是用?进行拼接) + 3.创建PrepareStatement预编译对象,因为PrepareStatement是接口,其实现类为Statement对象 + 1)ps = conn.prepareStatement(sql);//会预编译sql.//调用Connection接口的方法prepareStatement,获取PrepareStatement接口的实现类。 + 2)ps.setString(1, name);//调用PrepareStatement对象setXXX()方法,给问号赋值。1和2是占位参数,表示第几个问号。 + 4.执行sql语句 + int rows = ps.executeUpdate();//因为prepareStatement已经预编译过sql,所以statement.executeUpdate()不需要传sql参数了。 + 5.释放资源 \ No newline at end of file diff --git "a/JDBC/src/note/JDBC_day01/JDBC\345\216\237\347\220\206.jpg" "b/JDBC/src/note/JDBC_day01/JDBC\345\216\237\347\220\206.jpg" new file mode 100644 index 0000000..131028f Binary files /dev/null and "b/JDBC/src/note/JDBC_day01/JDBC\345\216\237\347\220\206.jpg" differ diff --git a/JDBC/src/note/JDBC_day02/JDBC_day02_summary.txt b/JDBC/src/note/JDBC_day02/JDBC_day02_summary.txt new file mode 100644 index 0000000..9a00174 --- /dev/null +++ b/JDBC/src/note/JDBC_day02/JDBC_day02_summary.txt @@ -0,0 +1,17 @@ +锘緿BUtil锛 + 瀹炵幇JDBC鐨勫伐鍏风被 + 瀹氫箟闈欐佹柟娉曪紝鐩存帴杩斿洖鏁版嵁搴撶殑杩炴帴瀵硅薄 + 瀹氫箟闈欐佹柟娉曪紝鍏抽棴鎵鏈夎祫婧 + +JDBCDemo01锛 + 浣跨敤浜咲BUtil宸ュ叿绫 + 浣跨敤PrepareStatement锛屽疄鐜版ā绯婃煡璇細ps.setString(1, "%"+condition+"%"); + +JDBCDemo02锛 + JDBC璇诲彇鏁版嵁琛╱sers锛屾瘡琛屾暟鎹皝瑁呭埌USers绫荤殑瀵硅薄涓 + +JDBCDemo03锛 + 閾惰杞处 + conn.setAutoCommit(false);//灏嗕簨鍔$殑鑷姩鎻愪氦鍙栨秷銆 + conn.commit();//鎵嬪姩鎻愪氦浜嬪姟锛屽彲灏嗕笂闈㈢殑閫昏緫鍏ㄩ儴鎺у埗鍦ㄤ竴涓簨鍔′腑銆 + conn.rollback();//鍥炴粴浜嬪姟銆 diff --git a/JDBC/src/note/project/one/project_EmpManage_summary b/JDBC/src/note/project/one/project_EmpManage_summary new file mode 100644 index 0000000..8a69bae --- /dev/null +++ b/JDBC/src/note/project/one/project_EmpManage_summary @@ -0,0 +1,43 @@ +EmpManage_JDBC: + 1.bean:实体类 + 2.dao:实现类(包)daoimpl,接口 + 3.test:测试类 + 4.DBUtil: + 静态--连接数据库的方法 + public static Connection getConnection (){ + Connection conn = null; + try{ + conn = Class.forName("jdbc.oracle.driver.OracleDriver"); + String url = ? + String username = ? + String password = ? + conn = DriverManager.getConnection(url, username, password); + }catch(Exception e){ + e.printStackTrace(); + } + return conn; + }; + 静态--关闭资源的方法 + public static void close(Connection conn,Statement ps,ResultSet rs) { + try { + if(rs != null) { + rs.close(); + } + if(ps != null) { + ps.close(); + } + if(conn != null) { + con.close(); + } + }catch(SQLException e) { + e.printStackTrace(); + } + } + +补充: + 1.sql.date转util.date可以自动转换。 + util.date--->sql.date: java.sql.Date date = new java.sql.Date(emp.getHiredate().getTime()); + //sql.Date的构造可以传1970的毫秒值,util.Date的getTime()可以得到1970的毫秒值。 + 2.String--->util.Date + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + emp.setHiredate(sdf.parse(sc.next()));//将String--->util.date,会抛出ParseException异常。 diff --git "a/JDBC/src/note/project/two/JAVA\345\237\272\347\241\200\345\256\236\350\256\255\347\273\203\344\271\240.docx" "b/JDBC/src/note/project/two/JAVA\345\237\272\347\241\200\345\256\236\350\256\255\347\273\203\344\271\240.docx" new file mode 100644 index 0000000..1b1ea81 Binary files /dev/null and "b/JDBC/src/note/project/two/JAVA\345\237\272\347\241\200\345\256\236\350\256\255\347\273\203\344\271\240.docx" differ diff --git a/JDBC/src/note/project/two/carRent_JDBC.sql b/JDBC/src/note/project/two/carRent_JDBC.sql new file mode 100644 index 0000000..f96570d --- /dev/null +++ b/JDBC/src/note/project/two/carRent_JDBC.sql @@ -0,0 +1,52 @@ +--建表 +create table car( + brand varchar2(10) not null, + vehicleId varchar2(20) not null unique, + perRent number(4) not null, + type varchar2(20) not null +); +create table bus( + brand varchar2(10) not null, + vehicleId varchar2(20) not null unique, + perRent number(4) not null, + seat number(2) not null +); +create table truck( + brand varchar2(10) not null, + vehicleId varchar2(20) not null unique, + perRent number(4) not null, + tonnage number(2) not null +); +create table rented( + brand varchar2(10) not null, + vehicleId varchar2(20) not null unique, + perRent number(4) not null, + type varchar2(20), + seat number(2), + tonnage number(2) +); +--插入数据 +insert into car values('宝马','京NY28588',800,'X6'); +insert into car values('宝马','京CNY3284',600,'550i'); +insert into car values('别克','京NT37465',300,'林荫大道'); +insert into car values('别克','京NT96968',600,'GL8'); +insert into bus values('金杯','京6566754',800,16); +insert into bus values('金龙','京8696997',800,16); +insert into bus values('金杯','京9696996',1500,34); +insert into bus values('金龙','京8696998',1500,34); +insert into truck values('一汽解放','京MH98725',50,5); +insert into truck values('重庆红岩','京L593216',50,5); +insert into truck values('一汽解放','京NU98631',50,10); +insert into truck values('重庆红岩','京CY56312',50,10); +--查看表 +select * from car; +select * from bus; +select * from truck; +select * from rented; +--删除表 +drop table car; +drop table bus; +drop table truck; +drop table rented; + + diff --git "a/JDBC/src/note/sql/MySQL \345\244\232\350\241\250\346\237\245\350\257\242\347\273\203\344\271\240.docx" "b/JDBC/src/note/sql/MySQL \345\244\232\350\241\250\346\237\245\350\257\242\347\273\203\344\271\240.docx" new file mode 100644 index 0000000..a4cf19e Binary files /dev/null and "b/JDBC/src/note/sql/MySQL \345\244\232\350\241\250\346\237\245\350\257\242\347\273\203\344\271\240.docx" differ diff --git a/JDBC/src/note/sql/MySQL.sql b/JDBC/src/note/sql/MySQL.sql new file mode 100644 index 0000000..363ef91 --- /dev/null +++ b/JDBC/src/note/sql/MySQL.sql @@ -0,0 +1,374 @@ +SQL(缁撴瀯鍖栨煡璇㈣瑷),姝ょ瑪璁颁富瑕侀拡瀵逛簬MySQL version 5.5; +1.SQL鍒嗙被锛 + DDL锛氭暟鎹畾涔夎瑷锛岀敤浜庢搷浣滄暟鎹璞★紙琛紝瑙嗗浘锛屽簭鍒楋紝绱㈠紩锛夈 + CREATE锛氬垱寤鸿〃鎴栧叾瀹冨璞° + ALTER锛氫慨鏀硅〃鎴栧叾瀹冨璞$粨鏋勩 + DROP锛氬垹闄よ〃鎴栧叾瀹冨璞° + TRUNCATE锛氬垹闄よ〃鏁版嵁锛屼繚鐣欒〃缁撴瀯銆傛竻绌鸿〃鐨勬搷浣溿 + DML锛氭暟鎹搷浣滆瑷锛堥氬父闇瑕佷即闅廡CL锛夛紝鐢ㄤ簬澧炲垹鏀硅〃涓殑鏁版嵁銆 + INSERT INTO锛氬皢鏁版嵁鎻掑叆琛ㄤ腑銆 + DELETE锛氬垹闄よ〃涓暟鎹 + UPDATE SET锛氭洿鏂拌〃涓暟鎹 + TCL锛氫簨鍔℃帶鍒惰瑷銆 + COMMIT锛氭彁浜ゃ + ROLLBACK锛氬洖婊氥 + DQL锛氭暟鎹煡璇㈣瑷 + SELECT锛氭煡璇㈡暟鎹 + DCL锛氭暟鎹帶鍒惰瑷銆 + GRANT锛氭巿浜堟潈闄愩 + REVOKE: 鎾ら攢鏉冮檺銆 + grant鈥reate鈥iew鈥o鈥cott; +2.Mysql鍩烘湰浠嬬粛: + 鍚姩鍜屽仠姝ysql鏈嶅姟锛歮ysql鏄竴绉岰/S缁撴瀯鐨勮蒋浠(瀹㈡埛绔拰鏈嶅姟鍣),鏈嶅姟绔搴旂殑杞欢锛歮ysqld.exe, 瀹㈡埛绔: mysql.exe; + cmd鍛戒护琛屾柟寮: 寮鍚湇鍔: net start mysql; 鍏抽棴鏈嶅姟: net stop mysql; + 绯荤粺鏈嶅姟鏂瑰紡: 姝ょ數鑴戯紝绠$悊锛屾湇鍔★紝MySQL; + cmd鐧婚檰mysql: mysql -uroot -proot, 鑻ユ湭閰嶇疆鐜鍙橀噺锛屽垯闇杩涘叆鍒癕ySQL閲岀殑bin鐩綍涓嬪啀鐢╟md鐧婚檰mysql銆 + -uroot锛氳〃绀虹敤鎴锋槸root锛屾槸榛樿鐨勭敤鎴; + -proot锛氳〃绀虹敤鎴风殑瀵嗙爜鏄痳oot; + 閫鍑簃ysql: exit鎴杚uit; +3.Mysql鏈嶅姟绔灦鏋: + (1)鏁版嵁搴撶鐞嗙郴缁(鏈澶栧眰):DBMS,涓撻棬绠$悊鏈嶅姟鍣ㄧ鐨勬墍鏈夊唴瀹广 + (2)鏁版嵁搴(绗簩灞):DB,涓撻棬鐢ㄤ簬瀛樺偍鏁版嵁鐨勪粨搴(鍙互鏈夊涓)銆 + (3)浜岀淮鏁版嵁琛(绗笁灞):TABLE,涓撻棬鐢ㄤ簬瀛樺偍瀹炰綋鐨勬暟鎹 + (4)瀛楁(绗洓灞):Field,鍏蜂綋瀛樺偍鏌愮绫诲瀷鐨勬暟鎹(瀹為檯鐨勫瓨鍌ㄥ崟鍏)銆 +4.鏁版嵁搴撳熀鏈搷浣: + (1)鍒涘缓鏁版嵁搴: create database [if not exists] 鏁版嵁搴撳悕 [charset 瀛楃闆哴;--if not exits濡傛灉涓嶅瓨鍦ㄥ垯鍒涘缓锛孾鍙啓鍙笉鍐橾.瀛楃闆嗚嫢涓嶆寚瀹氬垯鎸夐粯璁ゅ瓧绗﹂泦缂栫爜; + create database if not exists t_user charset utf8; + (2)鏄剧ず鏁版嵁搴: + 鏄剧ず鍏ㄩ儴鏁版嵁搴: show databases; + 鏄剧ず閮ㄥ垎鏁版嵁搴: show databases like '鍖归厤妯″紡'; _:鍖归厤褰撳墠浣嶇疆鐨勫崟涓瓧绗;%:鍖归厤鎸囧畾浣嶇疆鐨勫涓瓧绗; + 鑾峰彇浠y寮澶寸殑鏁版嵁搴: show databases like 'my%'; + (3)閫夋嫨鏁版嵁搴: use 鏁版嵁搴撳悕;--use t_user; + (4)淇敼鏁版嵁搴: + 1)淇敼鏁版嵁搴撳瓧绗﹂泦: alter database 鏁版嵁搴撳悕 charset 瀛楃闆; --alter database t_user charset gbk + 2)鍒犻櫎鏁版嵁搴: drop database 鏁版嵁搴撳悕; --drop database t_user; + (5)鏁版嵁琛ㄦ搷浣: + 1)鍒涘缓鏁版嵁琛: create table 琛ㄥ悕(瀛楁鍚 瀛楁绫诲瀷[瀛楁灞炴, 瀛楁鍚 瀛楁绫诲瀷[瀛楁灞炴, ...); + 渚嬪瓙:create table user( + username varchar(10), + password varchar(10) + ); + 2)鏄剧ず鏁版嵁琛: + 鏄剧ず鎵鏈夎〃: show tables; + 鏄剧ず閮ㄥ垎琛: show tables like '鍖归厤妯″紡'; + 3)鏄剧ず琛ㄧ粨鏋: desc 琛ㄥ悕; + 4)淇敼琛ㄧ粨鏋: 5.5鐗堟湰涔嬪悗鐨勬暟鎹簱鍚嶄笉鑳戒慨鏀 + 淇敼琛ㄥ悕: rename table 鏃ц〃鍚 to 鏂拌〃鍚; --rename table user to t_user; + 淇敼琛ㄩ夐」: alter table 琛ㄥ悕 charset utf8; + 鏂板瀛楁: alter table 琛ㄥ悕 add 鏂板瓧娈靛悕 瀛楁绫诲瀷[瀛楁灞炴 [浣嶇疆first/after瀛楁鍚峕; --alter table t_user add id int first; alter table t_user add age int; + 淇敼瀛楁鍚: alter table 琛ㄥ悕 change 鏃у瓧娈靛悕 鏂板瓧娈靛悕 瀛楁绫诲瀷[瀛楁灞炴 [鏂颁綅缃甝; --alter table t_user change age nianling int; + 淇敼瀛楁绫诲瀷: alter table 琛ㄥ悕 modify 瀛楁鍚 鏂扮被鍨媅鏂板睘鎬 [鏂颁綅缃甝; --alter table t_user modify username varchar(20); + 鍒犻櫎瀛楁: alter table 琛ㄥ悕 drop 瀛楁鍚; --alter table t_user drop nianling; + 5)鍒犻櫎琛ㄧ粨鏋: drop table 琛ㄥ悕[,琛ㄥ悕2];鍙互鍚屾椂鍒犻櫎澶氫釜鏁版嵁琛ㄣ + 6)娓呯┖琛ㄤ腑鏁版嵁: truncate table 琛ㄥ悕;涓嶅彲浠ュ悓鏃舵竻绌哄涓暟鎹〃銆 +5.鏁版嵁鍩虹鎿嶄綔: + 鎻掑叆鎿嶄綔: insert into 琛ㄥ悕[(瀛楁鍒楄〃)] values(瀵瑰簲瀛楁鍒楄〃); + insert into 琛ㄥ悕 values(瀵瑰簲鍏ㄩ儴瀛楁); + 鏌ヨ鎿嶄綔: select * from 琛ㄥ悕; --*琛ㄧず鍖归厤鎵鏈夌殑瀛楁. + select 瀛楁鍒楄〃 from 琛ㄥ悕;--瀛楁鍒楄〃浣跨敤","鍒嗛殧. + 鍒犻櫎鎿嶄綔: delete from 琛ㄥ悕 where 鏉′欢; --閫氬父鍒犻櫎閮ㄥ垎鏁版嵁锛屾墍浠ュ姞where鏉′欢銆 + truncate table 琛ㄥ悕; + 鏇存柊鎿嶄綔: update 琛ㄥ悕 set 瀛楁鍚=鏂板 where 鏉′欢; --閫氬父淇敼閮ㄥ垎瀛楁鐨勫硷紝鎵浠ュ姞where鏉′欢銆 +6.鍒楃被鍨(瀛楁绫诲瀷): + 1)鏁存暟绫诲瀷: + Tinyint: 杩蜂綘鏁村舰锛岀郴缁熼噰鐢ㄤ竴涓瓧鑺傛潵淇濆瓨鐨勬暣褰紝1涓瓧鑺傜瓑浜8浣嶏紝鏈澶ц兘琛ㄧず鐨勬暟鍊兼槸0~255. + mysql榛樿鐨勪负鏁村舰澧炲姞璐熸暟锛屽疄闄呰〃绀虹殑鍖洪棿涓-128~127. + Smallint: 灏忔暣褰紝绯荤粺閲囩敤涓や釜瀛楄妭鏉ヤ繚瀛樼殑鏁村舰锛岃兘琛ㄧず0~65535. + Mediumint: 涓暣褰紝绯荤粺閲囩敤涓変釜瀛楄妭鏉ヤ繚瀛樻暟鎹. + int: 鏁村舰锛屾爣鍑嗘暣褰㈢郴缁熼噰鐢ㄥ洓涓瓧鑺傛潵淇濆瓨鏁版嵁. + bigint: 姣攊nt鑼冨洿杩樿澶. + 渚嬪瓙: + 鍒涘缓鏁版嵁琛: + create table t_int( + num1 tinyint, + num2 smallint, + num3 mediumint, + num4 int, + num5 bigint + ); + insert into t_int values(-128,255,255,255,255); + insert into t_int values(255,255,255,255,255); --浼氭姤閿欙紝鍥犱负鏈澶ц寖鍥翠负-128~127. + 鏃犵鍙锋爣璇嗚瀹: + 鏃犵鍙: 琛ㄧず瀛樺偍鐨勬暟鎹啀褰撳墠瀛楁涓病鏈夎礋鏁(鍙湁姝f暟锛屽尯闂翠负0~255). + 鍦ㄧ被鍨嬩箣鍚庡姞涓婁竴涓猽nsigned銆 + alter table t_int add num6 tinyint unsigned first; + insert into t_int values(255,-128,255,255,255,255); + 2)灏忔暟绫诲瀷:娴偣鍨嬪拰瀹氱偣鍨; + 娴偣鍨(绮惧害绫诲瀷): 鏄竴绉嶆湁鍙兘涓㈠け绮惧害鐨勬暟鎹被鍨嬶紝鏁版嵁鏈夊彲鑳戒笉閭d箞鍑嗙‘(灏ゅ叾鏄湪瓒呭嚭鑼冨洿鐨勬椂鍊). + float: 鍗曠簿搴︽诞鐐瑰瀷(4涓瓧鑺)锛屽ぇ姒7浣嶅乏鍙崇殑绮剧‘搴︺俧loat(M,D)琛ㄧず涓鍏卞瓨鍌∕涓湁鏁堟暟瀛楋紝鍏朵腑灏忔暟閮ㄥ垎鍗燚浣嶃 + 渚嬪瓙: + create table t_float( + f1 float, + f2 float(7,2), + f3 float(12,2) + ); + insert into t_float values (123.456,12345.67,12345678.90);--f3鐨勬暟鎹細涓㈠け,12345679.00; 娉ㄦ剰: 濡傛灉鏁版嵁绮惧害涓㈠け锛岄偅涔堟诞鐐瑰瀷鏄寜鐓у洓鑸嶄簲鍏ョ殑鏂瑰紡杩涜璁$畻銆 + double: 鍙岀簿搴︽诞鐐瑰瀷(8涓瓧鑺)锛屽ぇ姒15浣嶅乏鍙崇殑绮剧‘搴︼紝鏁版嵁鏈夊彲鑳戒笉閭d箞鍑嗙‘(灏ゅ叾鏄湪瓒呭嚭鑼冨洿鐨勬椂鍊). + 瀹氱偣鍨:鑳藉淇濊瘉绮剧‘鐨勫皬鏁(灏忔暟閮ㄥ垎鍙兘涓嶇簿纭紝瓒呭嚭闀垮害浼氬洓鑸嶄簲鍏)锛屾暣鏁伴儴鍒嗕竴瀹氱簿纭傛秹鍙婂埌閽辩殑鏃跺欐湁鍙兘浣跨敤瀹氱偣鏁般 + decimal(M,D):M琛ㄧず鎬婚暱搴,鏈澶у间笉鑳借秴杩65,D琛ㄧず灏忔暟閮ㄥ垎闀垮害锛屾渶闀夸笉鑳借秴杩30銆 + 渚嬪瓙: + create table t_decimal( + f1 float(10,2), + d2 decimal(10,2) + ); + insert into t_decimal values(12345678.90,12345678.90);--f1:12345679.00 | d2:12345678.90 + insert into t_decimal values(99999999.99,99999999.99);--f1:100000000.00 | d2:99999999.99 + insert into t_decimal values(99999999.99,99999999.999);--error + 3)鏃堕棿鏃ユ湡绫诲瀷: + Date:鏃ユ湡绫诲瀷 YYYY-mm-dd + Time:鏃堕棿绫诲瀷 HH:ii:ss + Datetime:鏃ユ湡鏃堕棿绫诲瀷 YYYY-mm-dd HH:ii:ss + Timestamp:鏃堕棿鎴崇被鍨 mysql涓殑鏃堕棿鎴冲彧鏄〃绀轰粠鏍兼灄濞佹不鏃堕棿寮濮嬶紝浣嗘槸鏍煎紡渚濈劧鏄 YYYY-mm-dd HH:ii:ss + 4)瀛楃涓茬被鍨: + char: 瀹氶暱瀛楃涓,鎸囧畾闀垮害鍚,绯荤粺涓瀹氫細鍒嗛厤鎸囧畾鐨勭┖闂寸敤浜庡瓨鍌ㄦ暟鎹;char(L) L(0~255)浠h〃瀛楃鏁帮紝鍝曞彧浣跨敤浜嗕竴涓瓧绗︼紝绯荤粺涔熷垎閰峀涓瓧绗﹂暱搴; + varchar: 鍙橀暱瀛楃涓诧紝鎸囧畾闀垮害鍚庯紝绯荤粺浼氭牴鎹疄闄呭瓨鍌ㄧ殑鏁版嵁鏉ヨ绠楅暱搴﹀垎閰嶅悎閫傜殑绌洪棿; varchar(L) L(0~65535)浠h〃瀛楃鏁; + text: 闀挎枃鏈; +7.鍒楀睘鎬(瀛楁灞炴): 鍦╩ysql涓竴鍏辨湁6涓睘鎬ull,榛樿鍊,鍒楁弿杩,涓婚敭,鍞竴閿,鑷姩澧為暱; + 鍒涘缓鏁版嵁琛: + 1)not null/default: + create table t_user( + name varchar(10) not null, + age int default 18 + ); + insert into t_user(name) values('Tony'); insert into t_user values('Tom',default); + 2)comment: + create table t_user( + name varchar(10) not null comment '鐢ㄦ埛鍚嶉潪绌', --鐢ㄦ埛鍚嶄笉鑳戒负绌 + age int default 18 + ); + 鏌ョ湅comment蹇呴』閫氳繃鏌ョ湅寤鸿〃璇彞: show create table t_user; + 3)primary key: 涓婚敭,鍦ㄥ悓涓寮犺〃鍐呮湁涓斾粎鏈変竴涓瓧娈碉紝閲岄潰鐨勫煎叿鏈夊敮涓鎬;涓婚敭涓鏃﹀鍔狅紝閭d箞瀵瑰簲鐨勫瓧娈垫湁鏁版嵁瑕佹眰:褰撳墠瀛楁涓嶈兘涓恒佸綋鍓嶅瓧娈典笉鑳介噸澶; + 鍒涘缓涓婚敭: + 闅忚〃鍒涘缓: + 绗竴绉:鐩存帴鍦ㄩ渶瑕佸綋浣滀富閿殑瀛楁鍚庯紝澧炲姞primary key灞炴ф潵纭畾涓婚敭; + create table t_user( + name varchar(10) primary key, + age int + ); + 绗簩绉:鍦ㄦ墍鏈夊瓧娈典箣鍚庡鍔爌rimary key閫夐」锛 primary key(瀛楁淇℃伅); + create table t_user( + name varchar(10), + age int, + primary key(name) + ); + 琛ㄥ悗澧炲姞: alter table 琛ㄥ悕 add primary key(瀛楁); + 4)auto_increment:鑷姩澧為暱,褰撶粰瀹氭煇涓瓧娈电殑鏌愪釜灞炴т箣鍚庯紝璇ュ垪鐨勬暟鎹湪娌℃湁鎻愪緵纭畾鏁版嵁鐨勬椂鍊欙紝绯荤粺浼氭牴鎹箣鍓嶅凡缁忓瓨鍦ㄧ殑鏁版嵁杩涜鑷姩閫掑鍚庯紝濉厖鏁版嵁; + alter table t_user add id int auto_increment; + create table t_user( + id int auto_increment, + name varchar(10), + age int, + primary key(id) + ); + insert into t_user(name,age) values('Tony',18);--id=1; + insert into t_user values(2,'Mary',18);--id=2; + insert into t_user(name,age) values('Jack',18);--id=3; + 鑷姩澧為暱閫氬父鐢ㄤ簬閫昏緫涓婚敭. + 5)unique key:鍞竴閿,鐢ㄦ潵淇濊瘉瀵瑰簲鐨勫瓧娈典腑鐨勬暟鎹槸鍞竴鐨;涓婚敭涔熷彲浠ョ敤鏉ヤ繚璇佸瓧娈垫暟鎹敮涓鎬э紝浣嗘槸涓寮犺〃涓彧鑳芥湁涓涓富閿; + 瑕佹眰:涓寮犺〃涓彲浠ユ湁澶氫釜;鍏佽瀛楁鏁版嵁涓簄ull锛宯ull鍙互鏈夊涓(null涓嶅弬涓庢瘮杈); + 鍒涘缓鍞竴閿: + 鐩存帴鍦ㄨ〃瀛楁涔嬪悗澧炲姞鍞竴閿爣璇嗙: unique [key] + 鍦ㄦ墍鏈夌殑瀛楁涔嬪悗浣跨敤 unique key(瀛楁鍒楄〃[,瀛楁鍒楄〃,...]) + 鍦ㄥ垱寤哄畬琛ㄥ悗涔熷彲浠ュ鍔犲敮涓閿; alter table 琛ㄥ悕 add unique key(瀛楁鍒楄〃[,瀛楁鍒楄〃,...]); +8.鏁版嵁鏌ヨ: + (1)绠鍗曟煡璇: + 鏌ヨ鎵鏈夊垪: select * from 琛ㄥ悕; + 鏌ヨ鎸囧畾鍒: select 瀛楁1, 瀛楁2 from 琛ㄥ悕; + 鍘婚噸: select distinct 瀛楁 from 琛ㄥ悕; + 鍦ㄦ煡璇㈠垪琛ㄤ腑鍙互浣跨敤绠楁湳琛ㄨ揪寮: select empno as "鍛樺伐缂栧彿", ename '鍛樺伐濮撳悕', sal*12 骞磋柂 from emp;--璧峰埆鍚嶆椂: as鍙互浣跨敤锛屼篃鍙互涓嶄娇鐢;鍒悕鍙互浣跨敤鍗曞弻寮曞彿锛岀敋鑷冲彲浠ヤ笉鐢ㄥ紩鍙; + (2)鏉′欢鏌ヨ: select 瀛楁鍒楄〃 from 琛ㄥ悕 [where 鏌ヨ鏉′欢]; + 1)浣跨敤=浣滀负鏌ヨ鏉′欢鎴栦娇鐢<>鍜!=浣滀负鏌ヨ鏉′欢鎴栦娇鐢<,<=,>,>=浣滀负鏌ヨ鏉′欢锛岄傜敤浜庢暟鎹簱鐨勪笁绉嶄富瑕佺被鍨(鏁板煎瀷,瀛楃涓茬被鍨,鏃ユ湡鍨);娉ㄦ剰:鍦ㄤ娇鐢ㄥ瓧绗︿覆绫诲瀷鍜屾棩鏈熺被鍨嬬殑鏁版嵁鏃讹紝蹇呴』瑕佷娇鐢''鎴""; + select * from emp where sal = 800;--鏌ヨ宸ヨ祫鏄800鐨勫憳宸ヤ俊鎭; + select * from emp where ename = '姝︽澗';--鏌ヨ鍛樺伐濮撳悕鏄"姝︽澗"鐨勫憳宸ヤ俊鎭; + select * from emp where hiredate != "1981-02-22";--鏌ヨ闆囦剑鏃ユ湡涓嶆槸"1981-02-22"鐨勫憳宸ヤ俊鎭; + select * from emp where sal <> 800;--鏌ヨ宸ヨ祫涓嶆槸800鐨勫憳宸ヤ俊鎭; + 琛ュ厖: + mysql鍦╳indow骞冲彴涓婇潰榛樿涓嶅尯鍒嗗ぇ灏忓啓,linux骞冲彴涓婂尯鍒嗗ぇ灏忓啓;--鏁版嵁搴撻噷鐨勫悕瀛楁槸"SMITH"; + select ename from emp where binary ename="smith";--鎴戜滑鍙互浣跨敤binary璁﹎ysql鍦╳indow骞冲彴涓婁篃涓ユ牸鍖哄垎澶у皬鍐; + select * from emp where binary lower(ename)="smith";--鍦ㄦ暟鎹簱涓ユ牸鍖哄垎澶у皬鍐欑殑鎯呭喌涓嬶紝蹇界暐瀛楃涓插ぇ灏忓啓; + 2)浣跨敤between and 浣滀负鏌ヨ鏉′欢锛屽湪鐗瑰畾鑼冨洿涔嬪唴: + select * from emp where sal between 1600 and 3000;--鍖呮嫭1600鍜3000; + select * from emp where hiredate between "1981-02-22" and "1981-05-01"; + 3)浣跨敤is null鎴杋s not null浣滀负鏌ヨ鏉′欢,瀵逛簬null鐨勫垽鏂笉鑳戒娇鐢=鍜!=鍜<>,鑰屾槸瑕佷娇鐢 is null杩涜鍒ゆ柇; + 4)浣跨敤and浣滀负鏌ヨ鏉′欢,and涔熷彲浠ヤ娇鐢&&鏉ヤ唬鏇; + select * from emp where sal>1200 && deptno=20;--鏌ヨ宸ヨ祫澶т簬1200骞朵笖閮ㄩ棬鍙蜂负20鐨勫憳宸ョ殑淇℃伅; + 5)浣跨敤or浣滀负鏌ヨ鏉′欢,or涔熷彲浠ヤ娇鐢▅|鏉ヤ唬鏇; + 6)and鐨勪紭鍏堢骇姣攐r楂: + select * from emp where sal>1200&&(deptno=20||30);--鏌ヨ宸ヨ祫澶т簬1200骞朵笖閮ㄩ棬缂栧彿涓20鎴30鐨勫憳宸; + 7)浣跨敤in浣滀负鏌ヨ鏉′欢,in琛ㄧず鍖呭惈鐨勬剰鎬: + select * from emp where job in("鎺ㄩ攢鍛","鍒嗘瀽甯"); + 8)浣跨敤not浣滀负鏌ヨ鏉′欢: + select * from emp where sal!=1600 and sal!=3000; + select * from emp where sal not in(1600,3000); + select * from emp where sal not(sal=1600 or sal=3000); + 9)浣跨敤like鎵ц妯$硦鏌ヨ: %琛ㄧず0~澶氫釜浠绘剰鐨勫瓧绗, _琛ㄧず涓涓换鎰忕殑瀛楃; + select * from emp where ename like "鏉%";--鏌ヨ鍚嶅瓧浠"鏉"寮澶寸殑鍛樺伐淇℃伅; + 10)浣跨敤order by瀛愬彞缁欐煡璇㈢粨鏋滄帓搴: 鍙互鎸夌収鍗曚釜瀛楁鎺掑簭,涔熷彲浠ユ寜鐓у涓瓧娈垫帓搴; + select * from emp order by sal desc;--asc鍗囧簭(榛樿鍗囧簭,鍙笉鍐),desc闄嶅簭; + 鎸夌収澶氫釜瀛楁鎺掑簭,姣忎釜瀛楁鍙互鎸囧畾涓嶅悓鐨勬帓搴忚鍒 + select * from emp where sal>1200 order by deptno [asc], sal desc;--鏌ヨ宸ヨ祫澶т簬1200鐨勫憳宸ヤ俊鎭,骞舵寜鐓eptno鍗囧簭(榛樿鍗囧簭,鍙笉鍐)鍜宻al闄嶅簭鎺掑垪; + (3)鏁版嵁搴撳嚱鏁: + 鍗曡鍑芥暟: + 1)lower(str): 鎶婂瓧绗﹀瀷鏁版嵁杞崲涓哄皬鍐欑殑瀛楃; + 2)upper(str): 鎶婂瓧绗﹀瀷鏁版嵁杞崲涓哄ぇ鍐欑殑瀛楃; + 3)substr(琚埅鍙栧瓧绗︿覆鐨勫悕瀛,璧峰涓嬫爣,鎴彇闀垮害): 鎴彇瀛楃涓; + select substr(ename,2,1) from emp;--浠庡憳宸ュ悕瀛楃殑绗簩涓瓧绗﹀紑濮嬫埅鍙,鎴彇涓涓瓧绗﹂暱搴; + 4)length(str): 杩斿洖瀛楃涓插崰鐢ㄧ殑瀛楄妭鏁;gbk涓涓眽瀛楀崰涓や釜瀛楄妭,utf8鏄笁涓瓧鑺; + 5)char_length(str): 杩斿洖瀛楃涓蹭腑鏈夊灏戜釜瀛楃; + select ename, length(ename)/3 from emp;--鏌ヨ鍛樺伐鐨勫悕瀛椾互鍙婂悕瀛楃殑闀垮害; + select ename, char_length(ename) from emp; + 6)trim(): 鍘婚櫎瀛楃涓插瀷鏁版嵁鐨勫墠鍚庣┖鏍; + select trim(" 1 2 3 ");--1 2 3,oracle涓繀椤诲啓鏌愪竴涓〃,mysql涓笉鍐欑殑璇,榛樿浠庣郴缁熻〃涓煡璇; + 7)round(): 瀵规暟鍊煎瀷鏁版嵁杩涜鍥涜垗浜斿叆鎿嶄綔; + select round(176.56);--榛樿绮剧‘鍒颁釜浣; + select round(176.56,1);--绮剧‘鍒板皬鏁扮偣鍚1浣; + select round(176.56,-1);--绮剧‘鍒板皬鏁扮偣鍓1浣; + 8)ifnull(): 绌哄煎鐞嗗嚱鏁,null琛ㄧず娌℃湁鏁版嵁;鍦ㄧ畻鏈腑濡傛灉鍑虹幇null,缁撴灉鑲畾鏄痭ull; + select (sal+ifnull(comm,0))*12 "骞磋柂" from emp; + 9)case when鍑芥暟: 鎵ц鍒嗘敮璇彞鐨勫嚱鏁; + --鍖归厤宸ヤ綔宀椾綅,褰撲负缁忕悊鏃,钖按涓婅皟10%,褰撲负鍒嗘瀽甯堟椂,钖按涓婅皟50%,鍏跺畠宀椾綅涓嶅彉; + select empno,ename,job,sal as '鍘熸潵鐨勮柂姘', (case job when '缁忕悊' then sal*1.1 when '鍒嗘瀽甯' then sal*1.5 else sal end) as '鏂扮殑钖按' from emp; + 10)str_to_date(str,format): 鎶婂瓧绗︿覆杞崲涓烘棩鏈熺殑鍑芥暟 + select * from emp where hiredate = "1981-02-22"; + --mysql浼氳嚜鍔ㄧ殑璋冪敤str_to_date(str,format)鍑芥暟,鎶婂瓧绗﹀瀷鏁版嵁杞崲涓烘棩鏈熷瀷鐨勬暟鎹,鐒跺悗鍐嶅幓鍜宧iredate杩涜姣旇緝; + --mysql榛樿鐨勬棩鏈熸牸寮忔槸"骞-鏈-鏃";涓婇潰璇彞鐨勫疄闄呮墽琛岃繃绋嬪涓: + select * from emp where hiredate = str_to_date("1981-02-22","%Y-%m-%d");--娉ㄦ剰: 浣跨敤str_to_date(str,format)鐨勬椂鍊,鏃ユ湡瀛楃涓查渶涓巉ormat瀛楃涓茬殑鏍煎紡涓鑷,杞崲鎵嶈兘鎴愬姛; + --鍦╩ysql涓彁渚涗簡涓涓猲ow()鍑芥暟,鍙互鑾峰緱褰撳墠鏃堕棿鐐圭殑鏃ユ湡瀵硅薄(骞存湀鏃); + update emp set hiredate=now() where empno=7521; + 11)date_format(date,format): 鎶婃棩鏈熷瀷鐨勬暟鎹浆鎹负鐗瑰畾鏍煎紡鐨勫瓧绗︿覆 + select ename, hiredate from emp; + --mysql浼氳嚜鍔ㄧ殑璋冪敤date_format(date,format)鍑芥暟,鎶婃棩鏈熷瀷鏁版嵁杞崲涓哄瓧绗︿覆鍨嬬殑鏁版嵁;瀹為檯鎵ц杩囩▼濡備笅: + select ename,date_format(hiredate,"%Y-%m-%d") from emp;--鍙鎸囧畾涓涓棩鏈熸ā鏉垮氨鍙互鎶婃棩鏈熷瀷鐨勬暟鎹浆鎹负浠绘剰鏍煎紡鐨勫瓧绗︿覆; + 澶氳鍑芥暟(鑱氬悎鍑芥暟,鍒嗙粍鍑芥暟): + 娉ㄦ剰浜嬮」: + 1)澶氳鍑芥暟浼氳嚜鍔ㄥ拷鐣ョ┖鍊(null),涓嶉渶瑕佹墜鍔ㄧ敤where鎺掗櫎绌哄; + 2)澶氳鍑芥暟涓嶈兘鍑虹幇鍦╳here瀛愬彞涓; + 3)澶氳鍑芥暟涓嶈兘宓屽; + 甯哥敤澶氳鍑芥暟: + 1)sum(): 姹傛诲拰; + --鏌ヨemp琛ㄧ殑鏈堟敹鍏ユ诲拰: + select sum(sal+comm) from emp;--閿欒鐨,灏唖al+comm鐨勭粨鏋滀笉涓簄ull鐨勬眰鍜屼簡; + select sum(sal+ifnull(comm,0)) from emp;--姝g‘鐨; + select sum(sal)+sum(comm) from emp;--姝g‘鐨; + 2)count(): 鏌ヨ鏁版嵁鎬诲拰; + count(*): 鏌ヨ鎵鏈夌殑 璁板綍鎬绘暟; + count(瀛楁): 鏌ヨ鎸囧畾瀛楁涓嶄负null鐨勬暟鎹绘暟; + 3)avg(): 鏌ヨ骞冲潎鍊; select avg(sal) from emp; + 4)max(): 鏌ヨ鏈澶у; select max(sal),max(hiredate) from emp; + 5)min(): 鏌ヨ鏈灏忓; select min(sal),min(hiredate) from emp; + (4)鍒嗙粍鏌ヨ: 鍒嗙粍鏌ヨ闇瑕佷娇鐢╣roup by瀛愬彞;鎶婃暟鎹寜鐓х壒瀹氱殑鏉′欢鍒掑垎涓哄缁,鐒跺悗鍒嗗埆浣跨敤缁勫嚱鏁拌繘琛屾煡璇;鎶婃暟鎹垝鍒嗕负澶氬皯缁,鏈缁堝氨浼氬緱鍒板灏戞潯缁撴灉; + 璇硶: select 鏌ヨ鍒楄〃 from 琛ㄥ悕 group by 鍒嗙粍瀛楁; + 瑙勫垯: 鍑虹幇鍦ㄦ煡璇㈠垪琛ㄤ腑鐨勫瓧娈,瑕佷箞鍑虹幇鍦ㄧ粍鍑芥暟涓,瑕佷箞鍑虹幇鍦╣roup by涓;鎴栬呭垎缁勫瓧娈典粎浠呭嚭鐜板湪group by瀛愬彞涓; + 渚嬪瓙: + 1)鎸夌収鍗曚釜瀛楁杩涜鍒嗙粍: + select deptno,max(sal) from emp group by deptno;--鎶婃墍鏈夌殑鍛樺伐鎸夌収閮ㄩ棬缂栧彿鍒嗙粍,鏌ヨ鏈楂樺伐璧; + 鎸夌収閮ㄩ棬缂栧彿鍒嗙粍,鏌ヨ鏈楂樺伐璧勪互鍙婃渶楂樺伐璧勭殑鍛樺伐濮撳悕 + select ename,max(sal),deptno from emp group by deptno;--閿欒鐨,鍑虹幇鍦ㄦ煡璇㈠垪琛ㄤ腑鐨別name鍗虫病鏈夊嚭鐜板湪缁勫嚱鏁颁腑,涔熸病鏈夊嚭鐜板湪group by瀛愬彞涓,杩欐槸涓嶇鍚堣鍒欑殑;杩欐牱鐨勮鍙ュ湪Oracle涓棤娉曟墽琛,mysql涓兘澶熸墽琛,浣嗙粨鏋滀笉绗﹀悎棰勬湡闇姹; + 2)鎸夌収澶氫釜瀛楁杩涜鍒嗙粍: + select deptno,job,max(sal) from emp group by deptno,job;--鎸夌収閮ㄩ棬缂栧彿鍜岃亴浣嶈繘琛屽垎缁,鏌ヨ鏈楂樺伐璧; + 3)瀵瑰垎缁勪箣鍚庣殑鏁版嵁杩涜杩囨护,闇瑕佷娇鐢╤aving瀛愬彞: + select deptno,avg(sal) as '骞冲潎宸ヨ祫' from emp group by deptno having avg(sal)>2000;--鎸夌収閮ㄩ棬缂栧彿鍒嗙粍,鏌ヨ骞冲潎宸ヨ祫,骞朵笖鏄剧ず骞冲潎宸ヨ祫澶т簬2000鐨勮褰; + select deptno,avg(sal) avgsal from emp group by deptno having avgsal>2000;--涓庝笂涓鏉$瓑鏁; + select deptno,avg(sal) from emp where comm is null group by deptno having avg(sal)>2000 order by avg(sal);--鎶婃触璐翠负null鐨勫憳宸ユ寜鐓ч儴闂ㄧ紪鍙峰垎缁勬煡璇㈠钩鍧囧伐璧,骞朵笖鏄剧ず骞冲潎宸ヨ祫澶т簬2000鐨勬暟鎹,鐒跺悗鎸夌収骞冲潎宸ヨ祫鎺掑簭(鍗囧簭); + 4)鏌ヨ鍙ュ紡鍙婇『搴: + select 鏌ヨ鍒楄〃 + from 琛ㄥ悕 + where 鏌ヨ鏉′欢 + group by 鍒嗙粍鏉′欢 + having 鏌ヨ鏉′欢 + order by 鎺掑簭鏉′欢 + from,where,group by,having,select,order by; + (5)limit瀛愬彞(鏂硅█): 鐢ㄦ潵闄愬畾鏌ヨ缁撴灉鐨勮捣濮嬭浠ュ強鎬昏鏁般 + 鍒嗛〉鏌ヨ:limit 璧峰琛,椤靛ぇ灏; 璧峰琛=(椤电殑绱㈠紩-1)*椤靛ぇ灏; 椤靛ぇ灏=椤靛ぇ灏; + 渚嬪锛歴elect * from emp limit 4,3;--鏌ヨ璧峰琛屼负绗5琛岋紝涓鍏辨煡璇3琛岃褰曘 + 渚嬪瓙:EmpManageByMysql: https://github.com/ZichengQu/Java/tree/JavaWeb/JSP/EmpManageByMysql + public static Connection getConnection(){//浣跨敤JDBC杩炴帴mysql鏁版嵁搴 + Connection conn = null; + try { + //鍔犺浇椹卞姩 + Class.forName("com.mysql.jdbc.Driver"); + String url = "jdbc:mysql://localhost:3306/empdb";//鎸囧畾杩炴帴鐨勬暟鎹簱鍚嶇О涓篹mpdb + String user = "root"; + String password = "root"; + //鑾峰彇杩炴帴瀵硅薄 + conn = DriverManager.getConnection(url, user, password); + System.out.println("浣跨敤DBUtil杩炴帴Oracle鎴愬姛!"); + } catch (Exception e) { + e.printStackTrace(); + } + return conn; + } + (6)澶氳〃鏌ヨ: + 鎸夌収杩炴帴鐨勬柟寮: + 1)鍐呰繛鎺: 鍙互鏌ヨ婊¤冻涓涓瀵瑰簲鍏崇郴鐨勬暟鎹: 渚嬪杩欎釜鍛樺伐鏈夋墍灞炵殑閮ㄩ棬,杩欎釜閮ㄩ棬鏈夋墍灞炵殑鍛樺伐,杩欐牱鐨勬暟鎹弧瓒充竴涓瀵瑰簲鐨勫叧绯,鍙互浣跨敤鍐呰繛鎺ユ煡璇㈠嚭鏉; + 鍐呰繛鎺ュ垎绫: + 绛夊艰繛鎺: 寤虹珛鍦ㄧ埗瀛愯〃鍏崇郴涓,鐢ㄧ瓑鍙锋潵杩炴帴涓や釜琛; + select ename,sal,job,e.deptno,dname from emp e, dept where e.deptno=dept.deptno and e.deptno=20;--鏌ヨ鍛樺伐琛ㄥ強鍏堕儴闂ㄤ俊鎭; + select ename,sal,job,e.deptno,dname from emp e inner join dept on e.deptno=dept.deptno and e.deptno=20;--鍙互浣跨敤and鎴杦here鍦ㄥ叾鍚庤拷鍔犳潯浠; + 闈炵瓑鍊艰繛鎺: 涓や釜琛ㄤ箣闂存病鏈夌埗瀛愬叧绯,鐢ㄩ潪绛夊彿鏉ヨ繛鎺ヤ袱涓〃; + select e.empno, e.ename, e.sal, s.grade from emp e, salgrade s where e.sal between s.losal and s.hisal;--CREATE TABLE salgrade(grade INT PRIMARY KEY, losal INT, hisal INT);鎻掑叆鏁版嵁; + select e.empno, e.ename, e.sal, s.grade from emp e INNER JOIN salgrade s on e.sal between s.losal and s.hisal;--涓庝笂涓鏉$瓑鏁; + 鑷繛鎺: 浣跨敤鍒悕灏嗕竴涓〃铏氭嫙鎴愪袱涓〃(鐖跺瓙琛),鐒跺悗鍐嶈繖涓や釜琛ㄤ笂浣滅瓑鍊艰繛鎺; + select e.empno "鍛樺伐缂栧彿",e.ename "鍛樺伐濮撳悕",m.empno "缁忕悊缂栧彿", m.ename "缁忕悊濮撳悕" from emp e,emp m where e.mgr=m.empno;--鏌ヨ鍛樺伐鐨勪俊鎭強鍏剁洿鎺ラ瀵肩殑淇℃伅 + 2)澶栬繛鎺: 鍙互鏌ヨ涓嶆弧瓒充竴涓瀵瑰簲鍏崇郴鐨勬暟鎹: 渚嬪鏈夌殑鍛樺伐娌℃湁鎵灞為儴闂,鏈夌殑閮ㄩ棬娌℃湁鍛樺伐,杩欐牱鐨勬暟鎹笉婊¤冻涓涓瀵瑰簲鐨勫叧绯,鍙互浣跨敤澶栬繛鎺ユ煡璇㈠嚭鏉; + 澶栬繛鎺ュ垎绫: + 宸﹀杩炴帴(left outer join): 鍙互鎶婂乏琛ㄤ腑涓嶆弧瓒冲搴斿叧绯荤殑鏁版嵁鏌ヨ鍑烘潵; + select * from emp left join dept on emp.deptno=dept.deptno; + 鍙冲杩炴帴(right outer join): 鍙互鎶婂彸琛ㄤ腑涓嶆弧瓒冲搴斿叧绯荤殑鏁版嵁鏌ヨ鍑烘潵; + select * from emp right join dept on emp.deptno=dept.deptno; + 鍏ㄥ杩炴帴(full outer join)(涓嶆敮鎸): 鍙互鎶婂乏鍙充袱涓〃涓笉婊¤冻瀵瑰簲鍏崇郴鐨勬暟鎹煡璇㈠嚭鏉; + select * from emp full join dept on emp.deptno=dept.deptno;--mysql涓嶆敮鎸佸叏澶栬繛鎺,鍥犳姝ゆ煡璇㈣鍙ヤ細鎶ラ敊; + (7)瀛愭煡璇: 鐢ㄦ潵缁欎富鏌ヨ鎻愪緵鏌ヨ鏉′欢鎴栨煡璇㈡暟鎹岄鍏堟墽琛岀殑涓涓煡璇;涓绘煡璇娇鐢ㄥ瓙鏌ヨ鐨勭粨鏋;瀛愭煡璇㈠繀椤昏鏀惧湪()閲岄潰; + 瀛愭煡璇㈠垎绫: + 1)鍑虹幇鍦╳here涓殑瀛愭煡璇,鐢ㄦ潵缁欎富鏌ヨ鎻愪緵鏌ヨ鏉′欢; + select * from emp where sal<(select avg(sal) from emp);--鏌ヨ宸ヨ祫姣斿钩鍧囧伐璧勪綆鐨勫憳宸ヤ俊鎭; + 2)鍑虹幇鍦╢rom鍚庨潰鐨勫瓙鏌ヨ,鐢ㄦ潵缁欎富鏌ヨ鎻愪緵鏁版嵁鐨; + 3)鍑虹幇鍦ㄦ煡璇㈠垪琛ㄤ腑鐨勫瓙鏌ヨ,鍔熻兘绫讳技浜庡杩炴帴鐨勬晥鏋(浜嗚В); + select e.empno,e.ename,e.job,e.sal,e.deptno,(select dname from dept d where e.deptno=d.deptno) dname from emp e; + (8)union: 浣跨敤union鎶婁袱涓粨鏋滃悎骞舵垚涓涓粨鏋 + union(浼氬悎骞剁浉鍚岀殑鏁版嵁), union all(涓嶄細鍚堝苟鐩稿悓鐨勬暟鎹); + 娉ㄦ剰: 鍚堝苟涓や釜鏌ヨ缁撴灉鐨勬椂鍊,瑕佹眰涓や釜鏌ヨ缁撴灉鐨勭粨鏋滃繀椤昏涓鑷(鏌ヨ瀛楁鐨勪釜鏁,瀛楁鐨勭被鍨,瀛楁鐨勯『搴忓繀椤昏涓鑷); + select * from emp where sal>1500 union select * from emp where deptno=20; +9.鏁版嵁搴撲簨鍔″鐞: + 1)鎶婂涓浉鍏崇殑鎿嶄綔鎹嗙粦鎴愪竴涓暣浣,瑕佷箞閮芥垚鍔,瑕佷箞閮藉け璐; + 2)鍙湁DML(鏁版嵁鎿嶄綔璇█)璇彞鎵嶄細寮曡捣涓涓簨鍔; + 3)浜嬪姟鐨勫洓涓壒鎬э細 + 鍘熷瓙鎬(Atomicity): +銆 銆 鍘熷瓙鎬ф槸鎸囦簨鍔″寘鍚殑鎵鏈夋搷浣滆涔堝叏閮ㄦ垚鍔熷叏閮ㄥ簲鐢紝瑕佷箞鍏ㄩ儴澶辫触鍥炴粴銆傚洜姝や簨鍔$殑鎿嶄綔濡傛灉鎴愬姛灏卞繀椤昏瀹屽叏搴旂敤鍒版暟鎹簱锛屽鏋滄搷浣滃け璐ュ垯涓嶈兘瀵规暟鎹簱鏈変换浣曞奖鍝嶃 + 涓鑷存(Consistency): + 涓鑷存ф槸鎸囦竴涓簨鍔℃墽琛屼箣鍓嶅拰鎵ц涔嬪悗閮藉繀椤诲浜庝竴鑷存х姸鎬併傛嬁杞处鏉ヨ锛屽亣璁剧敤鎴稟鍜岀敤鎴稡涓よ呯殑閽卞姞璧锋潵涓鍏辨槸5000锛岄偅涔堜笉绠鍜孊涔嬮棿濡備綍杞处锛岃浆鍑犳璐︼紝浜嬪姟缁撴潫鍚庝袱涓敤鎴风殑閽辩浉鍔犺捣鏉ュ簲璇ヨ繕寰楁槸5000锛岃繖灏辨槸浜嬪姟鐨勪竴鑷存с + 闅旂鎬(Isolation): +銆銆 闅旂鎬ф槸鎸囧涓苟鍙戜簨鍔′箣闂磋鐩镐簰闅旂銆傚綋澶氫釜鐢ㄦ埛骞跺彂璁块棶鏁版嵁搴撴椂锛屾瘮濡傛搷浣滃悓涓寮犺〃鏃讹紝鏁版嵁搴撲负姣忎竴涓敤鎴峰紑鍚殑浜嬪姟锛屼笉鑳借鍏朵粬浜嬪姟鐨勬搷浣滄墍骞叉壈銆 + 鎸佷箙鎬(Durability): +銆銆 鎸佷箙鎬ф槸鎸囦竴涓簨鍔′竴鏃﹁鎻愪氦浜嗭紝閭d箞瀵规暟鎹簱涓殑鏁版嵁鐨勬敼鍙樺氨鏄案涔呮х殑锛屽嵆渚挎槸鍦ㄦ暟鎹簱绯荤粺閬囧埌鏁呴殰鐨勬儏鍐典笅涔熶笉浼氫涪澶辨彁浜や簨鍔$殑鎿嶄綔銆 + 4)mysql绠$悊浜嬪姟鐨勯粯璁ゆ柟寮忔槸: 鑷姩鎻愪氦; + start transaction: 鍏抽棴鏈鑷姩鎻愪氦浜嬪姟; + 鍏抽棴鑷姩鎻愪氦涔嬪悗鎵ц鐨勭涓涓狣ML璇彞浼氬紩璧蜂竴涓簨鍔;鍦ㄤ簨鍔″紑鍚箣鍚,鍙浜嬪姟娌℃湁缁撴潫,鎵ц鐨勬墍鏈塂ML鎿嶄綔閮芥槸闅跺睘浜庡悓涓涓簨鍔$殑;浜嬪姟涓鏁版嵁鐨勪慨鏀硅淇濆瓨鍦ㄥ唴瀛樹腑;鍙湁褰撳墠浜嬪姟鍙互鏌ヨ鍒拌繖浜涗慨鏀; + insert into dept values(50,"",""); + insert into dept values(60,"",""); + update dept set dname="鐮斿彂閮",loc="娌堥槼" where deptno>40; + select * from dept; + 鍏抽棴浜嬪姟 + commit: 鎻愪氦缁撴潫浜嬪姟鐨勬椂鍊,浜嬪姟涓鏁版嵁搴撶殑淇敼琚案涔呯殑淇濆瓨鍒版暟鎹簱涓,鎵鏈夌殑浼氳瘽鍙互鏌ヨ鍒拌繖浜涗慨鏀; + rollback: 鍥炴粴缁撴潫浜嬪姟鐨勬椂鍊,浜嬪姟涓鏁版嵁搴撶殑淇敼琚叏閮ㄦ斁寮,鏁版嵁搴撴仮澶嶅埌浜嬪姟寮濮嬩箣鍓嶇殑鐘舵; + 5)浜嬪姟鐨勯殧绂荤骇鍒: + 骞跺彂浜嬪姟闂: + 鑴忚: 璇诲埌鍙︿竴涓簨鍔$殑鏈彁浜ゆ洿鏂版暟鎹,鍗宠鍒颁簡鑴忔暟鎹; + 涓嶅彲閲嶅璇: 瀵瑰悓涓璁板綍鐨勪袱娆¤鍙栦笉涓鑷,鍥犱负鍙︿竴涓簨鍔″璇ヨ褰曡繘琛屼簡淇敼; + 骞昏(铏氳): 瀵瑰悓涓寮犺〃鐨勪袱娆℃煡璇笉涓鑷,鍥犱负鍙︿竴涓簨鍔℃彃鍏ヤ簡涓鏉¤褰; + 鍥涘ぇ闅旂绾у埆: + 涓茶鍖: serializable; + 涓嶄細鍑虹幇浠讳綍骞跺彂闂,鍥犱负瀹冨鍚屼竴鏁版嵁鐨勮闂槸涓茶鐨(闈炲苟鍙戣闂),鎬ц兘鏈宸; + 鍙噸澶嶈: repeatable read --mysql榛樿鐨勯殧绂荤骇鍒 + 鍙槻姝㈣剰璇诲拰涓嶅彲閲嶅璇,鎬ц兘姣攕erializable濂; + 璇诲彇宸叉彁浜: read committed --oracle榛樿鐨勯殧绂荤骇鍒 + 闃叉鑴忚,鎬ц兘姣攔epeatable read濂; + 璇诲彇鏈彁浜ょ殑鏁版嵁: read uncommitted --浼氳剰璇 + 鍙兘鍑虹幇浠讳綍浜嬪姟骞跺彂闂;鎬ц兘鏈濂; + mysql鐨勯殧绂荤骇鍒: + mysql鐨勯粯璁ら殧绂荤骇鍒负repeatable read,鍙互閫氳繃 select @@tx_isoliation 鏌ョ湅; + 涔熷彲浠ラ氳繃 set transaction isolationlevel [4閫1] 鏉ヨ缃綋鍓嶈繛鎺ョ殑闅旂绾у埆; + + + + \ No newline at end of file diff --git "a/JDBC/src/note/sql/Oracle\345\216\237\345\247\213\347\254\224\350\256\260.txt" "b/JDBC/src/note/sql/Oracle\345\216\237\345\247\213\347\254\224\350\256\260.txt" new file mode 100644 index 0000000..d971d98 --- /dev/null +++ "b/JDBC/src/note/sql/Oracle\345\216\237\345\247\213\347\254\224\350\256\260.txt" @@ -0,0 +1,810 @@ +软件的构成? +1、前端 HTML、CSS、JS、JQuery +2、后台 java +3、数据库 Oracle Mysql(甲骨文) + +1.安装Oracle + + 常用用户: + sys:超级用户 具有最高权限 具有sysdba角色 (数据库管理员) + 有创建数据库的权限 + system:管理操作员 权限仅次于超级管理员 + + scott:普通用户 一般用于练习 scott -- tiger + 解锁用户:alter user scott account unlock + 设置密码:alter user scott identified by tiger + +2.登录方式 + 1)sqlplus 回车 + 输入用户名 + 输入密码 + + 2)sqlplus/nolog + conn scott/tiger + +3. DB:DataBase 按照数据结构来管理数据的仓库 + 关系型数据库 + 以二维表形式存储数据(表的列:字段名 表的行:数据) + + + DBMS:数据库管理系统 + mysql、oracle、SqlServer +4.常用命令 + sqlplus 打开数据库 + conn 用户名/密码 连接数据库 + show user; 显示当前用户 + exit; 断开连接 + quit; 断开连接 +5.SQL:结构化查询语言 + SQL的分类:***** + DDL 数据定义语言 用于操作数据对象(表 视图 序列 索引) + DML 数据操作语言 用于增删改表中的数据(通常伴随事务) + TCL 事务控制语言 用于数据的提交和撤销 + DQL 数据查询语言 用于查询数据记录 + DCL 数据控制语言 用于执行权限分配 + + DDL:数据定义语言 + ---用于操作数据库对象(表 视图 序列 索引) + CREATE:用来创建表或其他对象 + ALTER:修改表或其他对象的结构 + DROP:删除表或其他对象的结构 + TRUNCATE:清空表(删除表中数据,保留表结构) + DML:数据操作语言 + ---用于增删改表中的数据(通常伴随事务) + INSERT INTO:将数据插入到表中 + DELETE:删除表中数据 ---- WHERE + UPDATE 表名 SET:更新表中数据 --- WHERE + + TCL:事务控制语言 + COMMIT:提交--保存 + ROLLBACK:回滚---后退 + + DQL:数据查询语言 + SELECT 查询***** + + DCL:数据控制语言 + 用来执行权限分配 GRANT REVOKE +6.DDL 数据定义语言 + 1、创建表 + 查看用户定义的表: + SELECT table_name FROM user_tables; + CREATE TABLE 表名 ( + 列名(字段名) 数据类型 [默认值 约束], + 列名(字段名) 数据类型 [默认值 约束], + 列名(字段名) 数据类型 [默认值 约束], + 列名(字段名) 数据类型 [默认值 约束] + ); + CREATE TABLE users( + id number(10) primary key, + name varchar2(20) not null unique, + salary number(10,2), + create_time date default sysdate + ); + id(主键) 特点:该列在整张表中每一行所保存的值都不相同,且必须有值(非空且唯一)PRIMARY KEY + 命名规则: + 表名和列名: + 1)必须以字母开头 + 2)必须在1-30个字符之间 + 3)必须只能包含A-Z,a-z,0-9,_,$,和# + 4)必须不能和用户定义的其他对象重名 + 5)必须不能是Oracle的保留字 + 数据类型: + 1)NUMBER:数值类型 + NUMBER(X):x代表位数 + NUMBER(3) 最多能存放3位数 + NUMBER(X,Y):x表示共几位 y表示其中有几位是小数 + NUMBER(6,2) 8888.88 + 2)CHAR:定长字符串 + CHAR(X):X表示共占多少字节 最多放2000字节 + 3)VARCHAR2:变长字符串 + VARCHAR2(X):X表示共占多少字节(根据其中保存的数据长度,占用的空间是变化的) 最多4000字节 + 4)DATE 时间日期 + SELECT SYSDATE FROM DUAL + 伪表:dual确实是一张表,是一张只有一个字段,一行记录的表,习惯上我们称之为伪表,因为它不存储 + 具体的数据 + 2、删除表: + DROP TABLE users; + 3、ALTER:修改表 + 修改表名: + RENAME 原表名 TO 新表名 + 修改表结构: + 向表中添加字段: + ALTER TABLE 表名 ADD(字段名 数据类型[默认值 约束]) + 列只能添加在最后,不能插入到现有的列中 + 删除表中已有字段: + ALTER TABLE 表名 DROP(字段名) + 修改表中已有字段的格式: + ALTER TABLE 表名 MODIFY(字段名 数据类型[默认值 约束]) +7、DML 数据操作语言 + 1、向表中添加数据 + 全字段插入数据: + INSERT INTO 表名 VALUES(1,'张三',8000,sysdate,'程序员'); + 注意:values中的数据顺序要和定义字段时一致 + 部分字段插入数据 + INSERT INTO 表名(想要插入数据的字段) VALUES(与字段顺序相对应的数据) + 2、修改表中已有数据 + 在修改表中数据时,通常添加where子句来限定要修改的记录,这样就只能修改满足where条件的记录, + 否则是全表修改 + UPDATE 表名 SET 字段名=数据,字段名=数据 WHERE 字段名=数据 + 3、删除表中数据 + 通常与where子句连用,否则的话是删除所有数据 + DELETE FROM 表名 WHERE 字段名=数据 + 在DDL语句中的TRUNCATE语句,同样有删除表数据的作用 + 和delete的区别: + --delete可以有条件删除,truncate将表数据全部删除 + --delete是DML,可以回退,truncate是DDL语句,立即生效,无法回退 + --如果是删除全部表记录,且数据量较大,delete语句效率比truncate语句低 + 删除全部记录: + delete from users; + 或者 + truncate table users; +8.TCL 事务控制语言 + commit 提交 + 显示:语句 按钮 + 隐式:正常关闭数据库工具 + rollback 回滚---后退 + 事务的四个特性:***** + 1.原子性:事务包含的所有操作要么全部成功,要么全部失败回滚;成功必须要完全应用到数据库,失败则不能对数据库 + 产生影响; + 2.一致性:事务执行前和执行后必须处于一致性状态, + 3.隔离性:当多个用户并发访问数据库时,数据库为每一个用户开启的事务,不被其他事务的操作所干扰,多个并 + 发事务之间要相互隔离; + 4.持久性:一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的 +9.DQL 数据查询语言 + 基本查询语句由SELECT子句和FROM子句组成 + SELECT:指定要显示的字段名称 + FROM:指定数据来源 + 1)查询所有 + SELECT * FROM 表名; + 2)查询部分数据信息 + SELECT 字段名称1,字段名称2 FROM 表名 WHERE 限定条件; + 注意:SELECT 可以显示字段、表达式、函数 + <>是不等于 + 若函数名称较长,不利于查询结果的列名显示,则可以给查询结果的列使用列别名 + 别名不能以数字开头,若以数字开头别名需要用""括上,同样不能以符号开头 + +10、常用函数 + 1)字符串函数 + CONCAT(c1,c2)连接字符串,将c1,c2两个字段拼接显示 + ||连接字符串符号(多个字符串连接,用||更直观) + SELECT ename || ':'|| sal as "姓名:工资" from EMP + + LENGTH(字段名)显示字符串长度 + SELECT length(ename) from emp + + UPPER(字段名)转大写 + LOWER(字段名)转小写 + INITCAP(字段名)首字母大写 + + TRIM() 去除字符串前后指定内容 + select trim('E' from 'EEEEEHELLO WORLDE') from dual + + 去除员工表中名字的首字母A + select ename,trim('A' FROM ename) from emp + + LTRIM('字符串','')去除字符串左侧指定内容 + RTRIM('字符串','')去除字符串右侧指定内容 + + LPAD(ch1,m,ch2) + RPAD(ch1,m,ch2) + 补位函数 + ch1要查询显示的内容 m指定位数 + ch2数据位数不足时由什么进行补位 + 在emp表中使用左补位,将sql用0补齐6位 + select ename,rpad(sal,6,'$') from emp + SUBSTR(ch,m,n):截取字符串--从1开始 + 截取ch这个字符串,从m开始截取,共截取n个 + 若m为负数,则是从后向前进行下标查询从而进行截取 + INSTR(ch1,ch2,m,n):查找ch1中ch2出现的位置,m代表从哪个位置开始检索,n代表第几次出现 + 不指定m和n,默认值都是1 + 2)数字函数 + ROUND(n,m):用于四舍五入 + 参数中的n可以是任何数字,指要被处理的数字 + m必须是整数,m取正数则四舍五入到小数点后第m位 + m取0则四舍五入到整数位 + m取负数,则四舍五入到小数点前m位 + m缺省,默认值是0 + TRUNC(n,m):截取数字,没有四舍五入 + select trunc(45.678,2),trunc(45.678,0),trunc(45.678,-1) from dual + MOD(m,n):返回m除以n后的余数,n为0则直接返回M + 薪水值按1000取余数 + select ename,sal,mod(sal,1000) from emp + CEIL(n):向上取整 大于该数的最小整数 + FLOOR(n):向下取整 小于该数的最大整数 + 3)日期函数 + sysdate:返回当前的系统时间,精确到秒 select sysdate from dual + systimestamp:返回当前系统日期和时间,精确到毫秒(时间戳) + 1)TO_DATE():相当于是SimpleDateFormat的parse()方法 + 作用:将给定的字符串按照给定的日期格式转换为Date + select to_date('2018-12-01 11:30','YYYY-MM-DD HH24:MI:SS') from dual + 2)TO_CHAR():用于将DATE按照给定的日期格式转换为字符串 + select ename,to_char(hiredate,'YYYY"年"MM"月"DD"日"') from emp + 日期常用函数: + 1)LAST_DAY(date):返回指定日期所在月的最后一天 + select last_day(sysdate) from dual + 2)ADD_MONTHS(date,i):返回日期date加上i个月后的日期值,若果i是负数,则获得的是减去i个月后的 + 日期值 + 查询员工入职20周年纪念日 + select ename,add_months(hiredate,20*12) "20周年" from emp + 3)MONTHS_BETWEEN(date1,date2):计算两个日期之间相差多少个月 + 实际运算的是date1-date2,如果date2时间比date1时间晚,会得到负值,除非两个日期间隔是整数月, + 否则会得到带小数位的结果 + 计算员工入职多少个月 + select ename,trunc(months_between(sysdate,hiredate)) from emp + date日期类型在数据库中可以进行减法操作,结果是相差的天数 + select ename,sysdate-hiredate from emp + 4)LEAST(date1,date2):显示两个时间中的最小值 + GREATEST(date1,date2):显示两个时间中的最大值 + 参数类型必须一致 + select LEAST(sysdate,to_date('2018-12-1','YYYY-MM-DD')) from dual + 5)EXTRACT(date from datetime):从参数datetime中提取参数date指定的数据,比如提取年、月、日 + select extract(day from sysdate) from dual + 查询1980年入职的员工有哪些 + select ename from emp where extract(year from hiredate) = 1980 + 4)空值函数 + null的含义: + 有时表中的某些字段值,数据未知或暂时不存在,取值null + 任何数据类型均可取值null + null条件查询: + null不等于任何值 + 判断一个字段的值是否为null,要使用is null或is not null + select * from emp where comm is null + 非空约束: + 非空(not null)约束用于确保字段值不为空 + 1)NVL(arg1,arg2):将null转变为非null值 + 如果arg1为null,返回arg2,否则返回arg1;arg1和arg2可以是任何数据类型,但两个参数的数据类型必 + 须是一致的 + 计算员工月收入 + select ename,sal,comm,sal+nvl(comm,0) from emp + 2)NVL2(arg,res1,res2):如果arg为null,则返回res2;arg不为null,则返回res1 + select ename,sal,comm,nvl2(comm,sal+comm,sal) from emp +11、基本查询语句: + 1)from子句: + select * from 表名 + select--用于指定要查询的列 + from--指定要从哪个表中查询 + 2)where子句: + 在select语句中,可以在where子句中使用比较操作符限制查询结果 + 查询部门10下的员工信息 + select * from emp where deptno=10 + 查询员工表中职位是'SALESMAN'的员工信息 + select * from emp where job='SALESMAN' --oracle中字符串区分大小写 +12、查询条件 + 1)使用>,<,>=,<=,!=,<>,= + 查询职员表中薪水低于2000的职员信息 + select ename,sal from emp where sal<2000 + 查询职员表中不属于部门10的员工信息 + select ename,sal,job from emp where deptno <> 10 + 查询职员表中在1981年1月1号以后入职的职员信息 + 2)使用AND,OR关键字 + AND 并且 + OR 或者 + 查询薪水大于1000并且职位是‘CLERK’的职员信息 + select ename,sal,job from emp where sal>1000 and job='CLERK' + 查询薪水大于1000或者职位是‘CLERK’的职员信息 + select ename,sal,job from emp where sal>1000 or job='CLERK' + 注意:AND优先级高于OR,可以使用()来提升优先级顺序 + select ename,sal,deptno from emp where deptno=20 or deptno=30 and sal>800 + 3)模糊查询***** + LIKE可以模糊匹配字符串 + select ename,job from emp where ename like 'A%' + _:任意一个字符 + %:任意多个字符 + 4)使用IN和NOT IN + IN(list):取出符合列表范围中的数据 + NOT IN(list):取出不符合此列表中的数据记录 + 查询职位是MANAGER或者CLERK的员工信息 + select * from emp where job in('MANAGER','CLERK') + 查询不是部门10或20的员工 + 5)BETWEEN...AND... + 用来查询符合某个值域范围条件的数据(闭区间) + 等价于>= AND <=的效果 + 查询薪水在1500-3000之间的职员信息 + select * from emp where sal between 1500 and 3000 + 6)使用ANY和ALL条件 + ALL和ANY不能单独使用,需要配合单行比较操作符>,>=,<,<=一起使用 + >ANY:大于最小 + ALL:大于最大 + ANY(select sal from emp where job='MANAGER') + 7)distinct过滤重复数据 + 查询员工的部门编号 + select distinct deptno from emp + 查询每个部门的职位 + select distinct deptno,job from emp +13、运算符优先级 + 1)() + 2)算术运算符:* / + - + 3)连接符:|| + 4)比较运算符:= > >= < <= <> is null,like,between...and...,in + 5)逻辑运算符:not and or + BETWEEN...AND与AND的区别? + 1、BETWEEN...AND:只能用来比较一个字段值 + 2、AND:可以用来比较不同的字段 +14、ORDER BY 排序 + 对结果集的排序,必须出现在select的最后一个子句 + 可以对结果集按照指定字段进行升序ASC或降序DESC + select ename,sal from emp order by sal asc + 注意:排序的字段中若包含NULL,则NULL被看做最大值 + select * from emp where deptno=10 order by mgr desc + 多个列排序: + 当以多列最为排序标准时,首先按照第一列进行排序,如果第一列数据相同,再以第二列排序,以此类推 + 多列排序不管正序还是倒序,每个列需要单独设置排序方式 + 对员工表中的职员排序,先按照部门编号正序排列,再按照薪水降序排列 + select ename,deptno,sal from emp order by deptno asc,sal desc +15、聚合函数(多行函数、分组函数) + 1)MAX和MIN:用来取得列或表达式的最大、最小值 + 可以用来统计任何数据类型,包括数字、字符和日期 + 获取机构下的最高薪水和最低薪水,参数是数字 + select max(sal),min(sal) from emp + 最早和最晚的入职时间,参数是日期 + select max(hiredate),min(hiredate) from emp + 2)AVG和SUM:用来统计列或表达式的平均值、和 + 只能操作数字类型,忽略NULL值 + 获取机构下全部职员的平均薪水和薪水总和 + select AVG(sal),SUM(sal) from emp + 3)COUNT:用来计算表中的记录条数,忽略NULL值 + 获取职员表中一共有多少名职员记录 + select count(*) from emp + 获得职员表中有多少人是有奖金的 + select count(comm) from emp + COUNT和SUM的区别? + COUNT是统计记录数,SUM是统计记录中值的总和,注意区分两者 + 4)聚合函数对空值的处理 + 聚合函数忽略NULL值 + select avg(comm) from emp + 如果不希望忽略null值,使用NVL函数 + select avg(nvl(comm,0)) from emp +16、GROUP BY 分组 + 将结果集按照指定字段进行分组 + 分组规则:该字段下的值一样的记录被看做一组 + 当希望得到每个部门的平均薪水,而不是整个机构的平均薪水 + select MAX(sal),MIN(sal),AVG(sal),SUM(sal) from emp group by deptno + select里面如果出现了聚合函数,同时又想出现某一字段时,那么该字段必须出现在group by子句中 + where后面不能使用聚合函数 + select MAX(sal),deptno from emp where MAX(sal)>4000 group by deptno(不能执行) + HAVING子句 + 用来对分组后的结果进一步限制,比如按部门分组后,得到每个部门的最高工资,可以继续限制输出结果 + 必须跟在group by后面,不能单独存在 + WHERE是非分组函数的过滤判断 + HAVING是分组(聚合)函数的过滤判断 + 查询部门中最大工资超过4000的部门以及最大工资 + select MAX(sal),deptno from emp group by deptno having MAX(sal)>4000 + 查看部门编号,以及该部门的平均工资,要求是该部门的平均工资要超过2000,职位是PRESIDENT的不参与统计 + select deptno,AVG(sal) from emp where job <> 'PRESIDENT' group by deptno having AVG(sal)>2000 +17、SELECT语句执行过程***** + 1、通过from子句中找到需要查询的表 + 2、通过where子句进行非分组函数筛选判断 + 3、通过group by子句完成分组操作 + 4、通过having子句完成组函数筛选判断 + 5、通过select子句选择要显示的列或表达式及组函数 + 6、通过order by子句进行排序操作 +18、函数总结***** + 单行函数和多行函数的分类并举例说明 + 单行函数: + 字符函数:substr() trim() length()... + 数值函数:round() trunc() mod()... + 日期函数:last_day() add_months()... + 转换函数: + 显示转换 to_char() to_date() + 隐式转换 其他类型与字符串连接通常会被转为字符串 + 通用函数:NVL() NVL2() + 注意:通常用于操作单行数据 可以任意嵌套多层,多层时由内向外依次执行 + 多行函数:MAX()最大值 MIN()最小值 SUM()求和 AVG()平均值 COUNT()统计 +19、关联查询 + 关联的概念: + 实际应用中所需要的数据,经常会需要查询两个或两个以上的表,这种查询叫做连接查询,连接查询通常建立存在 + 相互关 + 系的父子表之间 + 外键:保存另一张表主键的列称为外键 + 含有外键的表,在关联关系中属于多的一方 + 表与表之间的关系:一对多(通过外键建立关系),多对多(通过第三张表建立关系),一对一 + N张表的关联查询,最少需要N-1个连接条件,若不指定连接条件,会出现笛卡尔积(无意义的结果集) + 笛卡尔积: + 笛卡尔积指做关联操作的每个表的每一行和其他表的每一行做组合,假设两个表的记录条数分别是X和Y,笛卡尔积将 + 返回X*Y条记录 + select count(*) from emp--14条记录 + select count(*) from dept--4条记录 + select * from emp,dept--56条记录 + 等值连接 用法:外键=主键 + 查看员工名字、工资、部门名称 + select ename,sal,dname from emp e,dept d where e.deptno=d.deptno + select ename,sal,dname + from emp e,dept d + where e.deptno=d.deptno and d.loc='CHICAGO' + KING在哪里工作以及他的部门编号是多少 + select e.ename,e.deptno,d.loc + from emp e,dept d + where e.deptno=d.deptno and e.ename='KING' + 1.可以给表起别名,通过别名指定字段属于哪个表;若两个表字段名称相同,则必须指明数据来源 + 2.只有满足连接条件的结果,才会被查询出来 + 3.若有过滤条件,需同时满足连接条件和过滤条件的数据才会被查询出来 + 内连接: + 返回所有满足连接条件的记录,功能上和等值连接没有区别,只是写法不同 + 语法:表1 INNER JOIN 表2 ON 连接条件(INNER可以省略) + select ename,sal,dname from emp e INNER JOIN dept d ON e.deptno=d.deptno + 外连接 + 内连接返回满足连接条件的数据记录,有些情况下需要返回那些不满足连接条件的记录,需要使用外连接 + 将满足和不满足连接条件的结果全部查询出来 + 快速从已有表中复制数据 + create table empc as select * from emp + 向empc表中插入一条数据 部门号为50 + insert INTO empc(empno,ename,deptno) values(1000,'JACK',50) + 左外连接:(左表的全部,右表的部分) + 根据左表的记录,在被连接的右表中找出符合条件的记录与之匹配,如果找不到与左表匹配的,用null表示 + 语法:表1 LEFT OUTER JOIN 表2 ON 连接条件(OUTER可以省略) + 查询员工的编号,姓名,以及部门名称,包括不属于任何部门的员工 + select empno,ename,dname + from empc e + left join dept d + on e.deptno=d.deptno + 右外连接:(右表的全部,左表的部分) + 根据右表的记录,在被连接的左表中找出符合条件的记录与之匹配,如果找不到匹配的,用null补充 + 语法:表1 RIGHT OUTER JOIN 表2 ON 连接条件(OUTER可以省略) + 查询员工的编号,姓名,以及部门名称,包括没有员工的部门 + select empno,ename,dname + from empc e + right join dept d + on e.deptno=d.deptno + 全外连接 + 返回符合条件的所有表的记录,没有与之匹配的,用null表示(结果是左连接和右连接的并集) + 语法:表1 FULL OUTER JOIN 表2 ON 连接条件(OUTER可以省略) + 自连接 + 连接的两个表都是同一个表,表中的一个字段可以对应当前表的其它字段 + 查询每个员工的上级领导是谁 + select e.ename emp,m.ename mgr + from emp e,emp m + where e.mgr=m.empno + 查询SMITH的上司在哪个城市工作 + Oracle数据库自带语法:***** + 1)笛卡尔积 + 2)内连接:1.等值连接 + 2.非等值连接 + 输出员工编号、姓名、工资、工资等级 + select e.empno,e.ename,e.sal,s.grade + from emp e,salgrade s + where e.sal between s.losal and s.hisal + 3)外连接:1.左外连接: + 查询员工的编号,姓名,以及部门名称,包括不属于任何部门的员工 + select empno,ename,dname + from emp e,dept d + where e.deptno=d.deptno(+) + 2.右外连接: + 查询员工的编号,姓名,以及部门名称,包括没有员工的部门 + select empno,ename,dname + from empc e,dept d + where e.deptno(+)=d.deptno + 4)自连接 + 通用标准的SQL99语法 + 1.交叉连接 + 交叉连接和笛卡尔积的连接模式相同,都是表1中的每一行都与表2中的所有行建立一次连接 + select * from emp cross join dept + 2.自然连接 + 自然连接第一种情况:能够匹配到等值条件,那么就是等值连接的结果 + select * from emp natural join dept; --根据deptno进行等值连接 + 自然连接第二种情况:不能够匹配到等值的条件,那么查询结果就是交叉连接 + select * from emp natural join salgrade; --没有关系交叉连接 + 3.左外连接 + 4.右外连接 + 5.全外连接 + +20、子查询 + 为了给查询提供数据而首先执行的查询语句叫做子查询 + 子查询是嵌入在其它SQL语句中的SELECT语句,大部分时候出现在WHERE子句中,子查询嵌入的语句称作主查询或父查询 + 子查询需要注意: + 1.子查询需要写在括号中 + 2.子查询需要写在运算符的右端 + 3.子查询可以写在where,having,from子句中; + 4.子查询中通常不写order by子句 + 1)子查询在WHERE子句中 + 根据返回结果的不同,子查询分为单行子查询、多行子查询及多列子查询 + 1.单行子查询 + 返回一行一列数据,单行子查询要求使用单行操作符 > >= < <= <> = + select ename,sal from emp + where sal>(select MAX(sal) + from emp where deptno=20) + 查询与SCOTT同部门的员工信息 + select ename,job + from emp + where deptno=(select deptno from emp where ename='SCOTT') + 查找薪水比整个机构平均薪水高的员工 + select deptno,ename,sal + from emp + where sal>(select avg(sal) from emp) + 2.多行子查询 + 返回多行一列数据,使用多行操作符 in all any + select * from emp where deptno + in(select deptno from emp where job='SALESMAN') + and job <> 'SALESMAN' + >ANY:比子查询返回结果中的某个值大。即大于最小值 + 查询比10号部门某个员工工资高的员工信息 + select empno,ename,sal + from emp + where sal > any(select sal from emp where deptno=10) + =ANY:与子查询返回结果中的某个值相等 + 查询与10号部门某个员工工资相等的员工信息 + select empno,ename,sal + from emp + where sal = any(select sal from emp where deptno=10) + ALL:比子查询返回结果中的所有值都大 + 查询比30号部门所有员工工资高的员工信息 + select empno,ename,sal + from emp + where sal > ALL(select sal from emp where deptno=30) + (select min(sal) from emp where deptno=30) + 3)子查询在select部分 + 外连接的另一种写法,不推荐 + 查询每一个员工的同时,根据员工的部门编号查询部门的名称,若查询不到部门,该员工的部门信息就是null + select e.ename,e.sal, + (select d.dname from dept d where d.deptno=e.deptno) dname + from empc e +20、分页查询 + 找到员工表中工资最高的前三名(降序排序) + select * from emp order by sal desc + select rownum,e.* from emp e order by sal desc + --将上面的结果当作一张表处理,再查询 + select rownum,t1.* from (select e.* from emp e order by sal desc) t1 + --只要显示前三条记录 + select rownum,t1.* from (select e.* from emp e order by sal desc) t1 where rownum<4 + ROWNUM:伪列,系统自动生成的一列,用来表示行号 + rownum是ORACLE中特有的用来表示行号,默认值或起始值是1,在查询出结果之后,再加1 + 查询rownum大于2的所有记录 + select rownum,e.* from emp e where rownum>2--没有任何记录 + 查询rownum大于等于1的所有记录 + select rownum,e.* from emp e where rownum>=1 + 查询rownum小于6的所有记录 + select rownum,e.* from emp e where rownum<6 + 查询第6~第10条记录 + 第一种: + select * from (select rownum rn,e.* from emp e) t + where t.rn between 6 and 10 + 第二种: + select t1.* from (select emp.*,rownum rn from emp where rownum <=10) t1 where rn >=6; + 在oracle中只能使用子查询来做分页查询 + 页码:page + 每页最多条数:pageSize 5条 + 第一页:1~5 + 第二页:6~10 + 第三页:11~15 + start:(page-1)*pageSize+1 + end:pageSize*page +21、DECODE函数 + DECODE(参数1,值1,结果1,值2,结果2...[,默认值]) + 参数1依次与值进行匹配,与哪个匹配成功则显示对应的结果,若均未匹配,则显示最后一个默认值 + 查询职员表,根据职员的职位计算奖励金额,当职位分别是'MANAGER','SALESMAN','ANALYST'时, + 奖励金分别是薪水的1.2倍,1.1倍,1.05倍,如果不是这三个职位,则奖励金额取薪水值 + select ename,job,sal, + decode(job, + 'MANAGER',sal*1.2 + 'SALESMAN',sal*1.1 + 'ANALYST',sal*1.05 + sal + ) "奖金" from emp + 分组操作: + select decode(job, + 'MANAGER','VIP', + 'ANALYST','VIP', + 'OPERATION' + ) from emp group by + decode(job, + 'MANAGER','VIP', + 'ANALYST','VIP', + 'OPERATION' + ) + 排序: + select * from emp order by decode(job, + 'MANAGER',1 + 'SALESMAN',2 + 'ANALYST',3 + 4 + ) +22、集合函数 + UNION并集:将两个查询结果进行排序 + 所有的查询结果可能不是来自同一张表 + + 工资大于1500,或者20号部门下的员工 + select * from emp where sal>1500 or deptno=20 + --工资大于1500,或者20号部门下的员工 + select * from emp where sal>1500 + --20号部门下的员工 + select * from emp where deptno=20 + 并集运算:union、union all + union:去除重复的,并且排序 + union all:不会去除重复的 + select * from emp where sal>1500 + union + select * from emp where deptno=20 + INTERSECT交集:同时存在于两个结果集中的数据 + 工资大于1500并且在20号部门下的员工 + select * from emp where sal>1500 + INTERSECT + select * from emp where deptno=20 + MINUS差集:两个结果相减 + 1981年入职员工(不包括总裁和经理) + --1981年入职员工 + select * from emp where to_char(hiredate,'YYYY')='1981' + --总裁和经理 + select * from emp where where job='PRESIDENT' or job='MANAGER' + + select * from emp where to_char(hiredate,'YYYY')='1981' + MINUS + select * from emp where job='PRESIDENT' or job='MANAGER + 集合运算中的注意事项: + 1.列的类型要一致 + 2.按照顺序写 + 3.列的数量要一致,如果不足,用空值填充 + --列的类型不匹配 + select ename,sal from emp where sal>1500 + union + select sal,ename from emp where deptno=20 + --列的数量不匹配 + select ename,sal,deptno from emp where sal>1500 + union + select ename,sal from emp where deptno=20 +23、DDL语句管理表 + 1)创建表空间: + 逻辑单位,通常我们新建一个项目,就会新创建表空间,在表空间中创建用户来创建表 + 语法: + create tablespace 表空间的名称 + datafile '文件的路径' + size 大小 + autoextend on 自动扩展 + next 每次扩展的大小 + 切换到system账号下创建 + 删除表空间: + drop tablespace YYP + 2)创建用户: + create user 用户名 + identified by 密码 + default tablespace 表空间的名称 + 删除用户 + drop user yuanyipeng cascade; + 更改用户密码 + alter user 用户名 identified by 密码; + 授权 + grant connect to yuanyipeng + 分配角色 + grant dba to yuanyipeng + select * from scott.emp + 使用子查询的方式创建表: + create table 表名 as 查询语句 + create table emp as select * from scott.emp + 注意:只会复制表结构和表中数据,不会复制列的约束 + 如果查询语句有结果,就是复制表结构和数据 + 如果查询语句没有结果,就是复制表结构 + 只复制表数据(添加语句里可以没有values关键字) + insert into 表名 查询语句(表的结构与已有表结构一致) + 3)列的约束:约束主要是用来约束表中数据的规则 + 主键约束:primary key 不能为空,必须唯一 + 非空约束:not null + 唯一约束:unique + 检查约束:check(条件)在mysql中是可以写的,但是mysql直接忽略了检查约束 + 外键约束:主要是用来约束从表A中的记录,必须是存在于主表B中(保证数据完整性) + create table books( + book_id number(10) primary key, + book_name varchar2(20) not null, + price number(10,2), + cid number(10) not null references category(id)--外键约束 + ); + create table books( + book_id number(10) primary key, + book_name varchar2(20) not null, + price number(10,2), + cid number(10) not null, + foreign key(cid) references category(id)--外键约束 + ); + + create table category( + id number(10) primary key, + cname varchar2(10) + ); + alter table books add foreign key(cid) references category(id) +24、视图 + 数据库对象之一,视图在sql语句中体现的角色和表完全相同,但是视图并不是一个真实存在的表,它对应的是一 + 个查询语句的结果集(视图名跟表名不能一样) + 视图的作用:简化复杂查询、限制数据访问 + 1)创建简单视图(单表) + 若无权限,使用system用户授权 + 视图授权语句: + grant create view to 用户名; + 创建一个简单视图v_emp_10来显示部门10中的员工的编码、姓名和薪水 + create view v_emp_10 + as + select empno,ename,sal,deptno + from emp where deptno=10; + 2)修改视图 + 修改视图就是替换该视图的子查询,使用create or replace view 视图名即可,若视图不存在就创建,存在就替换 + 创建视图时,给列赋予别名 + create or replace view v_emp_10 + as + select empno id,ename name,sal salary,deptno + from emp where deptno=10; + 3)查询视图 + select * from v_emp_10 + 视图的列名和创建视图时的列名一致,不一定是原列名; + select id,name,salary from v_emp_10 + 4)视图的DML操作 + 对视图进行DML操作就是对视图数据来源的基础表进行操作 + 插入数据: + 1.注意视图中看不见的字段都被插入默认值,所以不能违反基础表中相应字段的约束条件,尤其是看不见的 + 字段的not null,否则会插入失败 + 2.为视图添加检查选项可以避免对视图进行DML操作时污染基础表,在创建语句后加with check option + 3.如果没有在视图上执行DML操作的必要,在建立视图时声明为只读来避免这种情况,保证视图对应的基础表 + 数据不会被非法修改with read only + 5)视图根据子查询的不同,分为简单视图和复杂视图,当子查询中包含单行函数、表达式或分组函数时,该视图是 + 一个复杂视图,复杂视图不能进行DML操作,必须为子查询中的表达式或函数定义别名 + 创建一个视图v_emp_salary,把职员表的数据按部门分组,获得每个部门的平均薪水、薪水总和、最低薪水 + create view v_emp_salary + as + select d.dname,avg(sal) avg_sal,sum(sal) sum_sal,min(sal) min_sal from emp e,dept d + where e.deptno=d.deptno group by d.dname + 6)删除视图 + DROP VIEW 视图名称 +25、序列:sequence 用来生成唯一数字值的数据库对象,通常作为表的主键值 + 序列是独立的数据库对象,序列并不依附于表 + 1)创建序列 + create sequence 序列名 + start with xx 起始数据 + increment by xx 步长(每次增加几) + maxvalue xx 最大值 + minvalue xx 最小值 + + create sequence users_seq + start with 100 + increment by 10 + + 序列中有两个伪列 + ---nextval:获取序列的下个值 + ---currval: 获取序列的当前值 + 当序列创建以后,必须先执行一次nextval,之后才能使用currval + 获取序列的第一个值,并且使用序列值为users表插入新的记录 + select users_seq.nextval from dual; + insert into users(id,name) values(users_seq.nextval,'马冬梅') + 2)删除序列:drop sequence users_seq +26、索引:一种提高查询效率的机制 + 经常作为过滤条件,去重,排序或链接条件的字段可以为其添加索引 + 1)创建索引: + create [unique] index 索引名称 + on 表名(列名) + 添加单列索引 + 在users表的name列上建立索引 + create index idx_users_name on users(name); + 添加多列索引 + create index idx_users_name_salary on users(name,salary); + 查询过程中自动应用索引,不需要我们制定,提高查询速度 + select * from users order by name,salary + 2)修改或删除索引 + 如果经常在索引列上执行DML操作,需要定期重建索引,提高索引的空间利用率 + alter index 索引名称 rebuild + 删除索引:drop index 索引名称 \ No newline at end of file diff --git a/JDBC/src/note/sql/SQL.sql b/JDBC/src/note/sql/SQL.sql new file mode 100644 index 0000000..f831846 --- /dev/null +++ b/JDBC/src/note/sql/SQL.sql @@ -0,0 +1,460 @@ +--SQL.day.02 +--创建表 +CREATE TABLE users( + id number(10) primary key,--主键 + name varchar2(20) unique,--唯一标识 + salary number(10,2), + create_time date default sysdate +); + +--查看表结构(在command window里用,SQL window不能使用) +desc 表名 + +--修改表名 +RENAME users to userplus + +--向表中添加字段 +ALTER TABLE userplus ADD(school varchar2(20)) +ALTER TABLE userplus ADD(job varchar2(10)) + +--删除表中已有字段 +ALTER TABLE userplus DROP(school) + +--修改表中已有字段的格式 +ALTER TABLE userplus MODIFY(salary number(10)) +ALTER TABLE userplus MODIFY(username varchar2(20) unique) + +--修改表中字段名称 +ALTER TABLE userplus RENAME column name to username + +--向表中添加数据 + --全字段插入数据 +INSERT INTO userplus VALUES(1, '张三', 8000,sysdate, '程序员'); +INSERT INTO userplus VALUES(2, '张三', 8000,default, '程序员');--因为表中有default sysdate,所以这里可以直接写default +INSERT INTO userplus VALUES(3, '张三', 8000,to_date('2018-12-01','YYYY-MM-DD'), '程序员'); + --部分字段插入 +INSERT INTO userplus(id, username, job) VALUES(4,'王五','产品经理'); +INSERT INTO userplus(id, username, job, salary) VALUES(5,'王五','产品经理',5000) + +--更新表中已有数据 +UPDATE userplus SET salary=salary*10, job='总经理' WHERE id=1; + +--删除表中数据 +DELETE FROM userplus WHERE salary>5000; + +--提交事务 +commit; + +--回滚 +rollback; + +--查询表中所有数据 +SELECT * FROM userplus; + +--查询部分数据信息 +SELECT job, salary FROM userplus; +SELECT * FROM userplus WHERE job <> '架构师'; +SELECT salary*12 "年薪" FROM userplus WHERE username='王五';--别名 +SELECT salary*12 AS "年薪" FROM userplus WHERE username='王五';--别名 + +--10.(1)字符串函数 + --连接字符串 +SELECT CONCAT(ename, sal) from EMP; +SELECT CONCAT(CONCAT(ename, ': ') ,sal)from EMP; +SELECT ename||': '||sal as "姓名:工资" from EMP; + --显示字符串长度 +SELECT LENGTH(ename) from EMP; + --转大写 +SELECT UPPER(ename) from EMP; + --去除字符串前后指定内容 +SELECT TRIM('E' from 'EEHELLO WORLDEEE') from dual; +SELECT ename, trim('A' FROM ename) from emp; --去除员工名字前后的所有'A' +SELECT LTRIM('EEHELLO WORLDEEE', 'E') from dual;--去除EEHELLO的前面的E +SELECT ename, ltrim(ename,'A') from emp;--去除员工名字前面的所有'A' + --补位函数 +select * from emp +select ename, LPAD(sal, 6, 0) AS salary from emp + --substr截取字符串 +select substr('helloworldqqqqq',6,10) from dual; + --INSTR字符串检索 +select instr('thinking in java','in',4,2) from dual; + +--10.(2)数字函数 + --截取,用于四舍五入 +select round(321.123,1) from dual; + --截取,无四舍五入 +select trunc(45.678,2), trunc(45.678,0), trunc(45.678), trunc(45.678,-1) from dual; + --取余数 +select ename, sal, mod(sal,1000) from emp; + --向上取整 +select ceil(45.678) from dual; + --向下取整 +select floor(45.678) from dual; +--10.(3)日期函数 + --系统时间,精确到秒 +select sysdate from dual; + --时间戳,精确到毫秒 +select systimestamp from dual; + --TO_DATE(),日期转换函数 +select to_date('2018-12-01 11:30','YYYY-MM-DD HH:MI:SS') from dual; +select to_date('2018-12-01 13:30','YYYY-MM-DD HH24:MI:SS') from dual; + --TO_CHAR(),将DATE按照给定的日期格式转换为字符串 +select ename, to_char(hiredate,'YYYY-MM-DD HH:MI:SS') from emp; +select ename, to_char(hiredate,'YYYY"年"MM"月"DD"日"') from emp; + --LAST_DAY(date),返回指定日期所在月的最后一天 +select last_day(sysdate) from dual; +select last_day(to_date('2018-12-01 11:30','YYYY-MM-DD HH:MI:SS')) from dual; + --ADD_MONTHS(date,i),返回+-i个月之后的日期 +select ename, hiredate, add_months(hiredate, 12*20) AS "20周年" from emp; + --MONTHS_BETWEEN(date1,date2):计算两个日期之间相差多少个月 +select ename,trunc(months_between(sysdate, hiredate)) from emp; + --date日期类型在数据库中可以进行减法操作,结果是相差的天数: +select ename, sysdate-hiredate from emp; + --LEAST(date1,date2):显示两个时间中的最小值。参数类型必须一致。 +select least(sysdate,to_date('2018/12/09','YYYY-MM-DD')) from dual; + --GREATEST(date1,date2):显示两个时间中的最大值。参数类型必须一致。 +select greatest(sysdate,to_date('2018/12/09','YYYY-MM-DD')) from dual; + --EXTRACT(date from datetime):从参数datetime中提取参数date指定的数据,比如提取:年、月、日。 +select extract(year from sysdate),extract(month from sysdate),extract(day from sysdate) from dual; +select extract(hour from systimestamp),extract(minute from systimestamp),extract(second from systimestamp) from dual; +select ename from emp where extract(year from hiredate) = 1980; + +--10.(4)空值函数: +select * from emp where comm is not null and comm != 0; + --NVL(arg1,arg2):将null转变为非null值。如果arg1为null,返回arg2;否则返回本身。 +select ename,nvl(comm,0) from emp; +select * from emp where nvl(comm,0)>0; + --NVL(arg1,arg2),如果arg1为null,返回arg2;否则返回本身。计算员工月收入(月工资加奖金(奖金可能为null)) +select ename, sal, comm, sal+nvl(comm,0) as "月收入" from emp; + --NVL2(arg,res1,res2):如果arg为null,则返回res2,arg不为null则返回res1. +select ename, sal, comm, nvl2(comm,comm+sal,sal) as"月收入" from emp; + +--11.基本查询语句: + --查询部门10下的员工信息: +select * from emp where deptno = 10; + --查询员工表中职位是'SALESMAN'的员工信息 +select * from emp where job = 'SALESMAN'; + +--12.查询条件: + --查询职员表中薪水低于2000的职员信息 +select ename, sal from emp where sal < 2000; + --查询职员表中不属于部门10的员工信息 +select * from emp where deptno <>10; + --查询职员表中在1981年1月1号以后入职的职员信息 +select * from emp where hiredate > to_date('1981/01/01','YYYY/MM/DD'); + --查询薪水大于1000,并且职位是'CLERK'的职员信息 +select * from emp where sal>1000 and job='CLERK'; + --查询薪水大于1000,或者职位是'CLERK'的职员信息 +select * from emp where sal>1000 or job='CLERK'; + --NVL(arg1,arg2),NVL2(arg,res1,res2) + --查询薪水大于1000,并且奖金不为null的职员信息 +select * from emp where sal>1000 and comm>0; +select * from emp where sal>1000 and nvl(comm,0)>0; +select * from emp where (deptno=20 or deptno=30) and sal>800; + --模糊查询,LIKE + --查询员工表中姓名以'A'开头的员工信息 +select * from emp where ename like 'ALLEN'; + --查询员工表中姓名第二个字母是'A'的员工信息 +select * from emp where ename like '_A%'; + --IN和NOT IN: + --查询职位是经理或者职员的员工信息 +select * from emp where job in ('MANAGER','CLERK'); + --查询部门不是10或20的员工 +select * from emp where deptno not in (10,20); +select * from emp where deptno <> all(10,20); + --BETWEEN...AND...:是用来查询符合某个值域范围条件的数据。 + --查询薪水在1500~3000之间的职员信息 +select * from emp where sal between 1500 and 3000;--[1500,3000] + --查询比经理最低工资高的员工信息。 +select * from emp where sal > any(select sal from emp where job='MANAGER'); + --查询员工的部门编号 +select distinct(deptno) from emp; +select distinct deptno,job from emp; + +--14.ORDER BY 排序(写在所有子句最后) +select ename, sal from emp order by sal; +select ename, sal from emp order by sal asc; +select * from emp where sal>2000 order by mgr desc; + --多列排序,对员工表中的职员排序,先按照部门编号正序排列,再按照薪水降序排列。 +select ename, deptno, sal from emp order by deptno asc, sal desc; + +--15.聚合函数 + --MAX和MIN +select deptno,max(sal),min(sal) from emp group by deptno; +select max(hiredate),min(hiredate) from emp; +select ename from emp a where hiredate = (select max(hiredate) from emp); + --ERROR: +select ename from emp a where hiredate = (select max(hiredate),min(hiredate) from emp); + --RIGHT: +select ename from emp where hiredate in ((select min(hiredate) from emp), (select max(hiredate) from emp)); + --AVG和SUM +select avg(sal),sum(sal) from emp; +select avg(comm),sum(comm) from emp;--忽略null值 + --COUNT +select count(*) from emp; +select count(comm) from emp;--忽略null值 +select count(*) from emp where comm is not null; + --不希望聚合函数忽略NULL值时: +select avg(nvl(comm,0)) from emp; + +--16.GROUP BY +select max(sal),min(sal),avg(sal) from emp group by deptno; +select deptno,max(sal),min(sal),avg(sal) from emp group by deptno; +select deptno,ename,max(sal),min(sal),avg(sal) from emp group by deptno,ename; + --where后面不能使用聚合函数,不能执行. +select max(sal),deptno from emp where max(sal)>4000 group by deptno; + --查询部门中最大工资超过4000的部门以及最大工资。 +select max(sal),deptno from emp group by deptno having max(sal)>4000; + --查看部门编号,以及该部门的平均工资(要求是该本门的平均工资超过2000,职位是PRESIDENT的不能参与统计) +select deptno, avg(sal) from emp where job<>'PRESIDENT' group by deptno having avg(sal)>2000; + +--19.关联查询 + --查询每个员工所在部门名称 +select ename, dname from emp, dept where emp.deptno=dept.deptno; + --查看员工名字、工资、部门名称 +select ename, sal, dname from emp e, dept d where e.deptno=d.deptno and loc='CHICAGO'; + --KING在哪里工作以及他的部门编号是多少? +select ename, e.deptno, loc from emp e, dept d where e.deptno=d.deptno and ename='KING'; + +--20.连接种类 + --内连接 +select ename, dname from emp inner join dept on emp.deptno=dept.deptno; + --外连接 + --快速从一个表中复制数据 +create table empc as select * from emp; + --向empc表中插入一条数据,部门号为50 +insert into empc(empno, ename, deptno)values(1000,'JACK',50); +select * from empc; + --左外连接,查询员工的编号、姓名、以及部门名称,包括不属于任何部门的员工。 +select empno, ename, dname, empc.deptno from empc left outer join dept on empc.deptno=dept.deptno; + --右外连接,查询员工的编号、姓名、以及部门名称,包括任何没有员工的部门。 +select empno, ename, dname, c.deptno from empc c right outer join dept d on c.deptno=d.deptno; + --全外连接,查询员工的编号、姓名、以及部门名称,包括不属于任何部门的员工,也包括任何没有员工的部门。 +select empno, ename, dname, c.deptno from empc c full outer join dept d on c.deptno=d.deptno; + --自连接,查询每个员工的上级领导 +select e.ename, m.ename from emp e, emp m where e.mgr=m.empno; +select e.ename emp, m.ename mgr from emp e left outer join emp m on e.mgr=m.empno; + --查询SMITH的上司在哪个城市工作 + --等值连接 +select e.ename emp, m.ename mgr, d.loc mgrloc +from emp e, emp m, dept d +where e.mgr=m.empno and m.deptno=d.deptno and e.ename='SMITH'; + --内连接 +select e.ename emp, m.ename mgr, d.loc mgrloc +from emp e inner join emp m +on e.mgr=m.empno and e.ename='SMITH' +inner join dept d +on m.deptno=d.deptno; + +--(外连接的另一种写法):查询每一个员工的同时,根据员工的部门编号查询部门的信息,若查询不到部门,该员工的部门信息就是null +select e.ename, e.sal, e.deptno from empc e;--ERROR + --Solution 1. +select e.ename, e.sal, +(select d.deptno from dept d where d.deptno=e.deptno) deptno +from empc e;--RIGHT + --Solution 2.正常的外连接写法:为满足要求,要写成d.deptno +select e.ename, e.sal,d.deptno +from empc e left outer join dept d +on e.deptno=d.deptno; + --Solution 3.当三张表时(例子不是三张表),这种方法比较简单一些 +select e.ename, e.sal, +(select d.dname from dept d where d.deptno=e.deptno) dname, +(select d.loc from dept d where d.deptno=e.deptno) loc +from empc e; + +--21.子查询 + --WHERE: + --单行子查询:查询大于部门号20的最高工资的员工信息 +select ename, sal from emp where sal>(select max(sal) from emp where deptno=20); + --单行子查询:查询与SCOTT同部门的员工信息 +select ename, job from emp where deptno=(select deptno from emp where ename='SCOTT') + --单行子查询:查找薪水比整个机构平均薪水高的员工 +select ename, job, sal from emp where sal>(select avg(sal) from emp); + --多行子查询:查询部门有SALESMAN但职位不是SALESMAN的员工的信息。 +select * from emp where deptno in (select deptno from emp where job='SALESMAN') and job<>'SALESMAN'; + --多行子查询:查询比10号部门某个员工工资相等的员工信息 +select * from emp where sal = any (select sal from emp where deptno = 10); + --多列子查询:?????????????????????????????????????????????????????????????????????????? + --EXISTS关键字:列出来那些有员工的部门信息 +select deptno, dname from dept d where EXISTS (select * from emp e where e.deptno=d.deptno); + --HAVING: + --查询最低工资高于部门30的最低工资的部门信息 +select min(sal) from emp group by deptno having min(sal)<(select min(sal) from emp where deptno=30); + +--22.分页查询 + --查询rownum大于2的所有记录 +select rownum, e.* from emp e where rownum>2;--ERROR,因为没有任何记录。 +select rownum, e.* from emp e where rownum>=1; +select rownum, e.* from emp e where rownum<6; + --找到员工表中工资最高的前三名(降序排序): + --ERROR +select rownum, e.* from emp e order by sal desc where rownum<=3; + --RIGHT +select * from emp order by sal desc;--先降序,再把它当成一张表,再去选rownum小于等于3的行。 +select rownum, t1.* from (select * from emp order by sal desc) t1 where rownum <=3; + --查询第6~10条记录(两种方法) +select * from (select rownum rn, e.* from emp e) t where t.rn between 6 and 10; +select t1.* from (select rownum rn, emp.* from emp where rownum<=10) t1 where rn between 6 and 10; + --工资降序后选6~10条记录:原表先降序,再加伪列,再当新表选范围。 +select * from (select rownum rn, e.* from (select * from emp order by sal desc) e) t where t.rn between 6 and 10; + +--23.DECODE(参数1,值1,结果1,值2,结果2...[,默认值]); + --查询职员表,根据职员的职位计算奖励金额,当职位分别是'MANAGER','SALESMAN','ANALYST'时,奖励金分别是薪水的1.2,1.1,1.05倍,其它为原本的薪水值。 +select ename, job, sal, decode(job,'MANAGER',sal*1.2,'SALESMAN',sal*1.1,'ANALYST',sal*1.05,sal) "奖金" from emp; +select decode(job,'MANAGER','VIP','ANALYST','VIP','OPERATION') from emp; + --分组操作,不能起别名 +select decode(job,'MANAGER','VIP','ANALYST','VIP','OPERATION') job, count(*) from emp group by decode(job,'MANAGER','VIP','ANALYST','VIP','OPERATION'); + --自定义排序 +select * from emp order by decode(job,'MANAGER','1','SALESMAN','2','ANALYST','3'); + +--24 + --union + --工资大于1500或20号部门下的员工 +select * from emp where sal>1500 or deptno=20; + --工资大于1500的 +select * from emp where sal>1500;--7条记录 + --20号部门下的员工 +select * from emp where deptno=20;--5条记录 + --并集运算:union(忽略重复数据,9条记录,并排序), union all(不忽略重复数据,12条记录,不排序) +select * from emp where sal>1500 union select * from emp where deptno=20;--并集之后,总共9条记录 + --INTERSECT,交集 +select * from emp where sal>1500 INTERSECT select * from emp where deptno=20; + --MINUS差集:两个结果相减。 + --1981年入职员工(不包括总裁和经理) +select * from emp where to_char(hiredate,'YYYY')='1981'; +select * from emp where job in ('PRESIDENT','MANAGER'); +select * from emp where to_char(hiredate,'YYYY')='1981' MINUS select * from emp where job in ('PRESIDENT','MANAGER'); + --注意事项: +select empno,ename from emp where to_char(hiredate,'YYYY')='1981' MINUS select null,ename from emp where job in ('PRESIDENT','MANAGER'); + +--25.DDL语句管理表: +CREATE tablespace YYP datafile 'e:/YYP.dbf' size 100m autoextend on next 10m;--创建 +drop tablespace YYP;--删除(取消和文件的关联,不会删除文件)(取消关联之后,可以手动删除)。 +create user zicheng identified by qqq default tablespace YYP;--创建用户 +drop user zicheng cascade;--删除用户 +alter user zicheng identified by eee;--修改密码 +grant connect to zicheng;--授权 +grant dba to zicheng;--分配角色 + --使用子查询的方式创建表: +create table emp as select * from scott.emp;--只复制表结构和表数据,不会复制列的约束。 +create table dept as select * from scott.dept where 1=2;--只复制表结构,无数据,因为1=2为false。 +insert into dept select * from scott.dept;--只复制表数据,但前提是表的结构与已有表结构一致。 +select * from dept; + +--26.列的约束 + --检查约束 +CREATE TABLE users( + id number(10) primary key,--主键 + name varchar2(20) unique,--唯一标识 + sex varchar2(2) check(sex in ('男' ,'女')),--检查约束 + salary number(10,2) check(salary>3000), + create_time date default sysdate +); +insert into users values(1,'admin','男',3500,default); + --外键约束 +create table category( + id number(10) primary key, + cname varchar2(10) +); +create table books( + book_id number(10) primary key, + book_name varchar2(20) not null, + price number(10,2) check(price>100),--检查约束 + cid number(10) not null references category(id)--外键约束 + --foreign key(cid) references category(id)--另一种外键约束的方式 +); + --可以不在定义表中建立外键约束,单独用此语句也可实现外键约束。 +alter table books add foreign key(cid) references category(id); + --例子: +insert into category values(1,'小说'); +insert into category values(2,'文学'); +insert into category values(3,'传记'); +select * from category; +insert into books values(1,'西游记',101,1); +select * from books; + --不能删除外键,因为从表中有相关的已建立关联的外键约束 +delete from category where id=1; +delete from books where cid=1;--删除外键关联的两种方法 +update books set cid=null where cid=1;--然后再删除主表中的数据就ok。 + +--27.视图 + --创建一个简单视图v_emp_10来显示部门10中的员工的编码、姓名和薪水。 +create view v_emp_10 as select empno,ename,sal,deptno from emp where deptno=10; + --修改视图就是替换该视图的子查询,使用create or replace view 视图名 即可,若视图不存在就创建,存在就替换。创建视图时,可以给列赋予别名。 +create or replace view v_emp_10 as select empno id,ename name,sal,deptno from emp where deptno=10; + --查询视图 +select * from v_emp_10; + --视图的DML操作,会修改原表的数据 +insert into v_emp_10 values(1,'Tony',8888,50) +select * from emp; + --with check option +create or replace view v_emp_10 as select empno id,ename name,sal,deptno from emp where deptno=10 with check option + --with read only只读,不能对视图进行DML操作。 +create or replace view v_emp_10 as select empno,ename,sal,deptno from emp where deptno=10 with read only; + --创建一个视图v_emp_salary,把职员表中的数据按部门分组,获得每个部门的平均薪水、薪水总和、最低薪水。 +create view v_emp_salary as select d.dname, avg(sal) avg_sal,sum(sal) sum_sal,min(sal) min_sal,max(sal) max_sal from emp e, dept d where e.deptno=d.deptno group by d.deptno, d.dname; +select * from v_emp_salary; + --drop view 视图名称:删除视图 +drop view v_emp_slary; + +--28.序列 + --建表、建立序列、插入基表、删除序列 +CREATE TABLE users( + id number(10) primary key,--主键 + name varchar2(20), --unique,--唯一标识 + salary number(10,2), + create_time date default sysdate +); + --建立序列:create sequence 序列名 start with **(起始数据) increment by **(步长,每次增加几,可正可负) maxvalue **(最大值) / minvalue **(最小值); +create sequence users_seq start with 100 increment by 10;--建立序列,第一次一定要用nextval,不能用currval +insert into users(id,name)values(users_seq.nextval,'马冬梅');--插入基表 +select users_seq.currval from dual;--查看当前序列值。 +drop sequence users_seq;--删除序列 + --循环插入 +begin + for i in 1..10000 + loop + insert into users(id,name,salary) values( users_seq.nextval,'瞬间爆炸',8888); + end loop; + commit; +end; + +--29.索引 + --创建索引:create [unique] index 索引名称 on 表名(列名) +create index idx_users_name on users(name);--在users表的ename列上建立索引 + --添加多列索引: +create index idx_users_salary on users(name,salary); + --查询过程中自动应用索引,不需要单独去制定,提高查询速度。 +select users.* from users order by name, salary; + --重构索引(索引是平衡二叉树,修改表后,最好重构一下索引的平衡二叉树) +alter index 索引名称 rebuild;--经常修改数据的表,不建议建立索引。 + --删除索引: +drop index idx_users_salary; + + + + + + + + + +--练习 +create table student( + id number(10) not null, + name varchar2(20), + hobby varchar2(100), + school varchar2(20), + create_time date +); +--修改表名student_t +rename student to student_t; +--添加字段:科目project,成绩score +alter table student_t add(project varchar2(20), score number(3)); +--删除学校字段 +alter table student_t drop(school); +--修改字段格式 +alter table student_t modify(create_time varchar2(20) default sysdate); +--修改表中字段名称,name改为stu_name +alter table student_t rename column name to stu_name; + diff --git a/JDBC/src/note/sql/SQLNote.sql b/JDBC/src/note/sql/SQLNote.sql new file mode 100644 index 0000000..a18543f --- /dev/null +++ b/JDBC/src/note/sql/SQLNote.sql @@ -0,0 +1,422 @@ +数据库//297,308,415 +一、 使用sqlplus连接数据库 + 1. 方式: + 1) sqlplus,回车,输出用户名和密码 + 2) sqlplus/nolog ------conn scott/tiger + 3) 使用可视化界面,developer。注意:使用窗口连接可视化工具却不能连接,会出现无服务或无监听错误,需要重新配置监听。(a.关闭服务。 b.根据配置监听文件修改HOST为当前IP,或修改为localhost,或127.0.0.1,或主机名。 c.再开启服务重新连接登陆即可。) + 2. 命令窗口注意事项: + 1) 所有sql语句以“;”结尾,回车执行。 + 2) sql语句不区分大小写,字符串除外。 + 3. Oracle用户(oracle安装后会自动生成4个账户): + 1) sys用户:超级用户,具有最高权限,具有sysdba(数据库管理员)角色,有数据字典和视图权限,能创建数据库,默认密码manager。 + 2) system用户:操作员,仅次于超级用户,具有sysoper(系统操作员)角色。不能创建库。 + 4. DB:Database数据库,关系型数据库,按照数据结构来管理数据的仓库,以二维表(列:字段; 行:数据)的形式存储数据。 + DBMS:数据库管理系统(Oracle, mysql, sqlserver…) +二、 sql语句 + 1. SQL (Structed Query Language,结构化查询语言) + 2. SQL分类: + DDL:数据定义语言,用于操作数据对象(表,视图,序列,索引)。 + CREATE:创建表或其它对象。 + ALTER:修改表或其它对象结构。 + DROP:删除表或其它对象。 + TRUNCATE:删除表数据,保留表结构。清空表的操作。 + DML:数据操作语言(通常需要伴随TCL),用于增删改表中的数据。 + INSERT INTO:将数据插入表中。 + DELETE:删除表中数据。 + UPDATE SET:更新表中数据。 + TCL:事务控制语言。 + COMMIT:提交。 + ROLLBACK:回滚。 + DQL:数据查询语言 + SELECT:查询数据。 + DCL:数据控制语言。 + GRANT:授予权限。 + grant…create…view…to…scott; + 3. 数据类型: + char(n):定长字符串,n是字节数。最多2000字节。 + varchar2(n):变长字符串,n是字节数。最多4000字节。 + number(n,m):n共多少位数字,m是其中几位小数。 + date:时间日期,select sysdate from dual; +三.SQL(DDL, DML,TCL,DQL) +软件的构成? + 1.前端:HTML,CSS,JS,JQuery + 2.后台:Java + 3.数据库:Oracle, Mysql(被甲骨文收购) + +1.安装Oracle + + 常用用户: + sys:超级用户 具有最高权限 具有sysdba角色 (数据库管理员) + 有创建数据库的权限 + system:管理操作员 权限仅次于超级管理员 + + scott:普通用户 一般用于练习 scott -- tiger + 解锁用户:alter user scott account unlock + 设置密码:alter user scott identified by tiger + +2.登录方式 + 1)sqlplus 回车 + 输入用户名 + 输入密码 + + 2)sqlplus/nolog + conn scott/tiger + +3. DB:DataBase 按照数据结构来管理数据的仓库(关系型数据库),以二维表形式存储数据(表的列:字段名 表的行:数据) + DBMS:数据库管理系统(mysql、oracle、SqlServer) + +4.常用命令 + sqlplus 打开数据库 + conn 用户名/密码 连接数据库 + show user; 显示当前用户 + exit; 断开连接 + quit; 断开连接 + +5.SQL:结构化查询语言 + SQL的分类: + DDL 数据定义语言 用于操作数据对象(表 视图 序列 索引) + DML 数据操作语言 用于增删改表中的数据(通常伴随事务) + TCL 事务控制语言 用于数据的提交和撤销 + DQL 数据查询语言 用于查询数据记录 + DCL 数据控制语言 用于执行权限分配 + + DDL:数据定义语言 + ---用于操作数据库对象(表 视图 序列 索引) + CREATE:用来创建表或其他对象 + ALTER:修改表或其他对象的结构 + DROP:删除表或其他对象的结构 + TRUNCATE:清空表(删除表中数据,保留表结构) + DML:数据操作语言 + ---用于增删改表中的数据(通常伴随事务控制语言) + INSERT INTO:将数据插入到表中 + DELETE:删除表中数据 ---- WHERE + UPDATE 表名 SET:更新表中数据 --- WHERE + + TCL:事务控制语言 + COMMIT:提交--保存 + ROLLBACK:回滚---后退 + + DQL:数据查询语言 + SELECT 查询***** + + DCL:数据控制语言 + 用来执行权限分配 GRANT REVOKE +6.DDL 数据定义语言 + 查看用户定义的表: + SELECT table_name FROM user_tables;--用户定义的所有表都会被列出来 + (1)创建表 + CREATE TABLE 表名 ( + 列名(字段名) 数据类型 [默认值 约束], + 列名(字段名) 数据类型 [默认值 约束], + 列名(字段名) 数据类型 [默认值 约束], + 列名(字段名) 数据类型 [默认值 约束] + ); + CREATE TABLE users( + id number(10) primary key, + name varchar2(20) not null unique, + salary number(10,2), + create_time date default sysdate + ); + id(主键) 特点:该列在整张表中每一行所保存的值都不相同,且必须有值(非空且唯一) + 命名规则: + 表名和列名: + 1)必须以字母开头 + 2)必须在1-30个字符之间 + 3)必须只能包含A-Z,a-z,0-9,_,$,和# + 4)必须不能和用户定义的其他对象重名 + 5)必须不能是Oracle的保留字 + 数据类型: + 1)NUMBER:数值类型 + NUMBER(X):x代表位数 + NUMBER(3) 最多能存放3位数 + NUMBER(X,Y):x表示共几位 y表示其中有几位是小数 + NUMBER(6,2) 8888.88 + 2)CHAR:定长字符串 + CHAR(X):X表示共占多少字节 最多放2000字节 + 3)VARCHAR2:变长字符串 + VARCHAR2(X):X表示共占多少字节(根据其中保存的数据长度,占用的空间是变化的) 最多4000字节 + 4)DATE 时间日期 SELECT SYSDATE FROM DUAL; + 伪表:dual确实是一张表,是一张只有一行一列的表,习惯上称为伪表,因为它不存储具体的数据。 + 查看表结构(在command window):DESC table_name; + (2)删除表: + DROP TABLE users;--删除表数据和结构 + TRUNCATE TABLE users;--删除表数据,保留表和表结构 + (3)修改表(ALTER): + 修改表名:RENAME old_name TO new_name + 修改表结构: + 向表中添加字段(只能添加到最后,不能插入到现有的序列中):ALTER TABLE table_name ADD(字段名,数据类型[默认值 约束]), 例如:ALTER TABLE usersplus ADD(school varchar2(20)) + 删除表中已有字段: ALTER TABLE biaoming DROP(字段名),例如:ALTER TABLE userplus DROP(school) + 修改表中已有字段的格式:ALTER TABLE 表名 MODIFY(字段名,数据类型[默认值 约束]),例如:ALTER TABLE userplus MODIFY(salary number(10)) + 修改表中字段名称:ALTER TABLE userplus RENAME column name to username +7.DML 数据操作语言 + (1)向表中添加数据: + 全字段插入数据:INSERT INTO 表名 VALUES(1, '张三', 8000,sysdate, '程序员'); 注意:values中的数据顺序要和定义字段时一致。 + 部分字段插入数据:INSERT INTO 表名(想要插入数据的字段)VALUES(与字段顺序相对应的数据)。 + (2)修改表中已有数据: + 在修改表中数据时,通常添加where子句来限定要修改的记录,这样就只能修改满足where条件的记录。否则修改全表。 + UPDATE 表名 SET 字段名=数据 WHERE 字段名=数据 + (3)删除表中数据: + DELETE FROM 表名 WHERE 字段名=数据。通常与where子句连用,否则删除表中所有数据。 + 在DDL语句中的TRUNCATE语句同样有删除表数据的作用。 + TRUNCATE和DELETE的区别:DELETE可以有条件的删除数据,但TRUNCATE将表中的数据全部删除;DELETE是DML语言,可以rollback,TRUNCATE是事务控制语言,立即生效,无法rollback. + 删除全部记录:DELETE FROM userplus(效率低); TRUNCATE TABLE userplus(效率高). +8.TCL:事务控制语言 + (1)commit:提交; 可以通过语句或按钮去提交,或者正常关闭数据库时会默认提交。 + (2)rollback:回滚; + 事务的四个特性: + 原子性(Atomicity): +    原子性是指事务包含的所有操作要么全部成功全部应用,要么全部失败回滚。因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。 + 一致性(Consistency): + 一致性是指一个事务执行之前和执行之后都必须处于一致性状态。拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性。 + 隔离性(Isolation): +   隔离性是指多个并发事务之间要相互隔离。当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰。 + 持久性(Durability): +   持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。 +9.DQL:数据查询语言 + 基本查询语句由SELECT子句和FROM子句组成。 + SELECT:指定显示的字段名称; FROM:指定数据来源。 + (1)查询所有:SELECT * FROM 表名; + (2)查询部分数据信息:SELECT field1, field2 FROM table_name where 限定条件; + 注意:SELECT可以显示字段,表达式,函数, <>是不等于。若函数名称较长,不利于查询结果的列名显示,可以起列别名。 + SELECT salary*12 "年薪" FROM userplus WHERE username='王五';--别名 + SELECT salary*12 AS "年薪" FROM userplus WHERE username='王五';--别名 + 别名不能以数字开头,若以数字或符号开头,别名需要用""括上。 +10.常用函数(单行函数):4 + (1)字符串函数:13 + CONCAT(c1,c2),连接字符串,将c1,c2两个字段拼接显示。例如:SELECT CONCAT(CONCAT(ename, ': ') ,sal)from EMP; + ||连接多个字符串符号。例如:SELECT ename||': '||sal as "姓名:工资" from EMP; + LENGTH(ch):显示字符串长度, 例如:SELECT LENGTH(ename) from EMP; + UPPER(字段名):转大写 + LOWER(字段名): 转小写 + INITCAP(字段名): 只有首字母大写 + TRIM():去除字符串前后指定内容。例如(右侧写字符串):SELECT TRIM('E' from 'EEHELLO WORLDEEE') from dual; SELECT ename, trim('A' FROM ename) from emp; --去除员工名字前后的'A' + LTRIM('',''):去除字符回串左侧指定内容。例如(左侧写字符串):SELECT LTRIM('EEHELLO WORLDEEE', 'E') from dual; + RTRIM('',''):去除字符串右侧指定内容。 + LPAD(ch1, m, ch2): 左补位函数,ch1是要查询显示的内容,m指定位数,数据位数不足时由ch2进行补位。在emp表中使用左补位,将sql用0补齐6位。例如:select ename, LPAD(sal, 6, 0) AS salary from emp + RPAD(ch1, m, ch2): 右补位函数。 + SUBSTR(ch,m,n):截取字符串,截取ch这个字符串,从m开始截取,共截取n个,若m为负数,则是从后向前进行下标查询,从而进行截取。 + INSTR(ch1,ch2,m,n):查找ch1中ch2出现的位置,m代表从哪个位置开始检索,n代表第几次出现,不指定m和n,默认值都是1。下标从1开始,无匹配数据的时候返回0. + (2)数字函数:5 + ROUND(n,m):用于四舍五入,参数中的n可以是任何数字(要被处理的数字);m必须是整数,m取整数则四舍五入到小数点后第m位,m取0则四舍五入到整数位(m缺省,默认是0),m取负数则四舍五入到小数点前m位。 + TRUNC(n,m):截取数字没有四舍五入 + MOD(m,n):返回m除以n后的余数,n为0则直接返回m。 + CEIL(n):向上取整,大于该数的最小整数。 + FLOOR(n):向下取整,小于该数的最大整数。 + (3)日期函数:11 + sysdate:返回当前的系统时间,精确到秒。 + systimestamp:时间戳,返回当前系统日期和时间,精确到毫秒。 + (1)TO_DATE():日期转换函数,相当于Java中的SimpleDateFormat的parse()方法,将给定的字符串按照给定的日期格式转换为Date。 + select to_date('2018-12-01 11:30','YYYY-MM-DD HH:MI:SS') from dual; + select to_date('2018-12-01 13:30','YYYY-MM-DD HH24:MI:SS') from dual; + (2)TO_CHAR():用于将DATE按照给定的日期格式转换为字符串。 + select ename, to_char(hiredate,'YYYY-MM-DD HH:MI:SS') from emp; + select ename, to_char(hiredate,'YYYY"年"MM"月"DD"日"') from emp; + (3)LAST_DAY(date):返回指定日期所在月的最后一天。 + (4)ADD_MONTHS(date,i):返回日期date加上i个月后的日期值,若i是负数,则获得的是减去i个月后的日期值。 + (5)MONTHS_BETWEEN(date1,date2):计算两个日期之间相差多少个月;若date2时间比date1时间晚,会得到负值,除非两个日期间隔是整数月,否则会得到带小数位的结果。 + (6)date日期类型在数据库中可以进行减法操作,结果是相差的天数:select ename, sysdate-hiredate from emp; + (7)LEAST(date1,date2):显示两个时间中的最小值。参数类型必须一致。 + (8)GREATEST(date1,date2):显示两个时间中的最大值。参数类型必须一致。 + (9)EXTRACT(date from datetime):从参数datetime中提取参数date指定的数据,比如提取:年、月、日。 + (4)空值函数:2 + null的含义:有时表中的某些字段值数据未知或暂时不存在,取值null。在Java中引用类型的默认值为null,在sql中,任何数据类型均可取值为null。 + null条件查询:不等于任何值, is null 和 is not null. + NVL(arg1,arg2):将null转变为非null值。如果arg1为null,返回arg2;否则返回本身。arg1和arg2可以是任何参数类型,但两个参数的数据类型必须是一致的。 + NVL2(arg,res1,res2):如果arg为null,则返回res2,arg不为null则返回res1. +11.基本查询语句 + (1)from子句:select * from table_name;select用于指定要查询的列,from指定要从哪个表中查询。 + (2)where子句:在select语句中可以在where子句中使用比较操作符限制查询结果。 +12.查询条件 + (1)比较运算符:>,<,>=,<=,<>,= + (2)关键字:AND(并且),OR(或),AND优先级高于OR,可以使用()来提高OR的优先级顺序。 + (3)模糊查询 + LIKE:可以模糊匹配字符串; + _代表任意一个字符,%代表任意0~n个字符。 + (4)IN和NOT IN: + IN(list):取出列表范围中的数据。 + NOT IN(list):取出不符合此列表中的数据记录。 + (5)BETWEEN...AND...:是用来查询符合某个值域范围条件的数据。 + (6)ALL和ANY: ALL和ANY不能单独使用,需要配合单行比较操作符(>,<,>=,<=,<>,=)一起使用。 + >ANY:大于最小 + ALL:大于最大 + , <, >=, <=, <>, !=, is null(is not null), between...and..., in; + 逻辑运算符not, and, or + BETWEEN...AND...和AND的区别: + BETWEEN...AND...:只能用来比较一个字段值 + AND:可以用来比较不同的字段 +14.ORDER BY:排序,对结果集的排序,必须出现在select的最后一个子句。 + asc或不写:升序;desc:降序。若排序的字段中包含null,则看作是最大值。 + 当以多列作为排序标准时,首先按照第一列进行排序,如果第一列数据相同,再以第二列排序,以此类推。 +15.聚合函数(多行函数,分组函数) + (1)MAX和MIN:用来取得列或表达式的最大、最小值。可以用来统计任何数据类型,包括数字、字符和日期。忽略NULL值。 + (2)AVG和SUM:用来统计列或表达式的平均值和总和,只能操作数字类型,忽略NULL值。 + (3)COUNT:用来计算表中的记录条数。忽略NULL值。 + (4)聚合函数对NULL值的处理:聚合函数忽略NULL值,select count(comm),avg(comm) from emp;--自动忽略comm为null的记录; + 如果不希望忽略NULL值,则需要使用NVL或NVL2:select count(nvl(comm,0)), avg(nvl(comm,0)) from emp; +16.GROUP BY:分组。将结果集按照指定字段进行分组。分组规则:该字段下的值一样的记录被看做一组。 + 如果select里面出现了聚合函数,同时又出现了某一字段时,那么该字段必须出现在group by子句中。 + where后面不能使用聚合函数,因为where是非分组函数的过滤判断。select max(sal),deptno from emp where max(sal)>4000 group by deptno;--不能执行 + HAVING:是分组(聚合)函数的过滤判断;必须跟在GROUP BY之后,不能单独存在;用来对分组后的结果进一步限制;比如按部门分组后,得到每个部门的最高工资,可以继续限制输出结果。 + 查询部门中最大工资超过4000的部门以及最大工资:select max(sal),deptno from emp group by deptno having max(sal)>4000; +17.SELECT语句执行过程: + (1)通过FROM子句中找到需要查询的表。 + (2)通过WHERE进行非分组函数的筛选判断。 + (3)通过GROUP BY子句完成分组操作。 + (4)通过HAVING子句完成组函数筛选判断。 + (5)通过SELECT子句选择要显示的列或表达式及组函数。 + (6)通过ORDER BY子句进行排序操作。 +18.函数总结 + 单行函数和多行函数的分类并举例说明: + 单行函数: + 字符函数13:CONCAT(c1,c2), LENGTH(ch), UPPER(字段名), LOWER(字段名), INITCAP(字段名), TRIM('e'FROM'ee'), LTRIM('ee','e'), RTRIM('ee','e'), LPAD(ch1, m, ch2), RPAD(ch1, m, ch2), SUBSTR(ch,m,n), INSTR(ch1,ch2,m,n) + 数值函数5:ROUND(n,m), TRUNC(n,m), MOD(m,n), CEIL(n), FLOOR(n) + 日期函数9:sysdate, systimestamp, LAST_DATE(date), ADD_MONTHS(date,i), MONTHS_BETWEEN(date1,date2), LEAST(date1,date2), GREATEST(date1,date2), EXTRACT(date from datetime) + 转换函数: + 显示转换:TO_DATE(), TO_CHAR() + 隐式转换:其它类型与字符串连接通常会转换为字符串。 + 通用函数2:NVL(), NVL2() + 注意:通常用于操作单行数据,可以任意嵌套多层,多层时由内向外依次执行。 + 多行函数(聚合函数)5:MAX()最大值, MIN()最小值, SUM()求和, AVG()平均值, COUNT()统计 +19.关联查询: + (1)概念:实际应用中所需要的数据,经常会需要查询两个或两个以上的表,这种查询叫做连接查询,连接查询通常建立存在相互关系的父子关系。 + (2)外键:保存另一张表主键的列称为外键。含有外键的表,在关联关系中属于多的一方。 + (3)表与表之间的关系:一对多(外键),多对多(通过第三张表建立关系),一对一。 + (4)N张表的关联查询最少需要(N-1)个连接条件;等值连接:外键=主键;若不指定连接条件,会出现笛卡尔积(指做关联操作的每个表的每一行和其它表的每一行做组合,是无意义的结果集)。 + (5)总结: + 可以给表起别名,通过别名指定字段属于哪个表;若两个表字段名称相同则必须指明数据来源。 + 只有满足连接条件的结果,才会被查询出来。(比如deptno40里没有人,因此不会被显示出来)。 + 若有过滤条件,需同时满足连接条件和过滤条件的数据才会被查询出来。 +20.连接种类: + ?内连接:返回所有满足连接条件的记录,功能上和等值连接没有区别,只是写法不同。 + 语法:表1 INNER JOIN 表2 ON 连接条件;(INNER可以省略) + 外连接:返回满足连接条件的数据记录,有些情况下需要返回那些不满足连接条件的记录,需要使用外连接。将满足和不满足连接条件的结果全部查询出来。 + create table empc as select * from emp;--快速从一个表中复制数据 + insert into empc(empno, ename, deptno)values(1000,'JACK',50); + 左外连接:(左表的全部,右表的部分)根据左表的记录,在被连接的右表中找出符合条件的记录与之匹配,如果找不到与左表匹配的用null表示。 + 语法:表1 LEFT OUTER JOIN 表2 ON 连接条件;(OUTER可以省略) + 右外连接:(右表的全部,左表的部分)根据右表的记录,在被连接的左表中找出符合条件的记录与之匹配,如果找不到与右表匹配的用null表示。 + 语法:表1 RIGHT OUTER JOIN 表2 ON 连接条件;(OUTER可以省略) + 全外连接:返回符合条件的所有表的记录,没有与之匹配的,用null表示(结果是左连接和右连接的并集)。 + 语法:表1 FULL OUTER JOIN 表2 ON 连接条件;(OUTER可以省略) + ?自连接:连接的两个表都是同一个表,表中的一个字段可以对应当前表的其它字段。 + Oracle数据库自带语法: + (1)笛卡儿积: + (2)内连接:a.等值连接 + b.非等值连接:输出员工编号、姓名、工资、工资等级:select e.empno, e.ename, e.sal, s.grade from emp e, salgrade s where e.sal between s.losal and s.hisal; + c.左外连接:select empno, ename, dname from emp e, dept d where e.deptno=d.deptno(+);--查询员工的编号,姓名,部门名称,包括不属于任何部门的员工。 + d.右外连接:select empno, ename, dname from emp e, dept d where e.deptno(+)=d.deptno;--查询员工的编号,姓名,部门名称,包括没有员工的部门。 + e.自连接: + 通用标准的SQL99语法: + (1)交叉连接:交叉连接和笛卡尔积的连接模式相同,都是表1中的每一行都与表2中的所有行建立一次连接。select * from emp cross join dept; + (2)自然连接:select * from emp natural join dept;--若能够匹配到等值条件(外键约束或相同的列),那么就是等值连接的结果.根据dept进行等值连接。 + select * from emp natural join salgrade;--若不能匹配到等值条件,那么结果就是交叉连接。 + (3)左外连接:left outer join + (4)右外连接:right outer join + (5)全外连接:full outer join +21.子查询: + 为了给查询提供数据而首先执行的查询语句叫做子查询。子查询是嵌入在其它SQL语句中的SELECT语句。子查询嵌入的语句称作主查询或父查询。 + 注意事项: + (1)子查询需要写在括号中。 + (2)子查询需要写在运算符的右端。 + (3)子查询可以写在WHERE,HAVING,FROM子句中。 + (4)子查询中通常不写ORDER BY。 + 子查询在WHERE子句中:根据返回结果的不同,子查询分为单行子查询,多行子查询及多列子查询。 + (1)单行子查询:返回一行一列数据,要求使用单行操作符(>,>=,<,<=,<>,=) + (2)多行子查询:返回多行数据,使用多行操作符(in,all,any) + (3)多列子查询: 通常用于建立在二次查询,常出现在FROM子句中。 + 统计低于自己工资低于所在部门平均工资的员工信息: + a.分组统计部门平均工资:select avg(sal) aa, deptno from emp group by deptno + b.员工工资小于<部门平均工资:select sal, ename, e.deptno from emp e, (select avg(sal) aa, deptno from emp group by deptno) t where e.deptno=t.deptno and e.sal=6; + 页码:page,每页最多pageSize为5,第一页1~5,第二页6~10,第三页11~15. start=(page-1)pageSize+1; end=pageSize*page; +23.DECODE函数 + DECODE(参数1,值1,结果1,值2,结果2...[,默认值]);用参数依次去和值匹配,匹配到了则显示相应的结果;无匹配则显示默认值,默认值不存在则显示null(相当于Java中的switch)。 + --查询职员表,根据职员的职位计算奖励金额,当职位分别是'MANAGER','SALESMAN','ANALYST'时,奖励金分别是薪水的1.2,1.1,1.05倍,其它为原本的薪水值。 + select ename, job, sal, decode(job,'MANAGER',sal*1.2,'SALESMAN',sal*1.1,'ANALYST',sal*1.05,sal) "奖金" from emp; + select * from emp order by decode(job,'MANAGER','1','SALESMAN','2','ANALYST','3');--自定义排序 +24.集合函数 + (1)UNION并集:将两个查询结果进行排序。union(忽略重复数据,并排序), union all(不忽略重复数据,不排序); + select * from emp where sal>1500 union select * from emp where deptno=20;--并集之后,总共9条记录 + (2)INTERSECT交集:同时存在于两个结果集中的数据。 + (3)MINUS差集:两个结果相减。 + (4)使用集合函数的原因:所有的查询结果可能不是来自同一张表,并且表与表之间无关联。 + (5)注意事项:a.对应的列的类型需要匹配。 + b.列的类型要按照顺序写。 + c.列的数量要一致,如果不一致时,用null去补充不匹配的列。 +25.DDL语句管理表: + (1)创建表空间:逻辑单位,通常我们新建一个项目,就会新创建表空间,在表空间中创建用户来创建表。 + 先切换到system,语法:CREATE tablespace 表空间名称 datafile '文件的路径' size 大小 autoextend on 自动拓展 next 每次扩展的大小; + (2)删除表空间:drop tablespace 表空间名称 + (3)创建用户:create user 用户名 identified by 密码 default tablespace 表空间的名称; + (4)删除用户:drop user 用户名 cascade; + (5)更改用户密码:alter user 用户名 identified by 密码; + (6)授权:grant connect to 用户名; + (7)分配角色:grant dba to 用户名; + (8)使用子查询的方式创建表(切换完了新创建的用户之后): + 只复制表结构和表数据,不会复制列的约束:create table emp as select * from scott.emp;-- + 如果查询语句有结果,就是复制表结构和数据,如果没有结果,就是复制表结构:create table dept as select * from scott.dept where 1=2;--只复制表结构,无数据,因为1=2为false。 + 只复制表数据(添加语句里可以没有values关键字):insert into 表名 查询语句 (表的结构与已有表结构一致):insert into dept select * from scott.dept; +26.列的约束:约束主要是用来约束表中数据的规则。 + 主键约束:primary key 不能为空,必须唯一。 + 非空约束:not null + 唯一约束:unique + 检查约束:check(条件) 在MySql中是可以写的,但MySql会直接忽略检查。price number(10,2) check(price>100),--检查约束,在创建表的时候直接写(和primary key, not null, unique一个位置或之后) + 外键约束:主要是用来约束从表A中的记录必须是存在于主表B中(保证数据完整性)。 + (1)references 外表名(外表的列名), --在创建表的时候直接写(和primary key, not null, unique, check一个位置或之后) + (2)foreign key(自己的列名) references 外表名(外表的列名)--另一种外键约束的方式,写在最后一个括号的前面 + (3)alter table books add foreign key(cid) references category(id);--可以不在定义表中建立外键约束,单独用此语句也可实现外键约束。 +27.视图:数据库对象之一,视图在sql语句中体现的角色和表完全相同,但视图并不是一个真实存在的表,它对应的是一个查询语句的结果集(视图名和表名不能一样)。 + 作用:简化复杂查询,可以限制数据访问。 + (1)创建简单视图(单表):若无权限,使用system用户授权,视图授权语句:grant create view to 用户名。 + create view v_emp_10 as select empno,ename,sal,deptno from emp where deptno=10; + (2)修改视图就是替换该视图的子查询,使用create or replace view 视图名 即可,若视图不存在就创建,存在就替换。创建视图时,可以给列赋予别名。 + create or replace view v_emp_10 as select empno id,ename name,sal,deptno from emp where deptno=10; + (3)查询视图:列名若有别名,以别名为准,不是原列名。select * from v_emp_10; + (4)视图的DML操作(不建议):对视图进行DML操作就是对视图数据来源的基础表进行操作。 + a.插入数据:视图中看不见的字段都被插入默认值,所以不能违反基础表中相应字段的约束(比如看不见的字段的not null等约束,否则会插入失败)。 + b.为视图添加检查选项可以避免对视图进行DML操作时污染基础表的情况,在创建语句后加with check option + create or replace view v_emp_10 as select empno id,ename name,sal,deptno from emp where deptno=10 with check option;--不能对基础表中deptno10以外的数据进行DML操作。 + c.with read only:只读,不能对视图进行DML操作。如果没有在视图上执行DML操作的必要,在建立视图时声明为只读来避免这种情况,保证视图对应的基础表数据不会被非法修改。 + create or replace view v_emp_10 as select empno,ename,sal,deptno from emp where deptno=10 with read only;--with read only只读,不能对视图进行DML操作。 + (5)视图根据子查询的不同,分为简单视图和复杂视图,当子查询中包含单行函数、表达式或分组函数时,该视图是一个复杂视图。复杂视图不能进行DML操作,并且必须被子查询中的表达式或函数定义别名。 + (6)删除视图:DROP VIEW 视图名称。 +28.序列:sequence是用来生成唯一数字值的数据库对象,通常作为表的主键值。序列是独立的数据库对象,序列并不依附于表。 + (1)创建序列:create sequence 序列名 [start with **(起始数据) increment by **(步长,每次增加几,可正可负) maxvalue **(最大值) / minvalue **(最小值)]; + (2)序列中有两个伪列:nextval/*获取序列的下个值*/ ,currval/*获取序列的当前值*/ + 当序列创建以后必须先执行nextval,之后才能使用currval。获取序列的第一个值,并使用序列值为users表插入新的记录。 + select users_seq.currval from dual;--查看当前序列值。 + (3)删除序列:drop sequence users_seq; + (4)例子: + create sequence users_seq start with 100 increment by 10;--建立序列,第一次一定要用nextval,不能用currval + insert into users(id,name)values(users_seq.nextval,'Tony');--插入基表 + select users_seq.currval from dual;--查看当前序列值。 + drop sequence users_seq;--删除序列 + +29.索引:一种提高查询效率的机制(类似于字典的目录),经常作为过滤条件、去重、排序或链接条件的字段,可以为其添加索引。 + ?(1)创建索引:create [unique] index 索引名称 on 表名(列名) + create index idx_users_name on users(ename);--在users表的ename列上建立索引 + (2)添加多列索引:create index idx_users_salary on users(name,salary); + (3)查询过程中自动应用索引,不需要单独去制定,提高查询速度。 + select users.* from users order by name, salary; + (4)重构索引(索引是平衡二叉树,修改表后,最好重构一下索引的平衡二叉树) + alter index 索引名称 rebuild;--经常修改数据的表,不建议建立索引。 + (5)删除索引:drop index idx_users_salary; \ No newline at end of file diff --git a/JDBC/src/note/sql/SQLPractice.sql b/JDBC/src/note/sql/SQLPractice.sql new file mode 100644 index 0000000..ad16146 --- /dev/null +++ b/JDBC/src/note/sql/SQLPractice.sql @@ -0,0 +1,233 @@ +1~10 homework: +--1、向USERS表中插入性别字段,并指定默认值为男 +alter table userplus add(sex char(2) default '男'); +--2、删除名字是张三的人的信息 +delete from userplus where username='张三'; +--3、查询USERS表中用户的姓名 +select username from userplus; +--4、查询每个用户的工资是多少 +select username, salary from userplus; +--5、查看阿三的工资 +select salary from userplus where username='阿三'; +--6、查询每个用户的年薪 +select salary*12 as "年薪" from userplus; +--7、查询用户工资大于2000的用户信息 +select * from userplus where salary > 2000; +--8、将 姓名 工资 连接显示 +select username||': '||salary as "姓名:工资" from userplus; +--9、查询USERS表中每个用户的名字长度 +select username,length(username) from userplus; +--10、查询名字3位以上的用户编号、姓名、工资、工作 +select id, username, salary, job from userplus where length(username)>=3; + +10~12 homework: +--1、请查询表DEPT中所有部门的情况。 +select * from dept; +--2、查询表DEPT中的部门号、部门名称两个字段的所有信息。 +select deptno, dname from dept; +--3、请从表EMP中查询10号部门工作的雇员姓名和工资。 +select ename, sal from emp where deptno=10; +--4、请从表EMP中查找工种是职员CLERK或经理MANAGER的雇员姓名、工资。 +select ename, sal from emp where job in ('CLERK','MANAGER'); +--5、请在EMP表中查找部门号在10-30之间的雇员的姓名、部门号、工资、工作。 +select ename, deptno, sal, job from emp where deptno between 10 and 30; +--6、请从表EMP中查找姓名以J开头所有雇员的姓名、工资、职位。 +select ename, sal, job from emp where ename like 'J%'; +--7、请从表EMP中查找工资低于2000的雇员的姓名、工作、工资,并按工资降序排列。 +select ename, job, sal from emp where sal<2000 order by sal desc; +--8、在表EMP中查询所有工资高于JONES的所有雇员姓名、工作和工资。 +select ename, job, sal from emp where sal>(select sal from emp where ename='JONES'); +--9、列出没有对应部门表信息的所有雇员的姓名、工作以及部门号。 +select ename, job, deptno from emp where deptno not in(select deptno from dept); +--10、查找工资在1000~3000之间的雇员所在部门的所有人员信息 +select * from emp where deptno in (select distinct deptno from emp where sal between 1000 and 3000); +--11、查询所有雇员的姓名、SAL与COMM之和。 +select ename, sal, comm, NVL2(comm,comm+sal,sal) from emp; +--12、查询所有在CHICAGO工作的经理MANAGER和销售员SALESMAN的姓名、工资 +select ename, sal from emp where deptno=(select deptno from dept where loc='CHICAGO') and job in('MANAGER','SALESMAN'); +select a.ename, a.sal from emp a, dept b where a.deptno=b.deptno and b.loc='CHICAGO' and a.job in('MANAGER','SALESMAN'); +--13、查询显示每个雇员加入公司的准确时间,按××××年××月××日 时分秒显示。 +select ename, to_char(hiredate,'YYYY"年"MM"月"DD"日" HH:MI:SS') from emp; + +13~18 homework: +select * from dept +select * from emp +--1.列出至少有一个员工的所有部门。 +select deptno from emp group by deptno having count(empno)>=1; +--2.列出薪金比“SMITH”多的所有员工。 +select * from emp where sal>(select sal from emp where ename='SMITH'); +--3.列出最低薪金大于1500的各种工作。 +select distinct(job) from emp group by job having min(sal)>1500; +--4.查询部门20,30 中的岗位不是"CLERK"或"SALESMAN"的所有员工信息 +select * from emp where deptno in (20,30) and job not in('CLERK','SALESMAN'); +--5.查询比平均员工工资高的员工信息 +select * from emp where sal > (select avg(sal) from emp); +--6.找出部门10中所有经理和部门20中所有办事员的详细资料。 +select * from emp where (deptno=10 and job='MANAGER') or (deptno=20 and job='CLERK'); +--7.显示不带有“R”的雇员姓名。 +select ename from emp where ename not like '%R%'; +--8.显示雇员姓名,根据其服务年限,将最老的雇员排在最前面。 +select ename, hiredate from emp order by hiredate asc; +--9.对于每个雇员,显示其加入公司的天数 +select ename, trunc(sysdate-hiredate+1) as "天数" from emp; +--10.查询各个职位的平均工资是多少? +select job, avg(sal) from emp group by job; +--11.查看每个部门有多少人 +select deptno, count(*) from emp group by deptno; +--12.查看每个职位的平均工资与工资总和 +select job, avg(sal),sum(sal) from emp group by job; +--13.查出emp表中所有部门的最高薪水和最低薪水,部门编号为10的部门不显示。 +select deptno, max(sal), min(sal) from emp where deptno<>10 group by deptno; +--14.查询出名字中有“A”字符,并且薪水在1000以上(不包括1000)的所有员工信息。 +select * from emp where ename like '%A%' and sal>1000; +--15.显示薪水最高人的职位。 +select job from emp where sal=(select max(sal) from emp); +select job from emp where sal>=all(select sal from emp); +--16.列出所有员工的年工资,按年薪从低到高排序。 +select ename, sal*12 as "年薪" from emp order by sal; + +19~21 homework: +select * from emp; +select * from salgrade; +--1.显示员工表中的不重复的岗位job +select distinct(job) from emp; +--2.查询10部门工资大于3000的员工信息,要求按员工的入职时间由前到后排序 +select * from emp where deptno=10 and sal>3000 order by hiredate; +--3.列出各个部门的MANAGER 的最低薪金 +select deptno,min(sal) from emp where job='MANAGER' group by deptno; +--4.查询所有员工的工作地点,包括没有员工的地点也要显示 +select ename,loc from dept d left outer join emp e on d.deptno=e.deptno; +--5.查询所有的员工信息和部门名称,包括不属于任何部门的员工 +select empno, ename, dname, e.deptno from emp e left outer join dept d on e.deptno=d.deptno; +--6.列出和"SCOTT"从事相同工作的所有员工及部门名称 +select empno, ename, job, dname from emp e,dept d where e.deptno=d.deptno and job=(select job from emp where ename='SCOTT'); +--7.列出受雇日期早于直接上级的所有员工的编号,姓名,部门名称 +select empno, ename, e.deptno, dname from emp e,dept d where e.deptno=d.deptno and hiredate<(select hiredate from emp m where e.mgr=m.empno); +--8.列出职位为“CLERK”的员工姓名和其所在部门名称,部门人数 +select ename, dname, t.b from emp e, dept d, (select deptno,count(*) b from emp group by deptno) t where e.deptno=d.deptno and e.deptno=t.deptno and job='CLERK'; +--9.查询至少有4个员工的部门的部门名称 +select e.deptno, count(*),dname from emp e, dept d where e.deptno=d.deptno group by e.deptno,dname having count(*)>4; +select d.dname from dept d where deptno in (select deptno from emp group by deptno having count(*)>4); + --自己写的 +select d.deptno, d.dname, t.count from emp e, dept d, (select count(*) count from emp a group by deptno) t where e.deptno=d.deptno and t.count>4; +--10.查询工资高于30号部门的所有员工的工资的员工姓名、工资及部门名称 +select ename, sal, e.deptno, dname from emp e,dept d where sal>(select max(sal) from emp where deptno=30); +--11.查询出“KING”所在部门的部门编号、部门名称以及该部门里的员工人数 +select e.deptno, dname, count(*) from emp e,dept d where e.deptno=d.deptno and e.deptno=( select deptno from emp where ename='KING') group by e.deptno,dname; + --自己写的,不太好: +select e.deptno, dname, e.deptno,(select count(*) count from emp where deptno= (select deptno from emp where ename='KING')) from emp e, dept d where e.deptno=d.deptno and ename='KING'; +--12.查询平均工资最高的部门的部门编号、部门名称和该部门的平均工资 +select e.deptno, d.dname, avg(sal) from emp e, dept d where e.deptno=d.deptno group by e.deptno,d.dname having avg(sal)>=all(select avg(sal) from emp group by deptno); + --自己写的 +select deptno from emp group by deptno having avg(sal)>=all(select avg(sal) from emp group by deptno); +--13.工资等级为2等级的 员工信息及其所在部门的信息 +select * from emp e,dept d, salgrade s where e.deptno=d.deptno and s.grade=2 and e.sal between s.losal and s.hisal; + --自己写的 +select e.ename, e.sal from emp e,dept d, (select losal, hisal from salgrade where grade=2) t where e.deptno=d.deptno and e.sal between t.losal and t.hisal; +--14.10号部门的部门信息 人员信息 工资等级 +select d.*,e.*,s.grade from emp e,dept d, salgrade s where e.deptno=d.deptno and e.deptno=10 and e.sal between s.losal and s.hisal; + --自己写的 +select ename, sal, (select t.grade from salgrade t where e.sal between t.losal and t.hisal) grade from emp e where deptno=10; +--15.查询最高领导者的薪水等级 +select grade from salgrade where (select sal from emp where mgr is null) between losal and hisal + --自己写的 +select ename, sal, (select t.grade from salgrade t where e.sal between t.losal and t.hisal) grade from emp e where mgr is null; +--16.SQL语句的执行过程及其每条子句的作用? +FROM,WHERE,GROUP BY,HAVING,SELECT,ORDER BY +--17.数据库的运算符类型及优先级? +();算术运算符*,/,+,-;连接符||;比较运算符=, >, <, >=, <=, <>, !=, is null(is not null), between...and..., in;逻辑运算符not, and, or +--18.数据库的函数分类? +DDL,DML,TCL,DQL,DCL +字符,数值,日期,转换 +--19.事务的四个特性 +原子性 +一致性 +隔离性 +持久性 + +--小总结: +--SQL语句的执行过程及其每条子句的作用? +(1)通过FROM子句中找到需要查询的表。 +(2)通过WHERE进行非分组函数的筛选判断。 +(3)通过GROUP BY子句完成分组操作。 +(4)通过HAVING子句完成组函数筛选判断。 +(5)通过SELECT子句选择要显示的列或表达式及组函数。 +(6)通过ORDER BY子句进行排序操作。 + +--数据库的运算符类型及优先级? +(); +算术运算符*,/,+,-; +连接符||; +比较运算符=, >, <, >=, <=, <>, !=, is null(is not null), between...and..., in; +逻辑运算符not, and, or + +--数据库的函数分类? +单行函数:CONCAT(c1,c2), LENGTH(ch), UPPER(字段名), LOWER(字段名), INITCAP(字段名), TRIM('e'FROM'ee'), LTRIM('ee','e'), RTRIM('ee','e'), LPAD(ch1, m, ch2), RPAD(ch1, m, ch2), SUBSTR(ch,m,n), INSTR(ch1,ch2,m,n) +数值函数:ROUND(n,m), TRUNC(n,m), MOD(m,n), CEIL(n), FLOOR(n) +日期函数:sysdate, systimestamp, LAST_DATE(date), ADD_MONTHS(date,i), MONTHS_BETWEEN(date1,date2), LEAST(date1,date2), GREATEST(date1,date2), EXTRACT(date from datetime)聚合函数:count(),avg(),sum(),max(),min(), +转换函数: + 显示转换:TO_DATE(), TO_CHAR() + 隐式转换:其它类型与字符串连接通常会转换为字符串。 +通用函数:NVL(), NVL2() +多行函数(聚合函数):MAX()最大值, MIN()最小值, SUM()求和, AVG()平均值, COUNT()统计 + +--结构化查询语言分类和作用? +SQL分类: + DDL:数据定义语言,用于操作数据对象(表,视图,序列,索引)。 + CREATE:创建表或其它对象。 + ALTER:修改表或其它对象结构。 + DROP:删除表或其它对象。 + TRUNCATE:删除表数据,保留表结构。清空表的操作。 + DML:数据操作语言(通常需要伴随TCL),用于增删改表中的数据。 + INSERT INTO:将数据插入表中。 + DELETE:删除表中数据。 + UPDATE SET:更新表中数据。 + TCL:事务控制语言。 + COMMIT:提交。 + ROLLBACK:回滚。 + DQL:数据查询语言 + SELECT:查询数据。 + DCL:数据控制语言。 + GRANT:授予权限。 + grant…create…view…to…scott; + +--事务的特性? +原子性(Atomicity): +  原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚。因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。 +一致性(Consistency): + 一致性是指一个事务执行之前和执行之后都必须处于一致性状态。拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性。 +隔离性(Isolation): +  隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。 +持久性(Durability): +  持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。 + +--Oracle数据库自带语法和通用标准的SQL99语法? +Oracle数据库自带语法: + (1)笛卡儿积: + (2)内连接:a.等值连接 + b.非等值连接:输出员工编号、姓名、工资、工资等级:select e.empno, e.ename, e.sal, s.grade from emp e, salgrade s where e.sal between s.losal and s.hisal; + c.左外连接:select empno, ename, dname from emp e, dept d where e.deptno=d.deptno(+);--查询员工的编号,姓名,部门名称,包括不属于任何部门的员工。 + d.右外连接:select empno, ename, dname from emp e, dept d where e.deptno(+)=d.deptno;--查询员工的编号,姓名,部门名称,包括没有员工的部门。 + e.自连接: +通用标准的SQL99语法: + (1)交叉连接:交叉连接和笛卡尔积的连接模式相同,都是表1中的每一行都与表2中的所有行建立一次连接。select * from emp cross join dept; + (2)自然连接:select * from emp natural join dept;--若能够匹配到等值条件(外键约束或相同的列),那么就是等值连接的结果.根据dept进行等值连接。 + select * from emp natural join salgrade;--若不能匹配到等值条件,那么结果就是交叉连接。 + (3)左外连接:left outer join + (4)右外连接:right outer join + (5)全外连接:full outer join + +--数据中的约束? +主键约束:primary key 不能为空,必须唯一。 +非空约束:not null +唯一约束:unique +检查约束:check(条件) 在MySql中是可以写的,但MySql会直接忽略检查。price number(10,2) check(price>100),--检查约束,在创建表的时候直接写(和primary key, not null, unique一个位置或之后) +外键约束:主要是用来约束从表A中的记录必须是存在于主表B中(保证数据完整性)。 + (1)references 外表名(外表的列名), --在创建表的时候直接写(和primary key, not null, unique, check一个位置或之后) + (2)foreign key(自己的列名) references 外表名(外表的列名)--另一种外键约束的方式,写在最后一个括号的前面 + (3)alter table books add foreign key(cid) references category(id);--可以不在定义表中建立外键约束,单独用此语句也可实现外键约束。 + +--用一条sql语句查出emp表中工资从大到小排在4,5,6位工资? +select * from (select rownum rn, e.* +from (select ename, sal from emp order by sal desc) e where rownum<=6)t +where t.rn >=4; \ No newline at end of file diff --git "a/JDBC/src/note/sql/\345\244\232\350\241\250\346\237\245\350\257\242\347\273\203\344\271\240\357\274\210\347\255\224\346\241\210\357\274\211.txt" "b/JDBC/src/note/sql/\345\244\232\350\241\250\346\237\245\350\257\242\347\273\203\344\271\240\357\274\210\347\255\224\346\241\210\357\274\211.txt" new file mode 100644 index 0000000..ca083df --- /dev/null +++ "b/JDBC/src/note/sql/\345\244\232\350\241\250\346\237\245\350\257\242\347\273\203\344\271\240\357\274\210\347\255\224\346\241\210\357\274\211.txt" @@ -0,0 +1,97 @@ +锘1.鍒楀嚭閮ㄩ棬鍚嶇О鍜岃繖浜涢儴闂ㄧ殑鍛樺伐淇℃伅锛屽悓鏃跺垪鍑洪偅浜涙病鏈夊憳宸ョ殑閮ㄩ棬 +select dept.dname,emp.* from dept +left outer join emp +on dept.deptno=emp.deptno; + +2.鍒楀嚭鍦ㄦ瘡涓儴闂ㄥ伐浣滅殑鍛樺伐鏁伴噺銆佸钩鍧囧伐璧勩 +select dept.deptno,count(emp.empno),avg(sal) +from dept +left outer join emp +on dept.deptno=emp.deptno +group by dept.deptno; + +3.鍒楀嚭鎵鏈夊憳宸ョ殑濮撳悕銆侀儴闂ㄥ悕绉板拰宸ヨ祫銆 +select emp.ename, dept.dname,emp.sal +from emp, dept +where emp.deptno=dept.deptno; + +4.鏌ヨ姣忎釜閮ㄩ棬鐨勯儴闂ㄧ紪鍙凤紝閮ㄩ棬鍚嶇О锛岄儴闂ㄤ汉鏁帮紝鏈楂樺伐璧勶紝鏈浣庡伐璧勶紝宸ヨ祫鎬诲拰锛屽钩鍧囧伐璧 +select d.deptno,d.dname,count(e.ename), +max(e.sal),min(e.sal),sum(sal),avg(sal) +from dept d join emp e on e.deptno=d.deptno +group by d.deptno,d.dname + +5.鏌ヨ姣忎釜缁忕悊鎵绠$悊鐨勪汉鏁帮紝缁忕悊缂栧彿锛岀粡鐞嗗鍚嶏紝瑕佹眰鍖呮嫭娌℃湁缁忕悊鐨勪汉鍛樹俊鎭 +select count(e.empno),m.empno,m.ename +from emp e +left join emp m +on e.mgr = m.empno +group by m.empno,m.ename; + +6.鏌ヨ閮ㄩ棬浜烘暟澶т簬2鐨勯儴闂ㄧ紪鍙凤紝閮ㄩ棬鍚嶇О锛岄儴闂ㄤ汉鏁 +select d.deptno,d.dname,count(e.ename) +from dept d +join emp e on d.deptno=e.deptno +group by d.dname,d.deptno +having(count(e.ename)>2); + +7.鏌ヨ閮ㄩ棬骞冲潎宸ヨ祫鍦2500鍏冧互涓婄殑閮ㄩ棬鍚嶇О鍙婂钩鍧囧伐璧勩 +select d.dname ,avg(e.sal) +from dept d +join emp e on d.deptno=e.deptno +group by d.dname +having(avg(e.sal)>2500); + +8.鏌ヨ鍛樺伐宀椾綅涓笉鏄互"SA"寮澶村苟涓斿钩鍧囧伐璧勫湪 2500鍏冧互涓婄殑宀椾綅鍙婂钩鍧囧伐璧勶紝骞舵寜骞冲潎宸ヨ祫闄嶅簭鎺掑簭銆 +select e.job,avg(e.sal) +from emp e +where e.job not like 'SA%' +group by e.job +having avg(e.sal)>2500 +order by avg(e.sal) desc + +9.鏄剧ず缁忕悊鍙风爜鍜岀粡鐞嗗鍚嶏紝杩欎釜缁忕悊鎵绠$悊鍛樺伐鐨勬渶浣庡伐璧勶紝娌℃湁缁忕悊鐨凨ING涔熻鏄剧ず锛屼笉鍖呮嫭鏈浣庡伐璧勫皬浜 +3000鐨勶紝鎸夋渶浣庡伐璧勭敱楂樺埌浣庢帓搴忋 +select m.empno,m.ename,min(e.sal) +from emp e +left join emp m +on e.mgr = m.empno +group by m.empno,m.ename +having min(e.sal)>=3000 +order by min(e.sal) desc; + +10.鏌ヨ閮ㄩ棬骞冲潎宸ヨ祫澶т簬2000锛屼笖浜烘暟澶т簬2鐨勯儴闂ㄧ紪鍙凤紝閮ㄩ棬鍚嶇О锛岄儴闂ㄤ汉鏁帮紝閮ㄩ棬骞冲潎宸ヨ祫锛屽苟鎸夌収閮ㄩ棬浜烘暟鍗囧簭鎺掑簭銆 +select d.deptno,d.dname,count(e.ename),avg(e.sal) +from dept d +join emp e on d.deptno=e.deptno +group by d.dname,d.deptno +having(count(e.ename)>2) and (avg(e.sal)>2000) +order by count(e.ename) ; + +11.鏌ヨ閮ㄩ棬鏈浣庡伐璧 楂樹簬10鍙烽儴闂 鏈浣庡伐璧勭殑閮ㄩ棬鐨勭紪鍙枫佸悕绉板強閮ㄩ棬鏈浣庡伐璧勩 +SELECT e.deptno,d.dname,MIN(e.sal) +FROM emp e,dept d +WHERE e.deptno=d.deptno +GROUP BY deptno,dname +HAVING MIN(e.sal)>(SELECT MIN(sal) from emp WHERE deptno=10) + +12.鏄剧ず30鍙烽儴闂ㄧ殑闆囧憳鎵浠庝簨鐨勪笉閲嶅鐨勫伐浣滃悕绉帮紝骞舵樉绀30閮ㄩ棬鐨勬墍鍦ㄥ湴銆 +SELECT DISTINCT e.job,d.loc +FROM emp e,dept d +WHERE e.deptno=d.deptno AND e.deptno=30; + +13.鏌ヨ宸ヤ綔鍦ㄥ箍宸炵殑鍛樺伐浜烘暟锛屾渶楂樺伐璧勫強鏈浣庡伐璧勩 +select count(*) 鍛樺伐浜烘暟, +max(e.sal) 鏈楂樺伐璧勶紝 +min(e.sal) 鏈浣庡伐璧 +from emp e, dept d +where e.deptno = d.deptno +and d.loc = '骞垮窞'; + +14.缁熻鍚勪釜閮ㄩ棬涓嶅悓鑱屽姟鐨勫憳宸ヨ柂姘寸殑鎬诲拰锛屽钩鍧囧伐璧,閮ㄩ棬缂栧彿锛岄儴闂ㄥ悕绉,閮ㄩ棬浣嶇疆锛岃亴鍔 +SELECT dept.deptno,dname,loc,JOB,sum(sal),avg(sal) +FROM emp,dept +WHERE emp.deptno=dept.deptno +GROUP BY dept.deptno,dname,loc,JOB; + + diff --git "a/JDBC/src/note/sql/\345\244\232\350\241\250\346\237\245\350\257\242\347\273\203\344\271\240\357\274\210\350\207\252\345\267\261\357\274\211.sql" "b/JDBC/src/note/sql/\345\244\232\350\241\250\346\237\245\350\257\242\347\273\203\344\271\240\357\274\210\350\207\252\345\267\261\357\274\211.sql" new file mode 100644 index 0000000..2c215cd --- /dev/null +++ "b/JDBC/src/note/sql/\345\244\232\350\241\250\346\237\245\350\257\242\347\273\203\344\271\240\357\274\210\350\207\252\345\267\261\357\274\211.sql" @@ -0,0 +1,33 @@ +--1.列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门 +select dname, e.* from dept d left outer join emp e on d.deptno=e.deptno; +--2.列出在每个部门工作的员工数量、平均工资。 +select count(ename), avg(sal) from emp e right outer join dept d on d.deptno=e.deptno group by d.deptno; +--3.列出所有员工的姓名、部门名称和工资。 +select ename, dname, sal from emp e, dept d where e.deptno=d.deptno; +--4.查询每个部门的部门编号,部门名称,部门人数,最高工资,最低工资,工资总和,平均工资 +select d.deptno, dname, count(*), max(sal), min(sal), sum(sal), avg(sal) from emp e, dept d where d.deptno=e.deptno group by d.deptno, dname; +--5.查询每个经理所管理的人数,经理编号,经理姓名,要求包括没有经理的人员信息。 +select count(e.ename), m.empno,m.ename from emp e left join emp m on e.mgr=m.empno group by m.empno,m.ename +--6.查询部门人数大于2的部门编号,部门名称,部门人数 +select d.deptno, d.dname, count(*) from emp e, dept d where e.deptno=d.deptno group by d.deptno, d.dname having count(*)>2; +--7.查询部门平均工资在2500元以上的部门名称及平均工资。 +select d.dname, avg(sal) from emp e, dept d where e.deptno=d.deptno group by d.dname having avg(sal)>2500; +--8.查询员工岗位中不是以"SA"开头并且平均工资在 2500元以上的岗位及平均工资,并按平均工资降序排序。 +select job, avg(sal) from emp where job not like 'SA%' group by job having avg(sal)>2500 order by avg(sal) desc +--9.显示经理号码和经理姓名,这个经理所管理员工的最低工资,没有经理的KING也要显示, +--不包括最低工资小于3000的,按最低工资由高到低排序。 +select m.empno, m.ename, min(e.sal) from emp e left outer join emp m +on e.mgr=m.empno group by m.empno, m.ename having min(e.sal)>=3000 order by min(e.sal) desc; +--10.查询部门平均工资大于2000,且人数大于2的部门编号,部门名称,部门人数,部门平均工资,并按照部门人数升序排序。 +select d.deptno, d.dname, count(*), avg(sal) from emp e, dept d +where e.deptno=d.deptno group by d.deptno, d.dname +having count(*)>2 and avg(sal)>2000 order by count(*); +--11.查询部门最低工资 高于10号部门 最低工资的部门的编号、名称及部门最低工资。 +select d.deptno, dname, min(sal) from emp e, dept d where d.deptno=e.deptno group by d.deptno, dname +having min(sal)>(select min(sal) from emp where deptno = 10); +--12.显示30号部门的雇员所从事的不重复的工作名称,并显示30部门的所在地。 +select distinct job, d.loc from emp e, dept d where d.deptno=e.deptno and e.deptno=30; +--13.查询工作在'CHICAGO'的员工人数,最高工资及最低工资。 +select count(empno),max(sal),min(sal) from emp e, dept d where d.deptno=e.deptno and loc='CHICAGO'; +--14.统计各个部门不同职务的员工薪水的总和,平均工资,部门编号,部门名称,部门位置,职务 +select sum(sal),avg(sal),d.deptno,dname,loc, job from emp e, dept d where d.deptno=e.deptno group by d.deptno,dname,loc, job; diff --git a/JDBC/src/project/EmpManage_JDBC/bean/Dept.java b/JDBC/src/project/EmpManage_JDBC/bean/Dept.java new file mode 100644 index 0000000..2ec3353 --- /dev/null +++ b/JDBC/src/project/EmpManage_JDBC/bean/Dept.java @@ -0,0 +1,40 @@ +package project.EmpManage_JDBC.bean; + +public class Dept { + private int deptno;//閮ㄩ棬缂栧彿 + private String dname;//閮ㄩ棬鍚嶇О + private String loc;//閮ㄩ棬鍦板潃 + + public Dept() {} + + public Dept(int deptno, String dname, String loc) { + this.deptno = deptno; + this.dname = dname; + this.loc = loc; + } + + public int getDeptno() { + return deptno; + } + public void setDeptno(int deptno) { + this.deptno = deptno; + } + public String getDname() { + return dname; + } + public void setDname(String dname) { + this.dname = dname; + } + public String getLoc() { + return loc; + } + public void setLoc(String loc) { + this.loc = loc; + } + + @Override + public String toString() { + return "Dept [deptno=" + deptno + ", dname=" + dname + ", loc=" + loc + "]"; + } + +} diff --git a/JDBC/src/project/EmpManage_JDBC/bean/Emp.java b/JDBC/src/project/EmpManage_JDBC/bean/Emp.java new file mode 100644 index 0000000..4e3c941 --- /dev/null +++ b/JDBC/src/project/EmpManage_JDBC/bean/Emp.java @@ -0,0 +1,112 @@ +package project.EmpManage_JDBC.bean; + +import java.util.Date; + +/* + * ORM思想:对象关系映射 + */ +public class Emp { + + private int empno;//员工编号 + private String ename;//员工姓名 + private String job;//员工职位 + private int mgr;//员工的经理编号 + private Date hiredate;//员工入职时间 + private double sal;//员工工资 + private double comm;//员工奖金 + private int deptno;//员工部门编号 + private Dept dept;//员工的部门 + + public Dept getDept() { + return dept; + } + + public void setDept(Dept dept) { + this.dept = dept; + } + + public Emp() {} + + public Emp(int empno, String ename, String job, int mgr, Date hiredate, double sal, double comm, int deptno) { + this.empno = empno; + this.ename = ename; + this.job = job; + this.mgr = mgr; + this.hiredate = hiredate; + this.sal = sal; + this.comm = comm; + this.deptno = deptno; + } + + public int getEmpno() { + return empno; + } + + public void setEmpno(int empno) { + this.empno = empno; + } + + public String getEname() { + return ename; + } + + public void setEname(String ename) { + this.ename = ename; + } + + public String getJob() { + return job; + } + + public void setJob(String job) { + this.job = job; + } + + public int getMgr() { + return mgr; + } + + public void setMgr(int mgr) { + this.mgr = mgr; + } + + public Date getHiredate() { + return hiredate; + } + + public void setHiredate(Date hiredate) { + this.hiredate = hiredate; + } + + public double getSal() { + return sal; + } + + public void setSal(double sal) { + this.sal = sal; + } + + public double getComm() { + return comm; + } + + public void setComm(double comm) { + this.comm = comm; + } + + public int getDeptno() { + return deptno; + } + + public void setDeptno(int deptno) { + this.deptno = deptno; + } + + @Override + public String toString() { + return "Emp [empno=" + empno + ", ename=" + ename + ", job=" + job + ", mgr=" + mgr + ", hiredate=" + hiredate + + ", sal=" + sal + ", comm=" + comm + ", deptno=" + deptno + ", dept=" + dept + "]"; + } + + +} diff --git a/JDBC/src/project/EmpManage_JDBC/dao/EmpDao.java b/JDBC/src/project/EmpManage_JDBC/dao/EmpDao.java new file mode 100644 index 0000000..289b290 --- /dev/null +++ b/JDBC/src/project/EmpManage_JDBC/dao/EmpDao.java @@ -0,0 +1,29 @@ +package project.EmpManage_JDBC.dao; + +import java.util.*; + +import project.EmpManage_JDBC.bean.Emp; + +/* + * JavaEE三层结构 + * dao层:dao层和数据库进行交互 + * service层:业务逻辑处理 + * web层::数据展示 + * 员工管理系统需求: + * 1.查询所有员工 + * 2.查询指定编号的员工 + * 3.添加员工信息 + * 4.删除指定编号的员工 + */ +public interface EmpDao { + + public Emp findOneEmp(int empno);//查询指定编号的员工 + public List findAllEmp();//查询所有员工 + public List selEmpInfo();//查询员工编号,姓名,工资,部门编号,部门名称 + public List selEmpByPage(int page,int pageSize);//分页查询 + public List fuzzyQuery(String str);//模糊查询 + public int saveEmp(Emp e);//添加员工信息 + public int deleteEmp(int empno);//删除指定编号的员工 + public int updateEmp(Emp emp);//修改员工职位、工资、津贴 + +} diff --git a/JDBC/src/project/EmpManage_JDBC/dao/impl/EmpDaoImpl.java b/JDBC/src/project/EmpManage_JDBC/dao/impl/EmpDaoImpl.java new file mode 100644 index 0000000..11d87ca --- /dev/null +++ b/JDBC/src/project/EmpManage_JDBC/dao/impl/EmpDaoImpl.java @@ -0,0 +1,229 @@ +package project.EmpManage_JDBC.dao.impl; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.junit.experimental.theories.FromDataPoints; + +import project.EmpManage_JDBC.bean.Dept; +import project.EmpManage_JDBC.bean.Emp; +import project.EmpManage_JDBC.dao.EmpDao; +import project.EmpManage_JDBC.util.DBUtil; + +public class EmpDaoImpl implements EmpDao{ + + @Override + public Emp findOneEmp(int empno) {//查询指定员工 + Connection conn = null; + PreparedStatement ps = null; + ResultSet rs = null; + Emp emp = null; + try{ + //1.创建连接对象 + conn = DBUtil.getConnection(); + String sql = "select * from emp where empno=?"; + //2.创建预编译对象 + ps = conn.prepareStatement(sql); + //3.赋值 + ps.setInt(1, empno); + //4.执行sql语句 + rs = ps.executeQuery(); + if(rs.next()){//5.遍历结果集,遍历一次,所以可以写if + int eno = rs.getInt("empno"); + String ename = rs.getString("ename"); + String job = rs.getString("job"); + int mgr = rs.getInt("mgr"); + Date hiredate = rs.getDate("hiredate"); + double sal = rs.getDouble("sal"); + double comm = rs.getDouble("comm"); + int deptno = rs.getInt("deptno"); + emp = new Emp(eno, ename, job, mgr, hiredate, sal, comm, deptno); + } + }catch(Exception e){ + e.printStackTrace(); + }finally { + DBUtil.close(conn, ps, rs); + } + return emp; + } + + @Override + public List findAllEmp() {//查询所有员工 + Connection conn = null; + PreparedStatement ps = null; + ResultSet rs = null; + List list = new ArrayList(); + try{ + conn = DBUtil.getConnection(); + String sql = "select * from emp"; + ps = conn.prepareStatement(sql); + rs = ps.executeQuery(); + while(rs.next()){ + int eno = rs.getInt("empno"); + String ename = rs.getString("ename"); + String job = rs.getString("job"); + int mgr = rs.getInt("mgr"); + Date hiredate = rs.getDate("hiredate"); + double sal = rs.getDouble("sal"); + double comm = rs.getDouble("comm"); + int deptno = rs.getInt("deptno"); + list.add(new Emp(eno, ename, job, mgr, hiredate, sal, comm, deptno)); + } + }catch(Exception e){ + e.printStackTrace(); + }finally { + DBUtil.close(conn, ps, rs); + } + return list; + } + + @Override + public List selEmpInfo() {//查询员工编号,姓名,工资,部门编号,部门名称 + Connection conn = null; + PreparedStatement ps = null; + ResultSet rs = null; + List list = new ArrayList(); + try { + conn = DBUtil.getConnection(); + String sql = "select ename,sal,e.deptno dno,dname " + + "from emp e,dept d where e.deptno=d.deptno"; + ps = conn.prepareStatement(sql); + rs = ps.executeQuery(); + while(rs.next()){ + String ename=rs.getString("ename"); + double sal = rs.getDouble("sal"); + int deptno = rs.getInt("dno"); + String dname = rs.getString("dname"); + Emp emp = new Emp(0, ename, null, 0, null, sal, 0, deptno); + Dept dept = new Dept(deptno, dname, null); + emp.setDept(dept); + list.add(emp); + } + } catch (Exception e) { + e.printStackTrace(); + }finally { + DBUtil.close(conn, ps, rs); + } + return list; + } + + @Override + public List selEmpByPage(int page, int pageSize) {//分页查询 + Connection conn = null; + PreparedStatement ps = null; + ResultSet rs = null; + List list = new ArrayList(); + try { + conn = DBUtil.getConnection(); + String sql = "select * from " + + "(select rownum rn, e.* from " + + "(select * from emp order by sal desc) e where rownum<=?)t " + + "where t.rn>=?"; + ps = conn.prepareStatement(sql); + ps.setInt(1, page*pageSize); + ps.setInt(2, (page-1)*pageSize+1); + rs = ps.executeQuery(); + while(rs.next()){ + int rownum = rs.getInt("rn"); + int eno = rs.getInt("empno"); + String ename = rs.getString("ename"); + String job = rs.getString("job"); + int mgr = rs.getInt("mgr"); + Date hiredate = rs.getDate("hiredate"); + double sal = rs.getDouble("sal"); + double comm = rs.getDouble("comm"); + int deptno = rs.getInt("deptno"); + list.add(new Emp(eno, ename, job, mgr, hiredate, sal, comm, deptno)); + } + } catch (Exception e) { + e.printStackTrace(); + }finally { + DBUtil.close(conn, ps, rs); + } + + + return list; + } + + @Override + public List fuzzyQuery(String str) {//模糊查询 + Connection conn = null; + PreparedStatement ps = null; + ResultSet rs = null; + List list = new ArrayList(); + try { + conn = DBUtil.getConnection(); + String sql = "select * from emp where ename like ?"; + ps = conn.prepareStatement(sql); + ps.setString(1, "%"+str+"%"); + rs = ps.executeQuery(); + while(rs.next()){ + int eno = rs.getInt("empno"); + String ename = rs.getString("ename"); + String job = rs.getString("job"); + int mgr = rs.getInt("mgr"); + Date hiredate = rs.getDate("hiredate"); + double sal = rs.getDouble("sal"); + double comm = rs.getDouble("comm"); + int deptno = rs.getInt("deptno"); + list.add(new Emp(eno, ename, job, mgr, hiredate, sal, comm, deptno)); + } + } catch (Exception e) { + e.printStackTrace(); + }finally { + DBUtil.close(conn, ps, rs); + } + return list; + } + + @Override + public int saveEmp(Emp emp) {//使用工具类DBUtil中的executeUpdate方法 + String sql = "insert into emp values(?,?,?,?,?,?,?,?)"; + //util.Date-->sql.Date + java.sql.Date date = new java.sql.Date(emp.getHiredate().getTime()); + Object[] obj = {emp.getEmpno(), + emp.getEname(), + emp.getJob(), + emp.getMgr(), + date, + emp.getSal(), + emp.getComm(), + emp.getDeptno()}; + return DBUtil.executeUpdate(sql, obj); + } + + @Override + public int deleteEmp(int empno) {//使用工具类DBUtil中的executeUpdate方法 + String sql = "delete from emp where empno=?"; + Object[] obj = {empno}; + return DBUtil.executeUpdate(sql, obj); + } + + @Override + public int updateEmp(Emp emp) {//这里使用的是常规方法进行更新,也可使用工具类DBUtil中的executeUpdate方法 + Connection conn = null; + PreparedStatement ps = null; + int rows = 0; + try { + conn = DBUtil.getConnection(); + String sql = "update emp set job=?,sal=?,comm=? where empno=?"; + ps = conn.prepareStatement(sql); + ps.setString(1, emp.getJob()); + ps.setDouble(2, emp.getSal()); + ps.setDouble(3, emp.getComm()); + ps.setInt(4, emp.getEmpno()); + rows = ps.executeUpdate(); + } catch (Exception e) { + e.printStackTrace(); + }finally { + DBUtil.close(conn, ps, null); + } + return rows; + } + + +} diff --git a/JDBC/src/project/EmpManage_JDBC/test/Test.java b/JDBC/src/project/EmpManage_JDBC/test/Test.java new file mode 100644 index 0000000..a5f09cd --- /dev/null +++ b/JDBC/src/project/EmpManage_JDBC/test/Test.java @@ -0,0 +1,179 @@ +package project.EmpManage_JDBC.test; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; + +import project.EmpManage_JDBC.bean.Emp; +import project.EmpManage_JDBC.dao.EmpDao; +import project.EmpManage_JDBC.dao.impl.EmpDaoImpl; + +public class Test { + + public static void main(String[] args) { + while(true){ + int choose = menu(); + switch (choose) { + case 1: + findOneEmp(); + break; + case 2: + findAllEmp(); + break; + case 3: + selEmpInfo(); + break; + case 4: + fuzzyQuery(); + break; + case 5: + selEmpByPage(); + break; + case 6: + saveEmp(); + break; + case 7: + deleteEmp(); + break; + case 8: + updateEmp(); + break; + case 9: + System.out.println("退出系统."); + return; + default: + System.out.println("没有找到你要执行的操作."); + break; + } + } + } + + public static int menu(){//菜单 + System.out.println("----------欢迎使用员工管理系统-------------"); + System.out.println("功能菜单: "); + System.out.println("\t1.查询指定编号的员工信息"); + System.out.println("\t2.查询所有员工信息"); + System.out.println("\t3.查询员工编号,姓名,工资,部门编号,部门名称"); + System.out.println("\t4.分页查询所有员工信息"); + System.out.println("\t5.模糊查询"); + System.out.println("\t6.添加员工信息"); + System.out.println("\t7.删除员工信息"); + System.out.println("\t8.修改员工信息"); + System.out.println("\t9.退出系统"); + System.out.print("请选择你要执行的操作:"); + return new Scanner(System.in).nextInt(); + } + + public static void findOneEmp(){//查询指定编号的员工 + //1.从控制台录入要查询的员工编号: + Scanner sc = new Scanner(System.in); + System.out.print("请输入要查询的员工编号:"); + int empno = sc.nextInt(); + //2.调用dao层方法: + EmpDao ed = new EmpDaoImpl(); + Emp emp = ed.findOneEmp(empno); + if(emp!=null){ + System.out.println(emp); + }else{ + System.out.println("你要查询的员工不存在!"); + } + } + + public static void findAllEmp(){//查询所有员工 + List list = new EmpDaoImpl().findAllEmp(); + System.out.println("员工信息如下:一共("+list.size()+")人"); + if(!list.isEmpty()){ + for(Emp e: list){ + System.out.println(e); + } + }else{ + System.out.println("无"); + } + } + + public static void selEmpInfo(){//查询员工编号,姓名,工资,部门编号,部门名称 + EmpDao ed = new EmpDaoImpl(); + for(Emp emp: ed.selEmpInfo()){ + System.out.println(emp); + } + } + + public static void selEmpByPage(){//分页查询 + Scanner sc = new Scanner(System.in); + System.out.print("请输入页数:"); + int page = sc.nextInt(); + EmpDao ed = new EmpDaoImpl(); + List list = ed.selEmpByPage(page, 5); + for(Emp emp: list){ + System.out.println(emp); + } + } + + public static void fuzzyQuery(){//模糊查询 + System.out.print("请输入要查询的员工姓名(支持模糊查询):"); + Scanner sc = new Scanner(System.in); + String str = sc.next(); + EmpDao ed = new EmpDaoImpl(); + List list = ed.fuzzyQuery(str); + for(Emp emp: list){ + System.out.println(emp); + } + } + + public static void saveEmp(){//添加员工信息 + Emp emp = new Emp(); + + Scanner sc = new Scanner(System.in); + System.out.print("员工编号: "); + emp.setEmpno(sc.nextInt()); + System.out.print("员工姓名: "); + emp.setEname(sc.next()); + System.out.print("员工职位: "); + emp.setJob(sc.next()); + System.out.print("员工的经理编号: "); + emp.setMgr(sc.nextInt()); + System.out.print("员工入职时间: "); + try {//String--->util.Date + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + emp.setHiredate(sdf.parse(sc.next())); + } catch (ParseException e) { + e.printStackTrace(); + } + System.out.print("员工工资: "); + emp.setSal(sc.nextDouble()); + System.out.print("员工奖金: "); + emp.setComm(sc.nextDouble()); + System.out.print("员工部门编号: "); + emp.setDeptno(sc.nextInt()); + + EmpDao ed = new EmpDaoImpl(); + int a = ed.saveEmp(emp); + System.out.println(a>0?"插入成功!":"插入失败!"); + } + + public static void deleteEmp(){//删除指定编号的员工 + System.out.print("员工编号: "); + int empno = new Scanner(System.in).nextInt(); + EmpDao ed = new EmpDaoImpl(); + int rows = ed.deleteEmp(empno); + System.out.println(rows>0?"删除成功!":"删除失败!"); + } + + public static void updateEmp(){//修改员工职位、工资、津贴 + EmpDao ed = new EmpDaoImpl(); + + Scanner sc = new Scanner(System.in); + System.out.print("员工编号: "); + Emp emp = ed.findOneEmp(sc.nextInt()); + System.out.println(emp); + System.out.print("员工职位: "); + emp.setJob(sc.next()); + System.out.print("员工工资: "); + emp.setSal(sc.nextDouble()); + System.out.print("员工奖金: "); + emp.setComm(sc.nextDouble()); + int a = ed.updateEmp(emp); + System.out.println(a>0?"更新成功!":"更新失败!"); + } + +} diff --git a/JDBC/src/project/EmpManage_JDBC/util/DBUtil.java b/JDBC/src/project/EmpManage_JDBC/util/DBUtil.java new file mode 100644 index 0000000..9676aec --- /dev/null +++ b/JDBC/src/project/EmpManage_JDBC/util/DBUtil.java @@ -0,0 +1,66 @@ +package project.EmpManage_JDBC.util; + +import java.sql.*; + +/* + * 实现JDBC的工具类 + * 定义方法,直接返回数据库的连接对象 + * 关闭所有资源 + */ +public class DBUtil { + //链接数据库的封装方法 + public static Connection getConnection(){ + Connection conn = null; + try { + //加载驱动 + Class.forName("oracle.jdbc.driver.OracleDriver"); + String url = "jdbc:oracle:thin:@localhost:1521:orcl"; + String user = "zicheng"; + String password = "qqq"; + //获取连接对象 + conn = DriverManager.getConnection(url, user, password); + System.out.println("使用DBUtil连接Oracle成功!"); + } catch (Exception e) { + e.printStackTrace(); + } + return conn; + } + + //增加、删除、修改 + public static int executeUpdate(String sql,Object[] obj){ + Connection conn = null; + PreparedStatement ps = null; + int rows = 0; + try { + conn = DBUtil.getConnection(); + ps = conn.prepareStatement(sql); + for(int i=0;i0 && days<3){ + price = this.getPerRent()*days; + }else if(days>=3 && days<7){ + price = this.getPerRent()*days*0.9; + }else if(days>=7 && days<30){ + price = this.getPerRent()*days*0.8; + }else if(days>=30 && days<150){ + price = this.getPerRent()*days*0.7; + }else{ + price = this.getPerRent()*days*0.6; + } + return price; + } + + @Override + public String toString() { + return "Bus [seat=" + seat + ", toString()=" + super.toString() + "]"; + } + + +} diff --git a/JDBC/src/project/carRent_JDBC/bean/Car.java b/JDBC/src/project/carRent_JDBC/bean/Car.java new file mode 100644 index 0000000..b2997c5 --- /dev/null +++ b/JDBC/src/project/carRent_JDBC/bean/Car.java @@ -0,0 +1,51 @@ +package project.carRent_JDBC.bean; + +public class Car extends Vehicle { + + //轿车型号 + private String type; + + public Car() {} + + public Car(String brand, String vehicleId, int perRent,String type) { + super(brand, vehicleId, perRent); + this.type = type; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + @Override + public double calRent(int days) { + // TODO Auto-generated method stub + double price = 0; + if(days>0 && days<=7){ + price = this.getPerRent()*days; + }else if(days>7 && days<=30){ + price = this.getPerRent()*days*0.9; + }else if(days>30 && days<=150){ + price = this.getPerRent()*days*0.8; + }else{ + price = this.getPerRent()*days*0.7; + } + return price; + } + + @Override + public String toString() { + return "Car [type=" + type + ", toString()=" + super.toString() + "]"; + } + + + + + + + + +} diff --git a/JDBC/src/project/carRent_JDBC/bean/Truck.java b/JDBC/src/project/carRent_JDBC/bean/Truck.java new file mode 100644 index 0000000..730865a --- /dev/null +++ b/JDBC/src/project/carRent_JDBC/bean/Truck.java @@ -0,0 +1,34 @@ +package project.carRent_JDBC.bean; + +public class Truck extends Vehicle { + + //吨位 + private int tonnage; + + public Truck() {} + + public Truck(String brand, String vehicleId, int perRent,int tonnage) { + super(brand, vehicleId, perRent); + this.tonnage = tonnage; + } + + public int getTonnage() { + return tonnage; + } + + public void setTonnage(int tonnage) { + this.tonnage = tonnage; + } + + @Override + public double calRent(int days) { + // TODO Auto-generated method stub + return tonnage*days*50; + } + + @Override + public String toString() { + return "Truck [tonnage=" + tonnage + ", toString()=" + super.toString() + "]"; + } + +} diff --git a/JDBC/src/project/carRent_JDBC/bean/Vehicle.java b/JDBC/src/project/carRent_JDBC/bean/Vehicle.java new file mode 100644 index 0000000..5ee8c7d --- /dev/null +++ b/JDBC/src/project/carRent_JDBC/bean/Vehicle.java @@ -0,0 +1,44 @@ +package project.carRent_JDBC.bean; + +public abstract class Vehicle { + //汽车品牌 + private String brand; + //车牌号 + private String vehicleId; + //日租金 + private int perRent; + + public Vehicle() {} + public Vehicle(String brand, String vehicleId, int perRent) { + super(); + this.brand = brand; + this.vehicleId = vehicleId; + this.perRent = perRent; + } + + public String getBrand() { + return brand; + } + public void setBrand(String brand) { + this.brand = brand; + } + public String getVehicleId() { + return vehicleId; + } + public void setVehicleId(String vehicleId) { + this.vehicleId = vehicleId; + } + public int getPerRent() { + return perRent; + } + public void setPerRent(int perRent) { + this.perRent = perRent; + } + + public abstract double calRent(int days); + @Override + public String toString() { + return "Vehicle [brand=" + brand + ", vehicleId=" + vehicleId + ", perRent=" + perRent + "]"; + } + +} diff --git a/JDBC/src/project/carRent_JDBC/dao/Operation.java b/JDBC/src/project/carRent_JDBC/dao/Operation.java new file mode 100644 index 0000000..444d94e --- /dev/null +++ b/JDBC/src/project/carRent_JDBC/dao/Operation.java @@ -0,0 +1,8 @@ +package project.carRent_JDBC.dao; + +import project.carRent_JDBC.bean.Vehicle; + +public interface Operation { + public Vehicle lease(String brand,String type,int seat,int tonnage); + public void choose(); +} diff --git a/JDBC/src/project/carRent_JDBC/dao/impl/OperationImpl.java b/JDBC/src/project/carRent_JDBC/dao/impl/OperationImpl.java new file mode 100644 index 0000000..23a7cf7 --- /dev/null +++ b/JDBC/src/project/carRent_JDBC/dao/impl/OperationImpl.java @@ -0,0 +1,155 @@ +package project.carRent_JDBC.dao.impl; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Scanner; + +import project.carRent_JDBC.bean.Bus; +import project.carRent_JDBC.bean.Car; +import project.carRent_JDBC.bean.Truck; +import project.carRent_JDBC.bean.Vehicle; +import project.carRent_JDBC.dao.Operation; +import project.carRent_JDBC.util.DBUtil; + +public class OperationImpl implements Operation{ + + + /** + * 选择租赁汽车的方法 + */ + public void choose() { + Scanner sc = new Scanner(System.in); + Vehicle v = null; + System.out.println("*****欢迎光临腾飞汽车租赁公司*****"); + System.out.println("1、轿车\t2、客车\t3、卡车"); + System.out.print("请选择你要租赁的汽车类型:"); + int vType = sc.nextInt(); + String brand = ""; + String type = ""; + int seat = 0; + int tonnage = 0; + if(vType==1) { + System.out.println("请选择你要租赁的轿车品牌:1、别克 2、宝马"); + int carBrand = sc.nextInt(); + if(carBrand==1) { + brand = "别克"; + System.out.println("请选择你要租赁的汽车类型:1、林荫大道 2、GL8"); + type = (sc.nextInt()==1)?"林荫大道":"GL8"; + }else if(carBrand==2) { + brand = "宝马"; + System.out.println("请选择你要租赁的汽车类型:1、X6 2、550i"); + type = (sc.nextInt()==1)?"X6":"550i"; + }else { + System.out.println("没有找到你要租赁的轿车品牌"); + } + }else if(vType==2) { + type = ""; + System.out.println("请选择你要租赁的汽车品牌:1、金龙 2、金杯"); + brand = (sc.nextInt()==1)?"金龙":"金杯"; + System.out.println("请选择你要租赁的汽车座位数:1、16座 2、34座"); + seat = (sc.nextInt()==1)?16:34; + }else if(vType==3) { + type = ""; + System.out.println("请选择你要租赁的汽车品牌:1、一汽解放 2、重庆红岩"); + brand = (sc.nextInt()==1)?"一汽解放":"重庆红岩"; + System.out.println("请选择你要租赁的汽车吨位:1、5吨 2、10吨"); + tonnage = (sc.nextInt()==1)?5:10; + }else { + System.out.println("没有找到你要租赁的汽车类型"); + } + v = this.lease(brand, type, seat, tonnage); + System.out.print("请输入你要租赁的天数:"); + int days = sc.nextInt(); + double money = v.calRent(days); + System.out.println("分配给您的车牌号是:"+v.getVehicleId()); + System.out.println("您需要支付的租金是:"+money+"元"); + System.out.println(v); + } + + /** + * 租赁汽车方法:得到一个租赁汽车的对象 + */ + public Vehicle lease(String brand,String type,int seat,int tonnage) { + Connection conn = null; + PreparedStatement ps1 = null; + PreparedStatement ps2 = null; + PreparedStatement ps3 = null; + ResultSet rs = null; + int rows1 = 0; + int rows2 = 0; + Vehicle v = null; + String sql1 = null; + String sql2 = null; + String sql3 = "insert into rented values (?,?,?,?,?,?)"; + if(type != null) { + sql1 = "select * from car where type = ?"; + sql2 = "delete from car where type = ?"; + }else if(seat != 0) { + sql1 = "select * from bus where seat = ?"; + sql2 = "delete from bus where seat = ?"; + }else if (tonnage != 0) { + sql1 = "select * from truck where tonnage = ?"; + sql2 = "delete from truck where tonnage = ?"; + } + try { + conn = DBUtil.getConnection(); + ps1 = conn.prepareStatement(sql1); + ps2 = conn.prepareStatement(sql2); + ps3 = conn.prepareStatement(sql3); + if(type != null) { + ps1.setString(1, type); + ps2.setString(1, type); + }else if(seat != 0) { + ps1.setInt(1, seat); + ps2.setInt(1, seat); + }else if (tonnage != 0) { + ps1.setInt(1, tonnage); + ps2.setInt(1, tonnage); + } + rs = ps1.executeQuery(); + + conn.setAutoCommit(false); + while (rs.next()) { + String vehicleId = rs.getString("vehicleId"); + int perRent = rs.getInt("perRent"); + + ps3.setString(1, brand); + ps3.setString(2, vehicleId); + ps3.setInt(3, perRent); + ps3.setString(4, type); + ps3.setInt(5, seat); + ps3.setInt(6, tonnage); + + if(type != null) { + v = new Car(brand, vehicleId, perRent, type); + ps2.executeUpdate(); + ps3.executeUpdate(); + }else if(seat != 0) { + v = new Bus(brand, vehicleId, perRent, seat); + ps2.executeUpdate(); + ps3.executeUpdate(); + }else if (tonnage != 0) { + v = new Truck(brand, vehicleId, perRent, tonnage); + ps2.executeUpdate(); + ps3.executeUpdate(); + } + } + conn.commit(); + + } catch (Exception e) { + try { + conn.rollback(); + } catch (SQLException e1) { + e1.printStackTrace(); + } + e.printStackTrace(); + }finally { + DBUtil.close(conn, ps1, ps2, ps3, rs); + } + return v; + } + +} \ No newline at end of file diff --git a/JDBC/src/project/carRent_JDBC/test/Test.java b/JDBC/src/project/carRent_JDBC/test/Test.java new file mode 100644 index 0000000..bb50281 --- /dev/null +++ b/JDBC/src/project/carRent_JDBC/test/Test.java @@ -0,0 +1,14 @@ +package project.carRent_JDBC.test; + +import project.carRent_JDBC.dao.Operation; +import project.carRent_JDBC.dao.impl.OperationImpl; + +public class Test { + + public static void main(String[] args) { + // TODO Auto-generated method stub + Operation op = new OperationImpl(); + op.choose(); + } + +} diff --git a/JDBC/src/project/carRent_JDBC/util/DBUtil.java b/JDBC/src/project/carRent_JDBC/util/DBUtil.java new file mode 100644 index 0000000..5080b3c --- /dev/null +++ b/JDBC/src/project/carRent_JDBC/util/DBUtil.java @@ -0,0 +1,72 @@ +package project.carRent_JDBC.util; + +import java.sql.*; + +/* + * 实现JDBC的工具类 + * 定义方法,直接返回数据库的连接对象 + * 关闭所有资源 + */ +public class DBUtil { + //链接数据库的封装方法 + public static Connection getConnection(){ + Connection conn = null; + try { + //加载驱动 + Class.forName("oracle.jdbc.driver.OracleDriver"); + String url = "jdbc:oracle:thin:@localhost:1521:orcl"; + String user = "zicheng"; + String password = "qqq"; + //获取连接对象 + conn = DriverManager.getConnection(url, user, password); + System.out.println("使用DBUtil连接Oracle成功!"); + } catch (Exception e) { + e.printStackTrace(); + } + return conn; + } + + //增加、删除、修改 + public static int executeUpdate(String sql,Object[] obj){ + Connection conn = null; + PreparedStatement ps = null; + int rows = 0; + try { + conn = DBUtil.getConnection(); + ps = conn.prepareStatement(sql); + for(int i=0;i