A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 林志博 初级黑马   /  2018-10-18 17:44  /  820 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 小石姐姐 于 2018-10-19 10:47 编辑

Day02-Day03重点
添加数据:insert into 表名(列名1,列名2,...列名n) values(值1,值2,...值n);
删除数据:delete from 表名 [where 条件] 删除空记录使用 is 不能使用 =
修改数据:update 表名 set 列名1 = 值1, 列名2 = 值2,... [where 条件];
基础查询:
多个字段的查询:select 字段名1,字段名2... from 表名;
去重:distinctselect distinct 列名 from 表名;
计算列:select 字段名1,字段名名2, 字段1+字段2 from 表明;
起别名:as也可以省略
条件查询
* > 、< 、<= 、>= 、= 、<>不等于
BETWEEN 条件1 AND 条件2 介于条件1和条件2之间

IN( 条件1,条件2,条件3) 释义:或者条件1或者条件2或者条件3
IS NULL 释义:空 查询为空的字段
and 或 && 并且
or 或 || 或者
not 或 ! 非
IS NOT NULL; 释义:非空
模糊查询
_:单个任意字符
SELECT * FROM student WHERE NAME LIKE '马%';
%:多个任意字符
SELECT * FROM student WHERE NAME LIKE '%德%';
排序查询
语法:order by 子句
格式:selecet 显示字段 from 表名 order by 排序字段 排序方式..
* 排序方式:
ASC:升序,默认的。
DESC:降序。


聚合函数
格式:SELECT 聚合函数( 列名) FROM 表名;
1. count(一般选择非空的列:主键) 计算个数
2. max:计算最大值
3. min:计算最小值
4. sum:计算和
5. avg:计算平均值
注意:聚合函数的计算,排除null值。
分组查询:
格式: select 显示的字段 from 表名 group by 分组的字段
格式:SELECT id,NAME, AVG(math),age FROM student GROUP BY sex;
注意:
where 分组前条件判断
group by 分组字段
having 分组后的
-- 按照性别分组。分别查询男、女同学的平均分,人数 要求:分数低于70分的人,不参与分组,分组之后。人数要大于2个人
SELECT sex,AVG(math) ,COUNT(id) 人数 FROM student WHERE math>70 GROUP BY sex HAVING 人数 >2
分页查询
1. 语法:limit(方言)开始的索引,每页查询的条数;
2. 公式:开始的索引 = (当前的页码 - 1) * 每页显示的条数
SELECT * FROM student LIMIT 0,3; -- 第1页
SELECT * FROM student LIMIT 3,3; -- 第2页
SELECT * FROM student LIMIT 6,3; -- 第3页
Day04-Day06重点
笛卡尔积现象
什么是笛卡尔积现象
什么是笛卡尔积:
-- 需求:查询所有的员工和所有的部门
select * from emp,dept;


左表的每条数据和右表的每条数据组合,这种效果称为笛卡尔乘积
如何清除笛卡尔积现象的影响
我们发现不是所有的数据组合都是有用的,只有 员工表.dept_id = 部门表.id 的数据才是有用的。所以需要通过条件过滤掉没用的数据。
-- 设置过滤条件 Column 'id' in where clause is ambiguous
select * from emp,dept where id=5;
select * from emp,dept where emp.`dept_id` = dept.`id`;
-- 查询员工和部门的名字
select emp.`name`, dept.`name` from emp,dept where emp.`dept_id` = dept.`id`;


内连接
隐式内连接
隐式内连接:看不到 JOIN 关键字,条件使用 WHERE 指定
SELECT 字段名 FROM 左表, 右表 WHERE 条件
select * from emp,dept where emp.`dept_id` = dept.`id`;


显式内连接
显示内连接:使用 INNER JOIN ... ON 语句, 可以省略 INNER
SELECT 字段名 FROM 左表 [INNER] JOIN 右表 ON 条件
查询唐僧的信息,显示员工 id,姓名,性别,工资和所在的部门名称,我们发现需要联合 2 张表同时才能查询出需要的数据,使用内连接


查询思路
确定查询哪些表:select * from emp inner join dept;

确定表连接条件,员工表.dept_id = 部门表.id 的数据才是有效的

确定查询条件,我们查询的是唐僧的信息,员工表.name='唐僧'
select * from emp e inner join dept d on e.`dept_id` = d.`id` where e.`name`='唐僧';

确定查询字段,查询唐僧的信息,显示员工 id,姓名,性别,工资和所在的部门名称
select e.`id`,e.`name`,e.`gender`,e.`salary`,d.`name` from emp e inner join dept don e.`dept_id` = d.`id` where e.`name`='唐僧';

我们发现写表名有点长,可以给表取别名,显示的字段名也使用别名
select e.`id` 编号,e.`name` 姓名,e.`gender` 性别,e.`salary` 工资,d.`name` 部门名字 fromemp e inner join dept d on e.`dept_id` = d.`id` where e.`name`='唐僧';


查询步骤:
总结内连接查询步骤:
1) 确定查询哪些表
2) 确定表连接的条件
3) 确定查询的条件
4) 确定查询的字段
左外链接
左外连接:使用 LEFT OUTER JOIN ... ON,OUTER 可以省略
格式:SELECT 字段名 FROM 左表 LEFT [OUTER] JOIN 右表 ON 条件
释义:
用左边表的记录去匹配右边表的记录,如果符合条件的则显示;否则,显示 NULL
可以理解为:在内连接的基础上保证左表的数据全部显示(左表是部门,右表员工)
-- 在部门表中增加一个销售部
insert into dept (name) values ('销售部');
select * from dept;
-- 使用内连接查询
select * from dept d inner join emp e on d.`id` = e.`dept_id`;
-- 使用左外连接查询
select * from dept d left join emp e on d.`id` = e.`dept_id`;


右外连接
右外连接:使用 RIGHT OUTER JOIN ... ON,OUTER 可以省略
格式:SELECT 字段名 FROM 左表 RIGHT [OUTER ]JOIN 右表 ON 条件
用右边表的记录去匹配左边表的记录,如果符合条件的则显示;否则,显示 NULL
可以理解为:在内连接的基础上保证右表的数据全部显示
-- 在员工表中增加一个员工

-- 在员工表中增加一个员工
insert into emp values (null, '沙僧','男',6666,'2013-12-05',null);
select * from emp;
-- 使用内连接查询
select * from dept inner join emp on dept.`id` = emp.`dept_id`;
-- 使用右外连接查询
select * from dept right join emp on dept.`id` = emp.`dept_id`;
子查询
什么是子查询
-- 需求:查询开发部中有哪些员工
select * from emp;
-- 通过两条语句查询
select id from dept where name='开发部' ;
select * from emp where dept_id = 1;
-- 使用子查询
select * from emp where dept_id = (select id from dept where name='市场部');


子查询的概念:
1) 一个查询的结果做为另一个查询的条件
2) 有查询的嵌套,内部的查询称为子查询
3) 子查询要使用括号
子查询结果的三种情况:
1) 子查询的结果是单行单列

2) 子查询的结果是多行单列

3) 子查询的结果是多行多列


子查询的结果是一个值的时候
子查询结果只要是单行单列,肯定在 WHERE 后面作为条件,父查询使用:比较运算符,如:> 、<、<>、=等.....
格式:SELECT 查询字段 FROM 表 WHERE 字段= (子查询)
案例:查询工资最高的员工是谁?
-- 1) 查询最高工资是多少
select max(salary) from emp;
-- 2) 根据最高工资到员工表查询到对应的员工信息
select * from emp where salary = (select max(salary) from emp);
查询工资小于平均工资的员工有哪些?
-- 1) 查询平均工资是多少
select avg(salary) from emp;
-- 2) 到员工表查询小于平均的员工信息
select * from emp where salary < (select avg(salary) from emp);
子查询结果是多行单列的时候
子查询结果是单例多行,结果集类似于一个数组,父查询使用 IN 运算符
格式:SELECT 查询字段 FROM 表 WHERE 字段 IN (子查询);
查询工资大于 5000 的员工,来自于哪些部门的名字
-- 先查询大于 5000 的员工所在的部门 id
select dept_id from emp where salary > 5000;

-- 错误 再查询在这些部门 id 中部门的名字
select name from dept where id = (select dept_id from emp where salary > 5000); -- Subquery returns more than 1 row 翻译过来:子查询子查询返回超过1行
-- 正确
select name from dept where id in (select dept_id from emp where salary > 5000);

查询开发部与财务部所有的员工信息
-- 先查询开发部与财务部的 id
select id from dept where name in('开发部','财务部');

-- 再查询在这些部门 id 中有哪些员工
select * from emp where dept_id in (select id from dept where name in('开发部','财务部'));


子查询的结果是多行多列
子查询结果只要是多列,肯定在 FROM 后面作为表
格式:SELECT 查询字段 FROM (子查询/虚表) 表别名 WHERE 条件;
子查询作为表需要取别名,否则这张表没有名称则无法访问表中的字段
查询出 2011 年以后入职的员工信息,包括部门名称
-- 在员工表中查询 2011-1-1 以后入职的员工
select * from emp where join_date >='2011-1-1';

-- 查询所有的部门信息,与上面的虚拟表中的信息组合,找出所有部门 id 等于的 dept_id
select * from dept d, (select * from emp where join_date >='2011-1-1') e whered.`id`= e.dept_id ;

-- 也可以使用表连接:
select * from emp inner join dept on emp.`dept_id` = dept.`id` wherejoin_date >='2011-1-1';
select * from emp inner join dept on emp.`dept_id` = dept.`id` andjoin_date >='2011-1-1';
SELECT * FROM emp,dept WHERE emp.`dept_id` = dept.`id` AND join_date >='2011-1-1'; -- 习惯使用这个


子查询小结
子查询结果只要是单列,则在 WHERE 后面作为条件
子查询结果只要是多列,则在 FROM 后面作为表进行二次查询
Day05
•        1.java.sql.DriverManager(类)
作用1:注册驱动(不用),推荐使用:Class.forName(“com.mysql.jdbc.Driver”)
作用2:获取Connection  con = getConnection(url,user,password);
•        2.java.sql.Connection(接口)
作用1:获取执行sql语句的对象
              Statement stmt = con.createStatement();
              PreparedStatement pstmt = con.prepareStatement(sql);
作用2:事务处理
•        3.java.sql.Statement(接口)
作用1: 执行DML: insert into , update ,delete
                    int  row =  stmt.executeUpdate(dml);
作用2: 执行DQL: select
                    ResultSet  rs = stmt.executeQuery(dql);
•        4.java.sql.PreparedStatment(接口)
作用1: 执行DML: insert into , update ,delete
                    int  row =  pstmt.executeUpdate();
作用2: 执行DQL: select
                    ResultSet  rs = pstmt.executeQuery(dql);
经典练习题
案例:将多条记录封装成集合 List<Student>,集合中每个元素是一个 JavaBean 实体类
[Java] 纯文本查看 复制代码
package com.itheima.com.demo05;
import com.itheima.com.demo02.JDBCUtils;
import demo04.Student;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
public class JDBCStudent1 {
public static void main(String[] args) {
Connection conn =null;
Statement stmt = null;
ResultSet res = null;
List<Student> students = new ArrayList<>();
try {
conn = JDBCUtils.Myconnection();
stmt = conn.createStatement();
//todo 条件判断的时候使用通配符进行占位,后面使用PreparedStatement对象进行执行sql语句
String sql = "SELECT * FROM student";
// todo Connection下面的prepareStatement方法指定预编译的SQL 语句,传入使用通配符来创建的字符串(sql指令)
PreparedStatement ps = conn.prepareStatement(sql);//获取执行sql数据库的对象
res = ps.executeQuery();//执行查询数据库
while (res.next()){
//每次循环,创建一个学生对象
Student student = new Student();
student.setId(res.getInt("id"));
student.setName(res.getString("name"));
student.setAge(res.getInt("age"));
student.setSex(res.getString("sex"));
student.setAddress(res.getString("address"));
student.setMath(res.getDouble("math"));
student.setEnglish(res.getDouble("english"));
students.add(student);//每循环一次,装一个学生对象到集合中
}
} catch (Exception e) {
e.printStackTrace();
}
JDBCUtils.close(res,stmt,conn);
for (Student student : students) {
System.out.println(student);
}

}
}

经典练习题
练习 PreparedStatement 执行 DML 操作

private static void update() {
Connection conn = null;
PreparedStatement ps =null;
try {
conn = JDBCUtils.Myconnection();
String sql = "UPDATE student set name = ? WHERE id = ?";
ps = conn.prepareStatement(sql);
ps.setString(1,"柳岩");
ps.setInt(2,20);
int count = ps.executeUpdate();
System.out.println("修改成功,修改了"+count+"条记录");
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtils.close(conn,ps);
}
}

private static void insert() {
Connection conn = null;
PreparedStatement ps =null;
try {
conn = JDBCUtils.Myconnection();
String sql = "INSERT into student VALUES (?,?,?,?,?,?,?)";
ps = conn.prepareStatement(sql);
ps.setInt(1,8);
ps.setString(2,"范冰冰");
ps.setInt(3,19);
ps.setString(4,"女");
ps.setString(5,"石家庄");
ps.setDouble(6,77);
ps.setDouble(7,88);
int count = ps.executeUpdate();
System.out.println("添加成功,一共添加了"+count+"条记录");
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtils.close(conn,ps);
}
}

}
package com.itheima.com.demo06;
import com.itheima.com.demo02.JDBCUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLOutput;
public class JDBCCaozuo {
public static void main(String[] args) {
insert();//添加数据
// update(); //修改数据
// deleat(); //删除数据
}

private static void deleat() {
Connection conn = null;
PreparedStatement ps =null;
try {
conn = JDBCUtils.Myconnection();
String sql = "DELETE FROM student WHERE id =?";
ps = conn.prepareStatement(sql);
ps.setInt(1,8);
int count = ps.executeUpdate();
System.out.println("删除成功,删除了"+count+"条记录");
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtils.close(conn,ps);
}

}

Day06数据库链接池
为什么要使用数据库连接池?
以前操作的弊端:每次操作数据库都要获取链接对象,操作完成后,关闭资源,每操作一次都要获取链接,关闭链接....这样消耗系统资源,造成资源浪费
数据库链接池释义:是一个容器(集合),存储和管理Connection对象(数据库链接)的容器.
好处是:当系统初始化后,容器被创建,容器中会申请一些链接对象,当用户来访问数据库时,从容器中获取链接对象,当用户访问完容器后,会将链接对象归还给连接池
总结优点:
1.不用每次都创建链接对象,可以从数据库连接池来获取
2.在没有数据库连接池时,使用完Connection以后,释放Connection(销毁)如果在数据库连接池里面去Connecion使用,使用完以后,归还给数据库连接池.
实现数据库连接池
3. 实现:
1. 标准接口:DataSource在 javax.sql包下的类
1. 方法:
* 获取连接:getConnection()
* 归还连接:Connection.close()。如果连接对象Connection是从连接池中获取的,那么调用Connection.close()方法,则不会再关闭连接了。而是归还连接

2. 一般我们不去实现它,由数据库厂商来实现
1. C3P0:数据库连接池技术
2. Druid:数据库连接池实现技术,由阿里巴巴提供的
经典练习题
使用: Spring框架对JDBC的简单封装。提供了一个JDBCTemplate对象简化JDBC的开发

Spring框架对JDBC的简单封装。提供了一个JDBCTemplate对象简化JDBC的开发
* 步骤:
1. 导入jar包
2. 创建JdbcTemplate对象。依赖于数据源DataSource
* JdbcTemplate template = new JdbcTemplate(ds);

3. 调用JdbcTemplate的方法来完成CRUD的操作
* update():执行DML语句。增、删、改语句
* queryForMap():查询结果将结果集封装为map集合,将列名作为key,将值作为value 将这条记录封装为一个map集合
* 注意:这个方法查询的结果集长度只能是1
* queryForList():查询结果将结果集封装为list集合
* 注意:将每一条记录封装为一个Map集合,再将Map集合装载到List集合中
* query():查询结果,将结果封装为JavaBean对象
* query的参数:RowMapper
* 一般我们使用BeanPropertyRowMapper实现类。可以完成数据到JavaBean的自动封装
* new BeanPropertyRowMapper<类型>(类型.class)
* queryForObject:查询结果,将结果封装为对象
* 一般用于聚合函数的查询
package com.itheima.demo05SpringJDBC;
import com.itheima.demo03Utils.JDBCUtils;
import org.junit.Test;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
public class TestJdbcTemplate {
@Test
public void slect04() {

//最简单
[Java] 纯文本查看 复制代码
JdbcTemplate template = new JdbcTemplate(JDBCUtils.getdataSource());
String sql = "SELECT * FROM emp ";
List<emp> list = template.query(sql, new BeanPropertyRowMapper<emp>(emp.class));
for (emp emp : list) {
System.out.println(emp);
//TypeMismatchException 注意这个异常,是数据库和定义类中的数据类型不一样引起的,null是引用数据类型
}
}


@Test
public void select03() {
[Java] 纯文本查看 复制代码
// * query():查询结果,将结果封装为JavaBean对象
JdbcTemplate template = new JdbcTemplate(JDBCUtils.getdataSource());
String sql = "SELECT * FROM emp ";
List<emp> query = template.query(sql, new RowMapper<emp>() {
@Override
public emp mapRow(ResultSet res, int i) throws SQLException {
emp e = new emp();
int id = res.getInt("id");
String uname = res.getString("uname");
double money = res.getDouble("money");
e.setId(id);
e.setUname(uname);
e.setMoney(money);
return e;
}
});
for (emp emp : query) {
System.out.println(emp);
}

}

@Test
[Java] 纯文本查看 复制代码
public void select02() {
//* queryForList():查询结果将结果集封装为list集合
//* 注意:将每一条记录封装为一个Map集合,再将Map集合装载到List集合中
JdbcTemplate template = new JdbcTemplate(JDBCUtils.getdataSource());
String sql = "SELECT * FROM emp WHERE id=? or id =?";
List<Map<String, Object>> maps = template.queryForList(sql, 2, 3);
for (Map<String, Object> map : maps) {
System.out.println(map);
}
}


@Test
[Java] 纯文本查看 复制代码
public void select01() {
// * queryForMap():查询结果将结果集封装为map集合,将列名作为key,将值作为value 将这条记录封装为一个map集合
//todo 注意:这个方法查询的结果集长度只能是1
JdbcTemplate template = new JdbcTemplate(JDBCUtils.getdataSource());
String sql = "SELECT * FROM emp WHERE id=?";
Map<String, Object> map = template.queryForMap(sql, 3);
System.out.println(map);//{id=3, uname=迪丽热巴, money=9000}
}

@Test
[Java] 纯文本查看 复制代码
public void delete() {
JdbcTemplate template = new JdbcTemplate(JDBCUtils.getdataSource());
//delete from 表名 [where 条件] 删除空记录使用 is 不能使用 =
String sql = "delete FROM emp WHERE id =?";//sql语句条件判断使用占位符
int update = template.update(sql, 1);
System.out.println(update);
}


@Test
[Java] 纯文本查看 复制代码
public void insert01() {
JdbcTemplate template = new JdbcTemplate(JDBCUtils.getdataSource());
String sql = "INSERT into emp VALUES (NULL ,'欧阳修',1099)";
int update = template.update(sql);
System.out.println(update);
}


@Test
[Java] 纯文本查看 复制代码
public void update01() {
//创建JdbcTemplate对象。依赖于数据源DataSource数据库连接池
JdbcTemplate template = new JdbcTemplate(JDBCUtils.getdataSource());
System.out.println(template);//org.springframework.jdbc.core.JdbcTemplate@4973813a
String sql = "UPDATE emp set UNAME ='赵敏' WHERE id = 1";
int update = template.update(sql);
System.out.println(update);//1
}
}

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马