第三天多表查询查询语法:select 列名列表from 表名列表where.... 准备sql 创建部门表 CREATE TABLE dept( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(20));INSERT INTO dept (NAME) VALUES ('开发部'),('市场部'),('财务部'); 创建员工表 id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(10), gender CHAR(1), -- 性别 salary DOUBLE, -- 工资 join_date DATE, -- 入职日期 dept_id INT, FOREIGN KEY (dept_id) REFERENCES dept(id) -- 外键,关联部门表(部门表的主键));INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('孙悟空','男',7200,'2013-02-24',1);INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('猪八戒','男',3600,'2010-12-02',2);INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('唐僧','男',9000,'2008-08-08',2);INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('白骨精','女',5000,'2015-10-07',3);INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('蜘蛛精','女',4500,'2011-03-14',1); 笛卡尔积: 有两个集合A,B .取这两个集合的所有组成情况。 要完成多表查询,需要消除无用的数据
多表查询的分类: 内连接查询: 隐式内连接:使用where条件消除无用数据 SELECT * FROM emp,dept WHERE emp.dept_id = dept.id`; -- 查询员工表的名称,性别。部门表的名称SELECT emp.name,emp.gender,dept.name FROM emp,dept WHERE emp.dept_id= dept.id`; SELECT t1.name, -- 员工表的姓名 t1.gender,-- 员工表的性别 t2.name -- 部门表的名称FROM emp t1, dept t2WHERE t1.dept_id = t2.id`; 显式内连接: 外链接查询: 左外连接: 语法:select 字段列表 from 表1 left [outer] join 表2 on 条件; 查询的是左表所有数据以及其交集部分。 例子:-- 查询所有员工信息,如果员工有部门,则查询部门名称,没有部门,则不显示部门名称SELECT t1.*,t2.name FROM emp t1 LEFT JOIN dept t2 ON t1.dept_id= t2.id`;
右外连接:
子查询: 概念:查询中嵌套查询,称嵌套查询为子查询。-- 查询工资最高的员工信息-- 1 查询最高的工资是多少 9000SELECT MAX(salary) FROM emp; -- 2 查询员工信息,并且工资等于9000的SELECT * FROM emp WHERE emp.`salary = 9000; -- 一条sql就完成这个操作。子查询SELECT * FROM emp WHERE emp.salary` = (SELECT MAX(salary) FROM emp); 子查询不同情况
事务事务的基本介绍 概念: 操作: 开启事务: start transaction; 回滚:rollback; 提交:commit;
例子:CREATE TABLE account ( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(10), balance DOUBLE);-- 添加数据INSERT INTO account (NAME, balance) VALUES ('zhangsan', 1000), ('lisi', 1000);
SELECT * FROM account;UPDATE account SET balance = 1000;-- 张三给李四转账 500 元 -- 0. 开启事务START TRANSACTION;-- 1. 张三账户 -500 UPDATE account SET balance = balance - 500 WHERE NAME = 'zhangsan';-- 2. 李四账户 +500-- 出错了...UPDATE account SET balance = balance + 500 WHERE NAME = 'lisi'; -- 发现执行没有问题,提交事务COMMIT; -- 发现出问题了,回滚事务ROLLBACK; MySQL数据库中事务默认自动提交 事务提交的两种方式: 自动提交: mysql就是自动提交的 一条DML(增删改)语句会自动提交一次事务。
手动提交: Oracle 数据库默认是手动提交事务 需要先开启事务,再提交
修改事务的默认提交方式:
事务的四大特征: 事务的隔离级别(了解) 概念:多个事务之间隔离的,相互独立的。但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题。 存在问题: 隔离级别: 演示:set global transaction isolation level read uncommitted;start transaction;-- 转账操作update account set balance = balance - 500 where id = 1;update account set balance = balance + 500 where id = 2;
DCL SQL分类: 1. DDL:操作数据库和表 2. DML:增删改表中数据 3. DQL:查询表中数据 4. DCL:管理用户,授权 DBA:数据库管理员 DCL:管理用户,授权 管理用户 添加用户: 删除用户: 修改用户密码: UPDATE USER SET PASSWORD = PASSWORD('新密码') WHERE USER = '用户名';UPDATE USER SET PASSWORD = PASSWORD('abc') WHERE USER = 'lisi'; SET PASSWORD FOR '用户名'@'主机名' = PASSWORD('新密码');SET PASSWORD FOR 'root'@'localhost' = PASSWORD('123'); mysql中忘记了root用户的密码? cmd -- > net stop mysql 停止mysql服务 使用无验证方式启动mysql服务: mysqld --skip-grant-tables 打开新的cmd窗口,直接输入mysql命令,敲回车。就可以登录成功 use mysql; update user set password = password('你的新密码') where user = 'root'; 关闭两个窗口 打开任务管理器,手动结束mysqld.exe 的进程 启动mysql服务 使用新密码登录。
查询用户:-- 1. 切换到mysql数据库USE myql;-- 2. 查询user表SELECT * FROM USER;
权限管理: 查询权限:-- 查询权限SHOW GRANTS FOR '用户名'@'主机名';SHOW GRANTS FOR 'lisi'@'%'; 授予权限:-- 授予权限grant 权限列表 on 数据库名.表名 to '用户名'@'主机名';-- 给张三用户授予所有权限,在任意数据库任意表上 GRANT ALL ON . TO 'zhangsan'@'localhost'; 撤销权限:-- 撤销权限:revoke 权限列表 on 数据库名.表名 from '用户名'@'主机名';REVOKE UPDATE ON db3.account` FROM 'lisi'@'%';
第四天JDBC抽取JDBC工具类:JDBCUtils代码实现:public class JDBCUtils { private static String url; private static String user; private static String password; private static String driver; /** //读取资源文件,获取值。 try { //1. 创建Properties集合类。 Properties pro = new Properties(); //获取src路径下的文件的方式--->ClassLoader 类加载器 ClassLoader classLoader = JDBCUtils.class.getClassLoader(); URL res = classLoader.getResource("jdbc.properties"); String path = res.getPath(); System.out.println(path);///D:/IdeaProjects/itcast/out/production/day04_jdbc/jdbc.properties //2. 加载文件 // pro.load(new FileReader("D:\IdeaProjects\itcast\day04_jdbc\src\jdbc.properties")); pro.load(new FileReader(path)); //3. 获取数据,赋值 url = pro.getProperty("url"); user = pro.getProperty("user"); password = pro.getProperty("password"); driver = pro.getProperty("driver"); //4. 注册驱动 Class.forName(driver); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } }
/** 获取连接 @return 连接对象*/public static Connection getConnection() throws SQLException { return DriverManager.getConnection(url, user, password);}
/** 释放资源 @param stmt @param conn*/public static void close(Statement stmt,Connection conn){if( stmt != null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); }} if( conn != null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); }}}
/** 释放资源 @param stmt @param conn*/public static void close(ResultSet rs,Statement stmt, Connection conn){if( rs != null){ try { rs.close(); } catch (SQLException e) { e.printStackTrace(); }} if( stmt != null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); }} if( conn != null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); }}}
} JDBC控制事务:事务:一个包含多个步骤的业务操作。如果这个业务操作被事务管理,则这多个步骤要么同时成功,要么同时失败。 操作: 使用Connection对象来管理事务 代码:public class JDBCDemo10 { public static void main(String[] args) { Connection conn = null; PreparedStatement pstmt1 = null; PreparedStatement pstmt2 = null; try { //1.获取连接 conn = JDBCUtils.getConnection(); //开启事务 conn.setAutoCommit(false); //2.定义sql//2.1 张三 - 500String sql1 = "update account set balance = balance - ? where id = ?";//2.2 李四 + 500String sql2 = "update account set balance = balance + ? where id = ?";//3.获取执行sql对象pstmt1 = conn.prepareStatement(sql1);pstmt2 = conn.prepareStatement(sql2);//4. 设置参数pstmt1.setDouble(1,500);pstmt1.setInt(2,1); pstmt2.setDouble(1,500);pstmt2.setInt(2,2);//5.执行sqlpstmt1.executeUpdate();// 手动制造异常int i = 3/0; pstmt2.executeUpdate();//提交事务conn.commit(); } catch (Exception e) { //事务回滚 try { if(conn != null) { conn.rollback(); } } catch (SQLException e1) { e1.printStackTrace(); } e.printStackTrace();}finally { JDBCUtils.close(pstmt1,conn); JDBCUtils.close(pstmt2,null);} }} }
第五天数据库线程池代码:public class JDBCUtils { //1.定义成员变量 DataSourceprivate static DataSource ds ; static{ try { //1.加载配置文件 Properties pro = new Properties(); pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties")); //2.获取DataSource ds = DruidDataSourceFactory.createDataSource(pro); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); }} /** /** 释放资源*/public static void close(Statement stmt,Connection conn){ /* if(stmt != null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); }} if(conn != null){ try { conn.close();//归还连接 } catch (SQLException e) { e.printStackTrace(); }}*/
close(null,stmt,conn);}
public static void close(ResultSet rs , Statement stmt, Connection conn){ if(rs != null){ try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if(stmt != null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if(conn != null){ try { conn.close();//归还连接 } catch (SQLException e) { e.printStackTrace(); } } } /** public static DataSource getDataSource(){ return ds; } } Spring JDBC //1. 获取JDBCTemplate对象 private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource()); /** */ @Test public void test1(){ //2. 定义sql String sql = "update emp set salary = 10000 where id = 1001"; //3. 执行sql int count = template.update(sql); System.out.println(count);} /** 添加一条记录*/ @Test public void test2(){ String sql = "insert into emp(id,ename,dept_id) values(?,?,?)"; int count = template.update(sql, 1015, "郭靖", 10); System.out.println(count);
} /** /** 4.查询id为1001的记录,将其封装为Map集合 注意:这个方法查询的结果集长度只能是1*/@Testpublic void test4(){String sql = "select * from emp where id = ? or id = ?";Map<String, Object> map = template.queryForMap(sql, 1001,1002);System.out.println(map);//{id=1001, ename=孙悟空, job_id=4, mgr=1004, joindate=2000-12-17, salary=10000.00, bonus=null, dept_id=20}
} /** /** @Testpublic void test6(){ String sql = "select * from emp"; List<Emp> list = template.query(sql, new RowMapper<Emp>() { @Overridepublic Emp mapRow(ResultSet rs, int i) throws SQLException { Emp emp = new Emp(); int id = rs.getInt("id"); String ename = rs.getString("ename"); int job_id = rs.getInt("job_id"); int mgr = rs.getInt("mgr"); Date joindate = rs.getDate("joindate"); double salary = rs.getDouble("salary"); double bonus = rs.getDouble("bonus"); int dept_id = rs.getInt("dept_id"); emp.setId(id);emp.setEname(ename);emp.setJob_id(job_id);emp.setMgr(mgr);emp.setJoindate(joindate);emp.setSalary(salary);emp.setBonus(bonus);emp.setDept_id(dept_id); return emp; } });
for (Emp emp : list) { System.out.println(emp); } } /** */ @Test public void test6_2(){ String sql = "select * from emp"; List<Emp> list = template.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class)); for (Emp emp : list) { System.out.println(emp); } } /**
|