JDBC总结

JDBC(Java Database Connectivity)

一、JDBC简介

+++

1. JDBC是什么?
  1. JDBC是JAVA语言连接数据库的一套工具API【应用程序编程接口】.

  2. JDBC主要由JDK的java.sql包和javax.sql.包提供核心API接口。

2. 三方的责任划分?
  1. JAVA官方
    JAVA官方制定如何连接数据库的标准
    
  2. 数据库厂商
    数据库厂商来实现标准,即提供“驱动”;真正让JAVA语言真正连接数据库的代码
    
  3. 开发人员(我们)
    开发人员学习标准使用实现
    
  4. 代码
    //1.标准:JDK官方提供 java.sql包
    public interface Connection{}
    //2.实现:MySQL厂商提供
    public class MySqlConnection implements Connection{}
    //3.我们:看标准 用实现
    
  5. 标准、实现和使用:
    1. 因为有实现,所以我们不用自己实现JAVA语言连接每一个我们要用到的数据库;因为有标准,所以我们不用查看每一个具体实现的差异;我们只是:【学标准,用实现】

    2. 但凡是需要JAVA语言连接数据库的地方,都需要“驱动”,也就是jar包 mysql.jar

二、JDBC的核心API?

+++

JDBC核心的API主要来自java.sql包和javax.sql包。

1. java.sql.Driver接口
  • 作用
    1. 驱动,真正创建连接的API。
    2. 每一个驱动包都提供了一个获得连接的真正实现类。
  • 核心方法

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vkz8OucS-1655820918650)(JDBC_new.assets/image-20220618164826746.png)]

2. java.sql.DriverManager
  • 作用
    1. 管理驱动

    2. 对外获得链接

  • 核心方法

在这里插入图片描述

3. java.sql.Connection接口
  • 作用
    1. 创建执行SQL的Statement执行器
    2. 管理事务
    3. 其他操作
  • 核心方法

在这里插入图片描述
在这里插入图片描述

4. java.sql.Statement接口
  • 作用
    1. 执行SQL语句
    2. 获得或者设置当前执行器对象的特性
  • 核心方法

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cc6ZfCb9-1655820918656)(JDBC_new.assets/image-20220618173915234.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rpzIUxSy-1655820918656)(JDBC_new.assets/image-20220618174023861.png)]

5. java.sql.ResultSet接口
  • 作用
    1. 存放数据库查询的返回值
    2. 提供了可滚动和可更新的方法
  • 核心方法

    ##### [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zXqP5MJn-1655820918657)(JDBC_new.assets/image-20220618174551906.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JDNbhlLu-1655820918657)(JDBC_new.assets/image-20220618174625312.png)]
    在这里插入图片描述

三、JDBC的基本流程?

+++

1. 基本步骤
1. 加载驱动【注册造桥的人】
2. 获得与数据库的链接【造桥】
3. 创建执行SQL语句的Statement对象【造车】
4. 执行SQL语句,需要返回结果的话返回结果【运送资源】
5. 处理结果【返回值】
6. 关闭资源【桶销毁、车报废、桥拆除】
2. 代码流程
import java.sql.*; 
/*
java.sql包中包含:DriverManager Connection Statement ResultSet
等核心接口
*/

public class HelloJDBC{
	public static void main(String args[])throws Exception{
		//1.注册驱动 com.mysql.jdbc.Driver
		Class.forName("com.mysql.cj.jdbc.Driver");
		//2.获得连接 et2110:代表database的名字
		//jdbc:mysql://localhost:3309/et2110
		String url="jdbc:mysql://127.0.0.1:3309/et2110?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true";
		String user="root";
		String pwd="etoak";
		Connection con = 					           DriverManager.getConnection(url,user,pwd);
		//3.创建执行SQL的Statement执行器
		Statement sta = con.createStatement();
		//4.执行SQL返回结果
		ResultSet rs = sta.executeQuery("select * from student");
		//5.处理结果
		while(rs.next()){
			int id = rs.getInt("id");
			String name = rs.getString("name");
			int age = rs.getInt("age");
			String phone = rs.getString("phone");
			String email = rs.getString("email");
			System.out.println(id+"\t"+name+"\t"+age+"\t"+
			phone+"\t"+email);
		}
		//6.关闭资源
		rs.close();sta.close();con.close();
	}
}

四、JDBC基本流程中的每一个步骤的细节?

+++

1. 加载驱动的底层?
  1. Class.forName(“com.mysql.cj.jdbc.Driver”)

    Class是一个用来描述类的类,其中forName()方法用来加载制定名字的类的。所以以上Class.forName(“”)加载mysql的驱动类。

  2. com.mysql.cj.jdbc.Driver类中有一个静态代码块。当类加载时静态代码块执行。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rm4trxA0-1655820918658)(JDBC_new.assets/image-20220620145101394.png)]

  3. DriverManager中的registerDriver方法中,把该驱动对象存放到内部(DriverManager)的集合中

image-20220618172400638

2. DriverManager 获得连接的方式?
  1. 三个参数获的连接 getConnection(url,user,pwd)
  2. 两个参数的获得连接:getConnection(url,Properties info)
3. Statement执行器中执行SQL语句的方法介绍?

Statement代表执行SQL语句的执行器,我们习惯叫运送SQL的车,其中有几个主要的执行方法需要重点掌握.

  1. execute方法

    结论:
    1.execute是万能方法,可以执行任意的SQL语句。
    2.execute方法返回值是以是否返回ResultSet为判断标准的。
    select --》ResultSet —>true
    show table—>ResultSet—>true
    insert update delete—>没有ResultSet–>false

  2. executeUpdate方法

    结论:

    1. 专门负责执行insert/update/delete语句,返回对数据库影响的行数
    2. 不能执行select
  3. executeQuery方法

    结论:

    ​ 1.专门执行返回ResultSet的语句

  4. executeBatch方法
    1. 批处理

    JDBC中每一条SQL都是靠着以上方法执行的,选择合适的方法执行合适的SQL至关重要

4. ResultSet介绍?
  1. ResultSet表示执行SQL查询语句返回的结果。有一个指向当前行的光标,最开始,光标在第一行之前,next方法将光标向下移动一行,因为该方法在没有下一行时返回false,所以可以在while循环中迭代输出。

  2. ResultSet中的数据,即可以通过列名字,也可以通过列的索引下标,从1开始访问。

5. 预编译的执行器PreparedStatement使用?
  • 预编译的Statement,即PreparedStatement是支持?占位符。

  • 预编译的Statement,当创建Statement对象时,需要立即传入SQL语句。立刻把SQL发送到数据库编译存储。等到执行之前只需要替换?参数。

  • PreparedStatement在执行时不需要传递SQL语句。

6. PreparedStatement和普通的Statement的比较?
  1. Statement一般用来执行静态SQL(没有参数,不会改变)。不支持?占位符,如果有参数拼接。

  2. PreparedStatement预编译的Statement,支持?占位符,而且效率和安全性要比普通的Statement高。[可以避免SQL注入]

  3. 我们推荐使用PreparedStatement,但是有些情况必须使用参数拼接:

    1. select * from ? :表名字不能使用?
    2. select * from xx where name like ‘?’:引号中不能使用?
    3. select * from xxxs group by xx order by ?:order by 后边不能使用?

    MyBatis中#和$的区别就是这里的PreparedStatement和Statement的区别,还会回来。

7. 可滚动的结果集
  1. 可滚动?

    1. 默认ResultSet只能从第一行到最后一行,遍历一次【MySQL8驱动默认不可滚动】
  2. 可滚动: 可以通过设置可滚动属性,多次遍历结果集

2. 滚动方法
1.next +getxxx

2.滚动方法:
absolute(int row) :绝对定位到指定行
beforeFirst():把光标移动到第一行之前
afterLast():把光标移动到最后一行之后
first:把光标移动的第一行
last()previous():向上 向前
3. 代码演示
public static void query(String name)throws Exception{
		Connection con = getConnection();
		String sql="select id,name as sname,age sage,birth,email from student ";
		Statement pst = con.createStatement(
			ResultSet.TYPE_SCROLL_INSENSITIVE,
			ResultSet.CONCUR_UPDATABLE);

		ResultSet rs = pst.executeQuery(sql);
		//Thread.sleep(10000)
		while(rs.next()){
			System.out.println(rs.getInt("id")+"\t"
			+rs.getString("sname")+"\t"+rs.getInt(3)+"\t"+rs.getDate(4)+"\t"+rs.getString(5));

		}
		System.out.println("=====================");
		while(rs.previous()){
			System.out.println(rs.getInt("id")+"\t"
					+rs.getString("sname")+"\t"+rs.getInt(3)+"\t"+rs.getDate(4)+"\t"+rs.getString(5));
		}
		rs.absolute(2);
		System.out.println("=====================");
				while(rs.previous()){
					System.out.println(rs.getInt("id")+"\t"
							+rs.getString("sname")+"\t"+rs.getInt(3)+"\t"+rs.getDate(4)+"\t"+rs.getString(5));
		}
		rs.close();
		pst.close();
		con.close();
	}
4. 应用
  • 假分页:逻辑分页 全部都查询出来 按需显示数据

  • 真分页:物理分页 使用关键字 limit oracle rownum 按需提取数据

    MyBatis默认分页就使用了可滚动的结果集。

8. 加载资源?
  • Student.class.getResourceAsStream(""):从包内开始寻找资源
  • Student.class.getClassLoader().getResourceAsStream(""):从包外开始寻找。

    作业:

    1.使用JDBC程序在ET2203数据库中新建一张表 school

    school(

    id int primary key , name:学校名字,phone联系电话 varchar(11),

    proid int ,cityid int,areaid int,info varchar(100)详细地址

    )

    2.JDBC往表中添加10条测试数据

五、使用JDBC添加数据时如何获得新添加到数据库中的主键?

+++

0. 为什么要返回主键?
  1. 数据库中带有存放大对象(电影、图片、音频)字段类型的。lob类型(largeObject),其中在mysql中,二进制的大对象叫 blob, 文本类型的大对象 text.
  2. 大对象的类型数据是无法通过 命令行客户端工具(小黑板)添加的,如果遇到大对象类型的字段,一般都是通过程序来添加或者查询(IO)
  3. 在实际开发中,一般不会把文件、图片直接存放到数据库中,而是把文件直接保存到服务器上指定目录中。然后把图片的保存地址(/pics/xxx.jpg)存放到数据库中
  4. 案例

#### [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BY3rds5w-1655820918659)(JDBC_new.assets/image-20220419114308994.png)]

1. 数字类型的可以自动增长的主键?
  1. 采用JDBC自带的开关 pst.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS)
    Connection con = getConnection();
    		String insert="insert into student(name,age,birth,email)values(?,?,?,?)";
    		PreparedStatement pst = con.prepareStatement(insert,Statement.RETURN_GENERATED_KEYS);
    		pst.setString(1,"zhaoliu");
    		pst.setInt(2,456);
    		java.util.Date d =  new java.util.Date();
    
    		pst.setDate(3,new java.sql.Date(d.getTime()));
    
    		pst.setString(4,"zhaoliu@qq.com");
    
    		int count = pst.executeUpdate();
    		if(count>0){
    			ResultSet keys = pst.getGeneratedKeys();
    			while(keys.next()){
    				System.out.println(keys.getInt(1));
    			}
    		}
    

    useGeneratedKey=true

  2. 同一个连接的前提下:采用查询的方式
    	public static void testNumberKey1()throws Exception{
    			Connection con = getConnection();
    			String insert="insert into student(name,age,birth,email)values(?,?,?,?)";
    			PreparedStatement pst = con.prepareStatement(insert);
    			pst.setString(1,"zhaoliu");
    			pst.setInt(2,456);
    			java.util.Date d =  new java.util.Date();
    
    			pst.setDate(3,new java.sql.Date(d.getTime()));
    
    			pst.setString(4,"zhaoliu@qq.com");
    
    			int count = pst.executeUpdate();
    			if(count>0){
    				pst = con.prepareStatement("select last_insert_id()");
    				ResultSet keys = pst.executeQuery();
    				while(keys.next()){
    					System.out.println(keys.getInt(1));
    				}
    			}
    
    
    	}
    

    ​ select last_insert_id()

    mybatis的自动增长的主键返回方式采用JDBC的方法。

2. 字符串类不可自动增长的主键?
  • 先查询字符串生成主键,然后再添加。
    public static void testStringKey()throws Exception{
    		//~~~~~~~~~~~~~~~~
    			Connection con = getConnection();
    			PreparedStatement pst = con.
    			prepareStatement("select replace(uuid(),'-','') as id");
    			ResultSet rs = pst.executeQuery();
    			rs.next();
    			String key = rs.getString("id");
      String key1 = UUID.randomUUID().toString().replaceAll('-','');
    		//```````````````````以上代码 首先查询字符串作为主键
    		
    			String insert="insert into t1(id,name)values(?,?)";
    
    			pst = con.prepareStatement(insert);
    			pst.setString(1,key);
    			pst.setString(2,"etoak");
    
    
    			int count = pst.executeUpdate();
    			System.out.println(key);
    
    		}
    

七、元数据接口(Metadata)

+++

0. 元数据?

​ 元数据就是关于“数据”的数据。如:数据库是存放数据的,关于数据库本身的数据就叫元数据,结果集是用来存放从数据库中查询的数据的,关于结果集中列的信息的数据就叫元数据

1. DatabaseMetaData:数据库的元数据
2. ResultSetMetaData:结果集的元数据 rs

exec:把et2203数据库中所有表和内容 都打印出来。

步骤:

1. 查询表名字
2. 组装select * from xxx
3. 把内容写出到表格中。
JAVA处理Excel:apache-poi组件
POI中提供了核心的API
  Workbook ==================> 工作簿===》整个excel文档
  HSSFWorkbook: 处理xx.xls文档
  XSSFWorkbook:处理*.xlsx的文档 数据量少 <1W
  SXSSFWorkbook: 处理*.xlsx文档 数量可以达到104万条
  
  Sheet =====================>页 
  Row========================>行
  Cell=======================>单元格
写:
1.内存中创建 Workbook对象
2.再workbook对象中创建sheet
3.给sheet添加row
4.给row添加cell
5.写出到文件

八、JDBC中的事务控制

+++

1. 事务的基本概念?
  • 事务的概念?多条SQL 一个单元
  • 事务的特征?A:原子性 C:一致性 I:隔离性 D:持久性
  • 事务相互影响可能出现的问题?脏读、不可重复读、幻读
  • 为了解决问题设置的隔离级别?读未提交、读已提交、可重复读、串行化
2. 事务的应用场景?
  • 添加学生携带图片

  • 清空购物车

    购物车—》结账—》订单 1.insert into orders 2.insert into orderitem 3.update 库存 4.生成日志 5.清空购物车 6.通知卖家 7.物流。。

  • 入职—》insert into Emp系统 、delete from emp系统

    emp : flag 0 1

    emp insert delete emp1 insert 2

    查看今年有哪些人再公司离职?

  • 转账

    1.update -100 2. update +100

  • 其他各种需要多条对数据库修改的语句同时执行的场景。

3. JDBC事务控制的方式?
  • jdbc默认的提交模式是自动提交

  • Connection.setAutoCommit(false)//禁用自动提交

    sql1 sql2 sqln

  • Connection.commit()//提交

  • Connection.rollback()//回滚

MyBatis和Spring都用JDBC的方式控制事务!!!

九、数据源(DataSource)?

+++

1. 数据源接口介绍?
  • DataSource接口是javax.sql包中提供的获得连接的工厂,是DriverManager的替代者。

  • DataSource是JDK推荐我们使用的获得连接的首选方式。

2. 数据源的实现方式:数据库连接池?
 		1. 标准实现:参考标准版 DriverManager.getConnection()

	2. 连接池实现:参考练接池版
	3. 连接池版进阶:使用动态代理,处理close方法
3. 数据库连接池的实现原理? 能过够表达出来
  1. 当服务器启动时初始化一些 连接 放在连接池中,等待客户端请求连接。

  2. 当客户端请求连接时,首先判断连接池中是否有可用连接,如果有则返回;如果没有,则判断当前连接数,是否超过了最大可用连接数,如果没有超过则创建新的连接返回;如果超过了,则等待或者抛出无可用连接的异常。

  3. 当客户端使用完连接时,再次放回到连接池中,从而实现连接的重用。

  4. 连接池方式实现数据源最大特点是实现了连接的重用。

4. 数据库连接池的模仿
5. 常用连接池组件?

​ commons-dbcp/c3p0/druid等 都是第三方提供的采用了连接池方式的数据源接口的具体实现类库。

6. 三者的关系?
  • javax.sql.DataSource:JDK官方提供的获得连接标准
  • 数据库连接池:使用官方提供的数据源的方案。
  • dbcp/c3p0/druid/我们自己写的类库 是采用连接池方案的标准的实现产品。
7. 通过手动实现数据源来模仿原理?
  1. 基本版本DriverManager.getConn…
  2. 连接池的版本
  3. 使用JDK动态代理设计模式实现:拦截close方法,把连接放回到池中。
  4. 动态代理涉及的核心API?
    1. java.lang.reflect.Proxy类:代理类
       * 通过Proxy类中的方法来生成代理类和对象
       * 其中newProxyInstance方法主要用来构造代理类的对象
         static newProxyInstance(类加载器,代理的接口,处理器)
          - 类加载器:用来加载该方法在内存中生成的代理类的字节码序列。
          - 代理类的接口:代理类可以看做是实现类,实现哪个接口必须要传入的。【JDK的代理方式必须提供接口】
          - 处理器:每一个代理中的方法 都会调用InvocationHandler的invoke方法。所以我们必须提供一个InvocationHandler接口类型的对象。
      
    2. java.lang.reflect.InvocationHandler:处理器类
      通过以上方法创建的任何代理对象中方法的调用都会执行InvocationHandler接口中的invoke方法
      public Object invoke(Object proxy,Method method,Object[] args){
      	proxy:代表代理对象
      	method:当前执行的方法
      	args:参数
      }
      

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QViSclek-1655820918660)(JDBC_new.assets/image-20220621175845977.png)]

10.回顾1:MySQL数据库和Oracle数据库的区别?


  1. Oracle中的表是属于某一个用户的,要想查看表首先需要登录到某个用户下;MySQL中的表都是属于某一个database的,要想查看表首先打开某一个database;

  2. MySQL中数字类型的主键支持auto_increment自动增长子句的。oracle中不支持的

  3. MySQL中分页的关键字 limit,Oracle中分页的关键字 rownum

  4. MySQL中支持 if [not] exists ,oracle中不支持
    drop table if exists student;

  5. MySQL中常用的数据类型: int varchar() date
    oracle …:number varchar2 date

11.回顾2:MySQL中的批量添加数据?


  1. insert into (字段列表) values (),(),()…
     insert into student(name,age,birth,email,phone)
        values
         ('lisi',234,now(),'lisi@qq.com','13512344321'),
         ('wangwu',345,now(),'ww@qq.com','1111');
    Query OK, 2 rows affected, 2 warnings (0.01 sec)
    Records: 2  Duplicates: 0  Warnings: 2
    
  2. insert into (字段列表) (select… ) union (select …) union (select) [mybatis.]
    insert into student(name,age,birth,email,phone)
        -> (select 'zhaoliu',age,birth,email,'333' from student where id=2)union all
        -> (select 'etoak',234,birth,email,phone from student where id=3);
    

12.回顾3:数据库中表和表之间的关系?


  • 一对一 :建表原则 :通过主键关联或者通过唯一外键关联

    person id name
    		1  zhangsan 
    idcard id address  personid[外键] unique
    		1  xxx      1
    		2  xxx      
    
  • 一对多 :建表原则:通过外键关联

    dept: deptno dname loc 一方
    	  10
    emp: empno ename job sal hiredate comm  deptno【外键】 多方
    										10
    										10
    
  • 多对多 :建表原则:通过第三张表关联

    student
    	id name
    	
    course 
    	id name 
    	
    桥表 关联表 sc:  sid  cid 
                      1    1
                      1   2
                      2   1
    

13.补充回顾4:SQL连表查询?


 1. 查询学生信息和所在的学校信息?
		mysql> select s.id as sid ,s.name as sname ,s.age,s.birth,sch.id,sch.name,sch.phone,concat_ws('-',pro.name,city.name,area.name ,sch.info) addr from student s left join  school sch on s.schid = sch.id left join locations pro on sch.proid = pro.id
	left join locations city on sch.cityid = city.id
	left join locations area on sch.areaid = area.id where s.name like '%a%' limit 0,2;
	+----+----------+------+---------------------+------+----------+-------------+-------+-------------------------------------------------------+
	| id | name     | age  | birth               | id   | name     | phone       | proid | concat_ws('-',pro.name,city.name,area.name ,sch.info) |
	+----+----------+------+---------------------+------+----------+-------------+-------+-------------------------------------------------------+
	|  1 | zhangsan |  123 | 2021-03-29 11:17:46 |    1 | 山东大学 | 13012344323 |     1 | 山东省-济南市-历下区-山大路XX号                       |
	|  2 | lisi     |  123 | 2021-03-29 11:17:51 |    1 | 山东大学 | 13012344323 |     1 | 山东省-济南市-历下区-山大路XX号                       |
	|  3 | wangwu   |   23 | 2021-03-29 11:20:36 |    1 | 山东大学 | 13012344323 |     1 | 山东省-济南市-历下区-山大路XX号                       |
	|  4 | zhaoliu  |   26 | 2021-03-29 11:20:36 |    2 | 青岛大学 | 13012344300 |     1 | 山东省-青岛市-市南区-青大路XX号                       |
	+----+----------+------+---------------------+------+----------+-------------+-------+-------------------------------------------------------+
	4 rows in set (0.00 sec)
	
	不使用like:							
	select s.id as sid ,s.name as sname ,s.age,s.birth,sch.id,sch.name,sch.phone,sch.proid,concat_ws('-',pro.name,city.name,area.name ,sch.info) info from student s left join  school sch on s.schid = sch.id left join locations pro on sch.proid = pro.id
	left join locations city on sch.cityid = city.id
	left join locations area on sch.areaid = area.id where  instr(s.name,'a')>0 limit 0,2
	
		2. 查询每个学校的学生人数
		mysql> select sch.id ,sch.name,count(s.id) as sl from school sch left join student s on s.schid = sch.id group by s.schid;
	+----+----------+-------------+
	| id | name     | count(s.id) |
	+----+----------+-------------+
	|  3 | 济南大学 |           0 |
	|  1 | 山东大学 |           3 |
	|  2 | 青岛大学 |           1 |
	+----+----------+-------------+
	3 rows in set (0.00 sec)
	
		3. 查询学生的选课信息和分数?
		查询学校地址是济南的学生的以上信息 每页显示2条,显示第二页数据
	mysql> select
	     s.id as sid,s.name as sname ,s.age,s.birth,
	     sch.id as schoolid,sch.name as schname,
	     concat_ws('-',pro.name,city.name,area.name,sch.info)      addr,c.id as cid,c.name as cname ,c.code,
	     sc.score from student s 
	     left join sc on s.id = sc.sid
	     left join course c on c.id = sc.cid
	     left join school sch on s.schid = sch.id
	     left join locations pro on sch.proid = pro.id
	     left join locations city on sch.cityid =city.id
	     left join locations area on sch.areaid = area.id
	     where concat_ws('-',pro.name,city.name,area.name,sch.info)  like '%济南%'
	     order by sc.score desc limit 2,2;
	+-----+----------+------+---------------------+----------+----------+---------------------------------+------+---------+------+-------+
	| sid | sname    | age  | birth               | schoolid | schname  | addr                            | cid  | cname   | code | score |
	+-----+----------+------+---------------------+----------+----------+---------------------------------+------+---------+------+-------+
	|   3 | wangwu   |   23 | 2021-03-29 11:20:36 |        1 | 山东大学 | 山东省-济南 市-历下区-山大路XX号 |    4 | DB      | 1004 |    95 |
	|   1 | zhangsan |  123 | 2021-03-29 11:17:46 |        1 | 山东大学 | 山东省-济南 市-历下区-山大路XX号 |    3 | JAVAWEB | 1003 |    92 |
	+-----+----------+------+---------------------+----------+----------+---------------------------------+------+---------+------+-------+
	2 rows in set (0.00 sec)
		4. 查询每门课程的选课人数?
		mysql> select name, count(sid) from sc left join course c on c.id = sc.cid group by cid;
	+----------+------------+
	| name     | count(sid) |
	+----------+------------+
	| COREJAVA |          3 |
	| ORACLE   |          1 |
	| JAVAWEB  |          2 |
	| DB       |          2 |
	| VUE      |          2 |
	| 事务     |          1 |
	+----------+------------+
	6 rows in set (0.00 sec)
		5. 查询选修所有课程的学生信息?
		mysql> select * from student where id in(select sid from sc group by sid having count(cid)=(select count(*) from course));
	+----+----------+------+---------------------+-------+
	| id | name     | age  | birth               | schid |
	+----+----------+------+---------------------+-------+
	|  1 | zhangsan |  123 | 2021-03-29 11:17:46 |     1 |
	+----+----------+------+---------------------+-------+
	1 row in set (0.00 sec)
		6. 查询选修了课程的学生信息?
		7. 查询选修了比李四多的课程的学生信息?
		mysql> select * from student where id in(select sid from sc group by sid having count(cid)>(select count(cid) from sc where sid=(select id from student where name='lisi')))
	+----+----------+------+---------------------+-------+
	| id | name     | age  | birth               | schid |
	+----+----------+------+---------------------+-------+
	|  1 | zhangsan |  123 | 2021-03-29 11:17:46 |     1 |
	|  3 | wangwu   |   23 | 2021-03-29 11:20:36 |     1 |
	+----+----------+------+---------------------+-------+
	2 rows in set (0.00 sec)
	
		8. 查询"COREJAVA"的最高分?
		select s.id,s.name ,s.age,s.birth,sc.score from student s left join sc on s.id = sc.sid left join course c on c.id = sc.cid where s.id in (select sid from sc where score=(select max(score) from sc where cid=(select id 		 from course where name='COREJAVA')) and cid=(select id from course where name='COREJAVA')) and c.name='COREJAVA';


14. 补充回顾5:SQL的常用命令?


1.建库
create database 库名字; etoak;
2.打开库
use etoak
3.建表
mysql> create table student(id int primary key auto_increment ,
-> name varchar(32),birth datetime,age int, email varchar(30));
Query OK, 0 rows affected (0.05 sec)

4.添加数据:
insert into student(id,name,age,birth,email)values(null,‘zhangsan’,123,now(),‘etoak@qq.com’);

15.数据类型补充?


1. MySQL中我们常见的数据类型:int  date  varchar ,还有一种不常见的数据类型 lob(Large Object) 大对象类型 。如: 数据库中存放一部电影、一张图片
2. MySQL中有两种大对象类型: 
   1. blob :   (binary  lob )二进制大对象 存放字节数据
   2. text:存放字符大对象  一篇论文
3.  大对象 类型数据不可以通过客户端添加的(小黑板不能添加),一般通过JDBC程序添加。
4. 我们一般不会把 图片、电影等直接存放到数据库,而是把这些数据存放到服务器的某个文件夹中,然后把地址放到数据库中。

## 

16.图片上传:图片表


1.图片表主要用来存放上传到服务器的图片信息

2.字段
id ,
savepath[保存路径:一般改名之后再保存,避免命名重复之后覆盖] varchar(200)
realname[原名字,改名之前的名字] varchar(200)
uploadtime[上传时间] datetime
flag[这张图片是否作为头像 0:不启用 1:启用] tinyint
stuid[该图片属于哪一个学生] int

17.JAVA读写Excel?


1. JAVA读写Excel 比较著名的组件 apache-POI

2. 写出Excel  

   1. Workbook==>工作簿======>一个Excel文档
   2. Sheet-------->页 -----》一个Excel页面
   3. Row---------->行
   4. Cell----------->列

3. Wokbook:

   1. HSSFWorkbook:处理 .xls文档

   2. XSSFWorkbook:处理.xlsx文档 一般万条数据以内

   3. SXSSFWorkbook:最多可以处理104万条数据

18. JDBC的封装?


1. 为什么封装?
	JDBC流程代码重复太多。
2. 如何封装?
变化的内容作为参数,不变的流程固定下
3. 封装案例?
apache DBUtils / Spring JdbcTemplate
4. 通过案例掌握DBUtils工具包?
代码实践
5. DBUtils的底层原理?
反射之后,再来详细研究,目前首先达到会用模式
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值