第七周总结

分页查询的语法

select 指定的字段列表 from  表名  limit 起始索引,每页显示的条数;
-- 起始索引 = (当前页码数-1)*每页显示的条数;
-- 当前页码数以及 每页显示的条数----前端传过来的数据!

-- 后端 pageBean:自定义分页组件
class PageBean<T>{
	private int currentPage;  当前页码
	private int pageSize ; 每页显示的条件
	private int totalPage; 总页数 ---  
					-- (totalCount % pageSize == 0)?totalCount/pageSize:向上取整;
	private int totalCount ;  总记录数
	private List<T> list ;  分页的列表数据
}

2.通过sql添加/删除为唯一约束的语法

-- 通过sql添加唯一约束
-- 如果在创建表的时候,没有设置唯一约束名称,默认和字段名称一致;
alter table 表名 add constraint <唯一约束名称> unique(字段名称) ;
-- 通过sql删除唯一约束
alter table 表名 drop index 唯一约束名称;

3.通过sql添加外键约束和删除外键约束

-- 添加外键约束
alter table 表名  
			add
            constraint 外键名称(主表名缩写_从表名的缩写_fk)
            foreign key(外键作用字段名称)
            references 主表名(主键id字段) ;
            
-- 删除外键约束
alter table 表名 drop foreign key 外键名称;

4.模糊搜索的语法

select 指定的字段列表 from 表名 where 字段名称 like '%关键字%' ; -- '关键字%'

5.反射获取一个类的字节码文件后如何调用成员方法?

//获取当前正在运行的这个类Class,字节码文件对象
Class  c = Class.forName("包名.类名") ;
//如果当前类的无参构造方法公共的,直接创建当前类实例
Object obj = c.newInstance();
//通过字节码文件对象获取成员方法所在的Method类对象
Method m = c.getDeclareedMethod("方法名",形式参数类型的.class属性...) ;
//取消Java语言访问检查
c.setAccessiable(true) ;
//调用方法
m.invoke(obj,实际参数和形式参数类型匹配) ;
//有返回值直接返回Object,或者没有返回值,单独调用或者return null;


级联查询

级联删除/级联修改
写在字段列表尾部
删除或者修改主表的时候从表也随之变化 不用一个一个的删除修改

    on  update cascade

    on  delete casecade

CREATE TABLE employee (
  id INT PRIMARY KEY AUTO_INCREMENT,
  -- 员工编号
  NAME VARCHAR (10),
  -- 员工姓名
  gender VARCHAR (3),
  -- 员工性别
  salary DOUBLE,
  -- 工资
  dept_id INT,
  -- 所在的部门编号
  -- 声明 
  CONSTRAINT -- 外键名称:主表名_从表名_fk
  dept_emp_fk -- 外键作用在哪个字段上
  FOREIGN KEY (dept_id) -- 关联
  REFERENCES -- 主表的主键字段(就是id)
  dept(id)
    
  ON UPDATE CASCADE 	-- 级联修改
  ON DELETE CASCADE 	-- 级联删除
) ;

SQL直接添加级联修改/删除

   alter table 表名 

add  constraint 外键名 

foreign key  (列名)

references 主表名(列名)

on  update cascade on  delete casecade

表和表的关系

一对多举例

		部门和员工的关系
		从部门维度--->一个部门中包含多个员工
		从员工维度---> 一个员工从属于某个部门
		
		用户和订单
			一个用户(用户维度):一个用户可以下多个订单
			订单(订单维度):一个订单在某个时刻属于某个用户的
					一个订单可以可以从属于多个用户的

多对多举例

		学生表和选课表
		一个学生可以选择多个课程
		一个课程被多个学生选择
		
		用户表和角色表   (用户表和角色表中间表)
		
			从用户维度--看角色:一个用户有多个角色
			从角色维度--看用户:一个角色赋予多个用户
		角色表和权限表	 (角色表和权限表中间表)
			从角色表维度--看权限:一个角色可以多个权限
							CEO:crud(添加,查询,修改和删除)
			从权限维度---看角色:一个权限可以被多个角色赋予
							查询权限:
									CEO
									hr
									root管理员
									普通管理员

一对一

三大范式

目的是为了减少冗余,建立结构合理的数据库,从而提高数据存储和使用的性能。

第一范式

遵循原子性,表中的字段数据不可再拆分, 每一列都是独立的

反例:
学生id姓名年龄
1一年级小张16
2二年级小李15
3三年级小黄17

可以看出 列2的数据是可以继续拆分的 所以不符合第一范式

修改成第一范式的如下:

正例:
学生id姓名年级年龄
1小张一年级16
2小李二年级15
3小黄三年级17

第二范式

在第一范式情况下 消除部分依赖 遵循唯一性,

表中任意一个主键可以确定除该主键外的所有非主键值

即非主键字段必须完全依赖主键字段

即每张表只能描述一件事情

总表
员工id姓名年龄绩效部门薪水
1小胡33A销售部3000
1小胡23A开发部6000
2小陈24B策划部5000
2小陈24C开发部6000
3小梁30C测试部4500

主键是ID可以确定姓名年龄 但是不能确定部门,工龄

主键是部门 可以确定薪水 但是无法确定其他数据

以此类推 不合适 所以拆分成三张表

员工表
员工id姓名年龄绩效
1小胡33A
1小胡23A
2小陈24B
2小陈24C
3小梁30C
部门表
部门薪水
销售部3000
开发部6000
测试部4500
策划部5000

第三范式

满足第二范式的情况下 消除依赖传递

即 知道任一主键就可以确定其他所有非主键字段的值的情况下,不能存在某非主键字段A可以获取某非主键字段B的情况。

员工id姓名部门直属上级
1小胡销售部王科

id为主键可以确定姓名部门和直属上级 但是知道直属上级也可以推导出是哪个部门的

员工表
学号姓名部门
1小胡销售部
部门表
部门直属上级
销售部王科

多表查询–内连接-显隐/外连接-左右

最基本的语法:
		select 指定字段名称 from 表名1 ,表名2;
		
查询两个表(主表 从表)的数据不加连接条件的话,会造成笛卡尔乘积
例如
A报表三组数据
B组五组数据
不设置连接条件会输出十五天数据

内连接:
     1)隐式内连接  where 条件1 and 条件2 and 条件3....
     2)显示内连接  表名1 inner(inner可写可不写) join 表名2 on 连续条件;
外连接
       左外:left (outer) join
       右外:right (outer) join
       outer 可写可不写
       
子查询
    select 嵌套 select
		利用聚合函数--查询出来的单行单列的数据和比较运算符 (完成嵌套)
		
		条件字段名称  in(嵌套selct...)
		
		(select 指定字段列表 from 表名)----> 虚表 和另一种张进行连接条件  
表名别名 .*  查询该表所有数据
隐式内连接例子
# 创建部门表
CREATE TABLE dept(
id INT PRIMARY KEY AUTO_INCREMENT, -- 部门编号
NAME VARCHAR(20) -- 部门名称
);
INSERT INTO dept (NAME) VALUES ('开发部'),('市场部'),('财务部');


# 创建员工表
CREATE TABLE emp (
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) -- 外键,关联部门表(部门表的主键) (省略constraint 外键名称)
) ;
# 写入内容
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('孙悟空','男
',7200,'2021-02-24',1);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('猪八戒','男
',3600,'2022-12-02',2);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES
('唐僧','男',9000,'2020-08-08',2);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('白骨精','女
',5000,'2021-10-07',3);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('蜘蛛精','女
',4500,'2021-11-14',1);

#  给表起别名
SELECT 
  e.`id` '员工编号',
  e.`name` '员工姓名',
  e.`gender` '性别',
  e.`salary` '工资',
  e.`join_date` '入职日期',
  d.`name` '部门名称' 
FROM
  emp e,
  -- 给表起一个别名
  dept d -- d是部门表的别名
WHERE e.`dept_id` = d.`id` ;

显示内连接例子
# 创建部门表
CREATE TABLE dept(
id INT PRIMARY KEY AUTO_INCREMENT, -- 部门编号
NAME VARCHAR(20) -- 部门名称
);
INSERT INTO dept (NAME) VALUES ('开发部'),('市场部'),('财务部');


# 创建员工表
CREATE TABLE emp (
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) -- 外键,关联部门表(部门表的主键) (省略constraint 外键名称)
) ;
# 写入内容
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('孙悟空','男
',7200,'2021-02-24',1);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('猪八戒','男
',3600,'2022-12-02',2);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES
('唐僧','男',9000,'2020-08-08',2);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('白骨精','女
',5000,'2021-10-07',3);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('蜘蛛精','女
',4500,'2021-11-14',1);

INSERT INTO emp(NAME,gender,salary,join_date)
VALUES('王大炮','男',8000,'2018-10-30') ;//插入一个没有部门信息的数据
INSERT INTO emp(NAME,gender,salary,join_date) VALUES('文章','男',7000.0,'2020-05-01') ; //插入一个没有部门信息的数据


select
   t1.`id` '员工编号',
   t1.`name` '员工姓名',
   t1.`salary` '工资',
   t1.`join_date` '入职日期',
   t2.`dept_id`'员工部门'
from
emp t1
  inner join  dept t2
on t1.`dept_id`=t2.`id`;
左外连接(比较常用)
将A表的数据全部显示以及A和B的有连接关系的所有数据查询
select
    指定的字段列表
from
    A 表 别名1
left (outer) join 
    B表 别名2
on
    A 和 B 的连接条件 ; 
    
-- 查询员工表的所有数据 包括没有部门的信息(王大炮)
SELECT 
  e.*,
  d.`id`,
  d.`name` 
FROM
  emp e 
  LEFT OUTER JOIN depts d 
    ON e.`depts_id` = d.`id` ;
   id	NAME	gender	salary	join_date	depts_id	id	name
1	孙悟空	男	7200	2021-02-24	1	1	开发部
5	蜘蛛精	女	4500	2021-11-14	1	1	开发部
2	猪八戒	男	3600	2022-12-02	2	2	市场部
3	唐僧	男	9000	2020-08-08	2	2	市场部
4	白骨精	女	5000	2021-10-07	3	3	财务部
6	王大炮	男	8000	2018-10-30	\N	\N	\N



INSERT INTO emp(NAME,gender,salary,join_date) VALUES('文章','男',7000.0,'2020-05-01') ; 
  -- 如果提示:仅仅没有部门的员工的也需要查询出来,使用左外连接
SELECT 
  e.`name` '员工姓名',
  e.`gender` '员工性别',
  e.`salary` '员工工资',
  e.`join_date` '入职日期',
  d.`name` '部门名称' 
FROM
  emp e 
  LEFT JOIN dept d 
    ON e.`dept_id` = d.`id` -- 作为两张表的连接条件
WHERE e.`salary` >= -- 附件条件
  (SELECT 
    AVG(salary) 
    
  FROM
    emp) ;

员工姓名	员工性别	员工工资	入职日期	部门名称
孙悟空	男	7200	2021-02-24	开发部
唐僧	男	9000	2020-08-08	市场部
王大炮	男	8000	2018-10-30	\N
文章	男	7000	2020-05-01	\N
右外连接
将B表的数据全部显示以及A和B的有连接关系的所有数据查询
select
    指定的字段列表
from
    B 表 别名1
right (outer) join 
    A表 别名2
on
    A 和 B 的连接条件 ;

子查询

(select 嵌套)

需求:查询工资是九千的员工信息部门
select
    t1.*,
    t2.*
from
    emp t1,dept t2
where  
    t1.`dept_id`=t2.`id`
and    
    t1.salary
    =(select max(salary)from emp);
    
    
需求: 子查询 in(值1,值2,值3...);
查询在2或者3号部门的所有员工信息
select
    e.*,
    d.`id`,
    d.name
from
    emp.e,
    dept.d
where
    e.`dept_id`=d.`id`
and e.`dept_id`in(
select
    id
form
    dept
where name in('市场部','财务部')
);

子查询-虚表

将某张表select的结果集---当做一张虚表和其他表建立连接查询

-- 需求:要查询出员工入职日期大于2021-10-07的员工的所有信息以及它的部门信息;
-- 查询员工入职日期大于  2021-10-07的员工所有信息 (查询出来的结果集当作 "虚表")
SELECT 
  t1.*,
  -- 所有的部门信息
  t2.* -- 所有员工信息
FROM
  depts t1 
  INNER JOIN 
    (SELECT 
      * 
    FROM
      emp 
    WHERE emp.`join_date` > '2021-10-07') 
  t2 
    ON t1.`id` = t2.`depts_id` ;
把员工表的满足入职日期在2021-10-07之后的数据的结果当作一个新的表
id	NAME	id	NAME	gender	salary	join_date	depts_id
1	开发部	  5	 蜘蛛精	    女	       4500	     2021-11-14	      1
2	市场部	  2   猪八戒    	男	      3600	     2022-12-02	  2

  

隐式内连接版本:
 SELECT 
  e.*,
  d.* 
FROM
  emp e,
  depts d 
WHERE e.`depts_id` = d.`id` 
  AND e.`join_date` > '2021-10-07' ;  
id	NAME	gender	salary	join_date	depts_id	id	NAME
5	蜘蛛精	   女	4500	2021-11-14	   1	      1	开发部
2	猪八戒	   男	3600	2022-12-02	   2	      2	市场部

数据库的事务

DBA(数据库管理员)用户在操作多个sql的时候,有一条执行语句异常,其他sql不执行,导致数据紊乱。应将整个sql的执行看作一个整体,要么同时执行成功,要么同时执行失败。

开启事务:start transaction

事务回滚:rollback  回滚最初的数据

commit:事务提交  不提交的话无法永久更改
传统事务特点(ACID)

原子性:
     执行的某个业务操作,同时执行多个sql ,增删改。
     要么同时成功要么同时失败
一致性:
     实际开发中,多个线程同时去读和写的时候,数据必须保持一致性
隔离性:
     事务和事务(业务和业务)之间,相互独立互不影响
持续性:
     对增删改的这些sql数据,一旦事务提交了。对数据库的表的操作是永久的,及时关机也不会改变
     
传统事务的隔离级别:
     执行效率从大到小。安全性从低到高  级别 从低到高
#读未提交 read uncommitted;
     一个事务读取到另一个没有提交的事务(最不安全的),出现脏读。
#读已提交:read committed;
     //有效防止脏读,但是又出现另一个问题:'不可重复读'
     读取到自己本身没有提交的事务的数据前后两次不一致  本身这个事务没有提交  
     多次读取到的数据必须一致,
     
# 可重复读,Mysql的默认隔离级别(repetable-read)
    //有效防止脏读,'不可重复读',但是又出现新的问题:幻读
#可序列化:serializable;
最高级别的隔离   避免脏读 避免不可重复读 避免幻读
事务只能一个接一个执行


设置隔离级别
set global transaction isoloation level
查看隔离级别
select @@tx_isoloation

1.什么是事务?

 	关系型数据库中--支持"多事务",都会在事务机制,当某个业务同时操作多个sql语句或者是多张表的sql插入/删除/修改),这多个sql要么同时执行成功,要么同时执行失败,保证数据的完整性!

2.事务的特点和事务的隔离级别

事务的特点
	原子性:多个sql要么同时执行成功,要么同时执行失败,保证数据的完整性!
	一致性:事务同时去操作多个sql的时候,需要保证数据的一致性!
	隔离性:多个事务(业务和业务之间)之间互相独立的,互不影响
	持久性:当事务一旦提交,对数据的更改是永久性的,即使关机也存在!
事务的隔离级别:
	-- 下面依次从小到大,安全性低大高,效率:从高到低;
	read uncommitted ; 读未提交
	read committed ;  读已提交
	repetable read ; 可重复读		mysql的默认级别:有效防止脏读以及不可重复读
	serializable ;  串行话

3.mysql多表查询内连接和左外连接的语法

-- 隐式内连接
select 指定的字段名称  from  表名1,表名2 where 条件1 and 条件2.... ;
-- 显示内连接
select 指定的字段名称  from  表名1 inner join 表名2  on  连接条件;
-- 左外连接语法:将左表数据全部查询以及它们的交集部分的数据
select 指定的字段名称	from   表名1 left outer join 表名2  on 连接条件  where 附件条件..

4.数据库的三大范式描述

1NF:
	数据库表中的每一列是独立,不能在拆分的原子数据项
2NF:
	在1NF基础上
	1)数据库指定表中,描述一件事情(一张表描述一件事情)
	2)数据库表中的非主键字段必须完全依赖主键字段
3NF:
	在2NF基础上			
	数据库表中非主键字段之间不能产生传递依赖!
	非主键字段A---字段B---->字段C :产生传递依赖		
	-- 解决冗余:比如多对多---拆分中间表:设置外键连接
	

5.通过mysql指令如何控制事务

-- 开启事务:将mysql自动提交,切换手动提交事务
start transaction ;
-- 设置回滚命令
rollback;
-- 永久更新数据(保证数据的持久性)
commit ;

-- 设置隔离级别
set global transaction isolation level 级别名称;
-- 查看隔离级别
select @@tx_isolation ;


JDBC

本质:数据库厂商提供的一个普通java类,实现sun公司提供的接口(java.sql.Driver)得类

在对应的数据库官网下载对应的jar包

#入门操作

 1. 导入驱动包:mysql-connector-java-5.1.25.jar或者mysql-connector-java-8.0.15.jar

     打开idea,File-->Project Structure-->Mudoles-->Dependencies-->左边+号点第一个JAR..

2. //注册驱动
3. //准备sql语句
4. //获取数据连接对象
5. //通过数据库的连接对象获取执行对象
6. //执行对象执行sql
7. //释放资源

例子

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

public class JdbcDemo {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        //准备sql语句
        String sql=
                " insert into test2 (id,name,age,address,number)values(2,'judy',20,'俄亥俄',13209879749);";
       //获取数据连接对象
  /*      public static Connection getConnerction(
                String url, 统一资源定位符:连接的具体库
                                                String user,  用户名
                                                 String password 密码
                )throws SQLException*/

        Connection connection = DriverManager.getConnection
                ("jdbc:mysql://localhost:3306/sanbao",
                        "root",
                        "yisanbao19970808");

        //通过数据库的连接对象获取执行对象
        Statement sts = connection.createStatement();
        //执行对象执行sql
        int i = sts.executeUpdate(sql);
        System.out.println("影响了"+i+"行");
        //释放资源
        sts.close();
        connection.close();
    }
}
sql中的结果:

id	name	age	address	    number
1	mike	18	加利佛尼亚	132979877
2	kiki	18	佛罗里达	 13243565465
3	joho	18	旧金山	      132985764
4	cc	    20	 纽约	       15387867
2	judy	20	俄亥俄        13209879749
    
    需要不断创建对象 写参数 比较麻烦
    

例子(改良1)

package com.qf.jdbc_01;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * @author 高圆圆
 * @date 2023/4/4 11:31
 * jdbc操作DDL语句,创建一张表 student
 *                              id int ,name varchar(10),age int,gender varchar(3),address varchar(50),
 *
 */
public class JdbcDemo2 {
    public static void main(String[] args) {
        //捕获异常
        //1)导包
        //2)注册驱动
        Connection conn = null ;
        Statement stmt = null ;
        try {
            Class.forName("com.mysql.jdbc.Driver") ;
            //3)获取数据库连接对象
            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/myee2302_db_2",
                    "root",
                    "123456");
            //4)准备sql
            String sql = "create table student(" +
                    "id int primary key auto_increment," +
                    "name varchar(10)," +
                    "age int," +
                    "gender varchar(3)," +
                    "address varchar(50));";
            //5)通过连接对象获取执行对象
            stmt  = conn.createStatement();
            //6)执行更新操作 DDL语句 executeUpdate(String sql)
            int count = stmt.executeUpdate(sql);
            System.out.println(count);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            if(stmt!=null){
                try {
                    stmt.close() ;
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if(conn!=null){
                try {
                    conn.close() ;
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }
    }
}

写工具类 把参数写src下的properties文件中

package com.qf.utils;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/**
 * 将jdbc步骤优化
 *       自定义工具类,将获取连接对象,释放资源都放在静态方法中,方便去使用!
 */
public class JdbcUtils {
    //统一资源定位符
    private static String url = null ;
    //用户名
    private static String user = null ;
    //密码
    private static String password = null ;
    //驱动类
    private static String driverClassName = null ;

    //定义静态代码块
    static{
        try {
            //1)读取src下面的jdbc.properties文件
            //创建一个属性集合列表
            Properties prop = new Properties() ;
            System.out.println(prop) ;
            InputStream inputStream = JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
            //将字节输入流加载到属性集合列表中
            prop.load(inputStream) ;
            System.out.println(prop) ;
            //2)通过key获取value
            driverClassName = prop.getProperty("driverClassName");
            url = prop.getProperty("url");
            user = prop.getProperty("user");
            password = prop.getProperty("password");

            //3)注册驱动
            Class.forName(driverClassName) ;

        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    //对外私有,不让外界new
    private JdbcUtils(){}


    //定义公共的静态方法,返回值就是Connection
    //public static Connection getConnection(String url,String user,String password){ //一会还得需要传入参数,
    public static Connection getConnection(){ //一会还得需要传入参数,
        Connection conn = null ;
        try {
           conn = DriverManager.getConnection(url,user,password) ;//url,user,password
            return  conn;
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return  null ;
    }


    //释放资源
    //主要针对DDL/DML语句操作释放资源
    public static void close(Statement stmt,Connection conn){
        if(stmt!=null){
            try {
                stmt.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {

        Connection conn = JdbcUtils.getConnection();
        System.out.println(conn);
    }
}





配置文件
# properties内:
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/myee2302_db_2
user=root
password=123456

Statement执行对象

package com.qf.jdbc_03;
//将表内容打印控制台
import com.qf.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * 使用Statment执行对象来操作DQL语句,并去将所有的结果集数据表打印在控制台上
 */
public class Statement_DQL {
    public static void main(String[] args) {
        Connection conn = null ;
        Statement stmt = null ;
        ResultSet rs = null ;
        try {
            //注册驱动并获取连接对象
             conn = JdbcUtils.getConnection() ;//JdbcUtils来自上面的例子里的工具类
            //准备sql语句
            String sql = "select * from student;" ;

            //通过连接对象获取执行对象,准备发送sql到数据库
            stmt = conn.createStatement() ;
            //执行通用的查询操作
            rs = stmt.executeQuery(sql) ;
            //第一次获取
            System.out.println("编号\t姓名\t\t\t年龄\t性别\t地址") ;
            //有下一行数据获取
            //boolean next() ;
       /*     if(rs.next()){
                //列的索引值获取
                int id = rs.getInt(1) ;
                String name = rs.getString(2) ;
                int age = rs.getInt(3) ;
                String gender = rs.getString(4);
                String address = rs.getString(5);
                System.out.println(id+"\t"+name+"\t\t"+age+"\t"+gender+"\t"+address);
            }

            //第二次获取
            //通过列的名称获取
            if(rs.next()){
                int id = rs.getInt("id") ; //id名称
                String name = rs.getString("name") ; //name名称
                int age = rs.getInt("age") ; //age名称
                String gender = rs.getString("gender") ; //gender
                String address = rs.getString("address") ; //address
                System.out.println(id+"\t"+name+"\t\t"+age+"\t"+gender+"\t"+address);
            }

            //第三次获取
            //通过列的名称获取
            if(rs.next()){
                int id = rs.getInt("id") ; //id名称
                String name = rs.getString("name") ; //name名称
                int age = rs.getInt("age") ; //age名称
                String gender = rs.getString("gender") ; //gender
                String address = rs.getString("address") ; //address
                System.out.println(id+"\t"+name+"\t\t\t"+age+"\t"+gender+"\t"+address);
            }*/

            //当不明确多少个结果,while循环
            while(rs.next()){
                //有数据,获取
                int id = rs.getInt("id") ; //id名称
                String name = rs.getString("name") ; //name名称
                int age = rs.getInt("age") ; //age名称
                String gender = rs.getString("gender") ; //gender
                String address = rs.getString("address") ; //address
                System.out.println(id+"\t"+name+"\t\t\t"+age+"\t"+gender+"\t"+address);
            }



        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            JdbcUtils.close(rs,stmt,conn);
        }
    }
}

自己例子

package Utils;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class Jdbcutils {
    private static  String url=null;
    private  static String user=null;
    private  static String password=null;
    private  static String driverClassName=null;

    //定义静态代码块
    static {
        try {
            Properties prop = new Properties();
            System.out.println(prop);
            InputStream input = Jdbcutils.class.getClassLoader().getResourceAsStream("jdbc.properties");
            prop.load(input);
            System.out.println(prop);

            driverClassName= prop.getProperty("driverClassName");
            url=prop.getProperty("url");
            user=prop.getProperty("user");
            password=prop.getProperty("password");
            Class.forName(driverClassName);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    private Jdbcutils(){}

    public static Connection getConnection(){
        Connection conn=null;
        try {
            conn= DriverManager.getConnection(url, user, password);
            return  conn;
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return null;
    }
    public static void close(Statement stmt, Connection conn) {
        if (stmt!=null) {
            try {
                stmt.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
}




jdbc.properties内容:
driverClassName=com.mysql.jdbc.Driver
password=yisanbao19970808
user=root
url=jdbc:mysql://localhost:3306/sanbao



package Test1;


import Utils.Jdbcutils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Test {
    public static void main(String[] args){
        Connection conn = null;
        Statement stm=null;
        ResultSet rs=null;

        try {
            String sql="select*from student";
            conn = Jdbcutils.getConnection();
            stm = conn.createStatement();
            rs=stm.executeQuery(sql);
            System.out.println("编号\t姓名\t语文成绩\t数学成绩\t英语成绩");

            while(rs.next()){
                int id=rs.getInt("id");
                String name=rs.getString("name");
                int chinese=rs.getInt("chinese");
                int math=rs.getInt("math");
                int english=rs.getInt("english");
                System.out.println(id+"\t"+"    "+name+"\t"+"    "+chinese+"\t"+"      "+math+"\t"+"           "+english);
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
}


模仿例子

JdbcUtils

package com.qf.utils;

import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

/**
 * 将jdbc步骤优化
 *       自定义工具类,将获取连接对象,释放资源都放在静态方法中,方便去使用!
 */
public class JdbcUtils {
    //统一资源定位符
    private static String url = null ;
    //用户名
    private static String user = null ;
    //密码
    private static String password = null ;
    //驱动类
    private static String driverClassName = null ;

    //定义静态代码块
    static{
        try {
            //1)读取src下面的jdbc.properties文件
            //创建一个属性集合列表
            Properties prop = new Properties() ;
            //System.out.println(prop) ;
            InputStream inputStream = JdbcUtils.class.getClassLoader().
                    getResourceAsStream("jdbc.properties");
            //将字节输入流加载到属性集合列表中
            prop.load(inputStream) ;
            //System.out.println(prop) ;
            //2)通过key获取value
            driverClassName = prop.getProperty("driverClassName");
            url = prop.getProperty("url");
            user = prop.getProperty("user");
            password = prop.getProperty("password");

            //3)注册驱动
            Class.forName(driverClassName) ;

        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    //对外私有,不让外界new
    private JdbcUtils(){}


    //定义公共的静态方法,返回值就是Connection
    //public static Connection getConnection(String url,String user,String password){ //一会还得需要传入参数,
    public static Connection getConnection(){ //一会还得需要传入参数,
        Connection conn = null ;
        try {
           conn = DriverManager.getConnection(url,user,password) ;//url,user,password
            return  conn;
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return  null ;
    }


    //释放资源
    //针对DQL语句操作释放资源
    public static void  close(ResultSet rs,Statement stmt,Connection conn){
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if(stmt!=null){
            try {
                stmt.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }

    //主要针对DDL/DML语句操作释放资源
    public static void close(Statement stmt,Connection conn){
        close(null,stmt,conn);
    }
   //测试类  
    public static void main(String[] args) {

        Connection conn = JdbcUtils.getConnection();
        System.out.println(conn);
    }
}

jdbc.properties内容:
driverClassName=com.mysql.jdbc.Driver
password=yisanbao19970808
user=root
url=jdbc:mysql://localhost:3306/sanbao

Student

package Test2;
/*
id  int(11) NULL
name  varchar(20) NULL
chinese  int(11) NULL
english  int(11) NULL
math  int(11) NULL*/
@SuppressWarnings("all")
public class Student {
    private  int id;
    private  String name;
    private  int chinese;
    private int math;
    private  int english;

    public Student() {
    }

    public int getId(int id) {
        return this.id;
    }

    public String getName(String name) {
        return this.name;
    }

    public int getChinese(int chinese) {
        return this.chinese;
    }

    public int getMath(int math) {
        return this.math;
    }

    public int getEnglish(int english) {
        return this.english;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setChinese(int chinese) {
        this.chinese = chinese;
    }

    public void setMath(int math) {
        this.math = math;
    }

    public void setEnglish(int english) {
        this.english = english;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", chinese=" + chinese +
                ", math=" + math +
                ", english=" + english +
                '}';
    }
}

StudentDao

package Test2;

import java.util.List;

public interface StudentDao {
    List<Student> findAll();
    void add(Student s)throws Exception;
}

StudentImpl

package Test2;

import Utils.JdbcUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
@SuppressWarnings("all")
public class StudentImpl  implements StudentDao{
    @Override
    public List<Student> findAll() {
        List<Student> list = null ;
        Connection conn = null ;
        Statement stt = null ;
        ResultSet res = null ;
        try {
            list=new ArrayList<>();
            conn= JdbcUtils.getConnection();
            String sql="select * from student;";
            stt=conn.createStatement();
            res=stt.executeQuery(sql);
            Student s=null;
            while(res.next()){
                s=new Student();
                s.getId(res.getInt("id"));
                s.getName(res.getString("name"));
                s.getChinese(res.getInt("chinese"));
                s.getMath(res.getInt("math"));
                s.getEnglish(res.getInt("english"));

                list.add(s);
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return  list;

    }

    @Override
    public void add(Student s) throws Exception {
        Connection connection = JdbcUtils.getConnection();
        String sql="insert into student(id,name,chinese,english,math)values('\"+s.getId()+\"','\"+s.getName()+\"','\"+s.getChinese()+\"','\"+s.getEnglish()+\"','\"+s.getMath()');";
        Statement statement = connection.createStatement();
        int count=statement.executeUpdate(sql);
        System.out.println(count);
        JdbcUtils.close(statement, connection);

    }
}

Test

package Test2;


import Utils.JdbcUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
@SuppressWarnings("all")
public class Test2 {
    public static void main(String[] args) {
        List<Student> list = getStudents();
        for(Student s:list){
            System.out.println(s);
        }
    }

    public static List<Student> getStudents() {
        List<Student> list = null ;
        Connection conn=null;
        Statement stt=null;
        ResultSet res=null;
        try {
            list=new ArrayList<>();
            conn= JdbcUtils.getConnection();
            String sql="select*from student;";
            stt=conn.createStatement();
            res=stt.executeQuery(sql);
            Student s=null;
            while(res.next()){
                s=new Student();
                s.setId(res.getInt("id"));
                s.setName(res.getString("name"));
                s.setChinese(res.getInt("chinese"));
                s.setMath(res.getInt("math"));
                s.setEnglish(res.getInt("english"));

                list.add(s);
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return  list;
    }
}




输出结果:
{}
{user=root, url=jdbc:mysql://localhost:3306/sanbao, password=yisanbao19970808, driverClassName=com.mysql.jdbc.Driver}
Student{id=1, name='行哥', chinese=89, math=90, english=78}
Student{id=2, name='潘金莲', chinese=67, math=95, english=53}
Student{id=3, name='凤姐', chinese=87, math=77, english=78}
Student{id=4, name='旺财', chinese=88, math=92, english=98}
Student{id=5, name='白小黑', chinese=82, math=67, english=84}
Student{id=6, name='白小黄', chinese=55, math=45, english=85}
Student{id=7, name='范蹦蹦', chinese=75, math=30, english=65}


单元测试

一个java语言的单元测试框架

程序测试分为白盒和黑盒,查询结果是否在范围内

黑盒测试

    不需要写过多的代码(数据的录入集成..)

    输入指定数据输出结果,技术含量低。一直录入数据 直到程     序出bug。

白盒测试(结构测试/透明盒测试)

    懂各种后端语言的基础

    例如给你一个计算机类 add(),sub(), mul(), div()提供加减乘除的功能,调用add(10,20)通过junit提供”断言“add方法的结果是否和预期值一致。需要自己书写代码。

需要使用:”junit “单元测试方法

提供的runner启动器可以编译和运行

1)导包,导入jar包,核心包(junit)和依赖包(hamcrest)

2)写单元测试类-->xxxTest

提供一个成员方法:没有参数 没有返回值!

成员方法上加一个注解@Test

测试功能

导入idea的方法和导入jdbc包一样。

例子

package JunitDemo1;
//计算器类
public class Calculator {
    //加
    public int add(int a, int b) {
        return a + b;
    }
   //乘
    public int mul(int a, int b) {
        return a * b;
    }
    //除
    public int div(int a, int b) {
        return a / b;
    }
     //减
    public int sub(int a, int b) {
        return a - b;
    }
}


package JunitDemo1;
//单元测试类
import org.junit.Assert;
import org.junit.Test;

public class CalculatorTets {
  @Test//要写Test
    public void testAdd(){
      Calculator cal = new Calculator();
      int sum= cal.add(10, 20);
      Assert.assertEquals(30, sum);
     //参数1:预期值,参数2:结果实际值,两个是否相等,相等,则断言成功;否则断言失败!
  }
}
//此时的断言是成功的 10+20=30,符合预期值
当我们把与预期值改了或者把调用的计算器类的方法改了 再或者故意把add方法改为a-b,总之就是出问题了,程序断言错误:
java.lang.AssertionError: 
Expected :50
Actual   :0
<Click to see difference>

经典作业题

题目

1.使用Statement执行对象,完成针对员工进行添加,删除,修改,和查询操作

员工类Employee中有员工编号,姓名,员工年龄,员工性别,员工工资,员工出生日期 (根据今天有一个项目中代码分层进行操作)
	com.qf.pojo
	com.qf.dao
	com.qf.dao.impl
	com.qf.test--->里面提供单元测试的类以及单元测试方法

	EmployeeDao接口提供以下功能
			a)添加员工
			b)修改员工
			c)删除员工
			d)查询所有员工
			e)List<Employee> findEmpByName(String name); 模糊查询  举例"模糊查询姓王的员工"
			f)List<Employee> findEmpByLimit(int currentPage,int pageSize) ;分页查询,已知当前页码和每页显示的条数
			g)int totalCount() ;查询总记录数
			h)通过id查询指定的员工信息  Employee  findEmpById(int id)
	在EmployeeDaoImpl中实现
	在EmployeeTest中使用单元测试 针对功能进行测试!  (工具类自己最好手写一遍,加深印象)

实体类

package com.number1.pojo;

public class Employee {
    private  int id;
    private  int age;
    private  String name;
    private  String gender;
    private  int salary;
    private  String birthday;

    public Employee() {
    }

    public Employee(int id, int age, String name, String gender, int salary, String birthday) {
        this.id = id;
        this.age = age;
        this.name = name;
        this.gender = gender;
        this.salary = salary;
        this.birthday = birthday;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public int getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }

    public String getBirthday() {
        return birthday;
    }

    public void setBirthday(String birthday) {
        this.birthday = birthday;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", age=" + age +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", salary=" + salary +
                ", birthday='" + birthday + '\'' +
                '}';
    }
}

接口类

package com.number1.dao;

import com.number1.pojo.Employee;

import java.sql.SQLException;
import java.util.List;

public  interface EmployeeDao{
    //添加
    void add(Employee e) throws SQLException;
    //删除
    void delete(int d) throws SQLException;
    //修改
    void update(Employee e,int a) throws SQLException;
    //查询
    List<Employee> findall() ;
    //模糊查询
    List<Employee> findEmpByName(String name);
   //分页查询
    List<Employee> findEmpByLimit(int currentPage, int pageSize) ;
   //查询总记录数
    int totalCount() throws SQLException;
    //通过id查询指定的员工信息
    Employee  findEmpById(int a) throws SQLException;

}

子实现类

package com.number1.dao.impl;



import JdbcUtils.JdbcUtils;
import com.number1.dao.EmployeeDao;
import com.number1.pojo.Employee;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

@SuppressWarnings("all")
public  class EmployeeDaoImpl implements EmployeeDao{
    //添加
    @Override
    public void add(Employee e) throws SQLException {
      /*  Connection conn = JdbcUtils.getConnection();
        String sql =
                "insert into employee2(id,name,gender,age,birthday,salary) values(' " + e.getId() +" ' , ' "+ e.getName()+ " ' , ' "+ e.getGender() + " ' ,' " + e.getAge() + " ' , ' " + e.getBirthday() + " ' , ' " + e.getSalary() +" ') ;";
        Statement stt = conn.createStatement();
        int i=stt.executeUpdate(sql);
        System.out.println("影响了"+i+"行");
        JdbcUtils.close(stt, conn);*/
    }
     //删除
    @Override
    public void delete(int d) throws SQLException {
/*        Connection conn = JdbcUtils.getConnection();
        String sql =
                "delete from employee2 where id=' "+d+" ';";
        Statement stt = conn.createStatement();
        int i=stt.executeUpdate(sql);
        System.out.println("影响了"+i+"行");
        JdbcUtils.close(stt, conn);*/
    }
    //修改
    @Override
    public void update(Employee e,int a) throws SQLException {
/*        Connection conn = JdbcUtils.getConnection();
        String sql =
                "UPDATE employee2 SET NAME=' "+e.getName()+" ' WHERE ID=' "+a+" ';";
        Statement stt = conn.createStatement();
        int j=stt.executeUpdate(sql);
        System.out.println("影响了"+j+"行");
        JdbcUtils.close(stt, conn);*/
    }
   //查询全部
    @Override
    public List<Employee> findall() {
        List<Employee>list=null;
        Connection conn=null;
        Statement stt=null;
        ResultSet rs=null;

        try {
            list=new ArrayList<>();
            String sql="select * from employee2;";
            conn=JdbcUtils.getConnection();
            stt=conn.createStatement();
            rs=stt.executeQuery(sql);
            Employee e=null;
            while(rs.next()){
                               
                e.setId(rs.getInt("id"));
                e.setName(rs.getString("name"));
                e.setAge(rs.getInt("age"));
                e.setGender(rs.getString("gender"));
                e.setBirthday(rs.getString("birthday"));
                e.setSalary(rs.getInt("salary"));

                list.add(e);
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return list;
    }
   //模糊查询
    @Override
    public List<Employee> findEmpByName(String name) {
        List<Employee>list=null;
        Connection conn=null;
        Statement stt=null;
        ResultSet rs=null;

        try {
            list=new ArrayList<>();
            String sql="select * from employee2 where  name  like' %" +name+"% ';";
            conn=JdbcUtils.getConnection();
            stt=conn.createStatement();
            rs=stt.executeQuery(sql);
            Employee e=null;
            while(rs.next()){
                e=new Employee();
                e.setId(rs.getInt("id"));
                e.setName(rs.getString("name"));
                e.setAge(rs.getInt("age"));
                e.setGender(rs.getString("gender"));
                e.setBirthday(rs.getString("birthday"));
                e.setSalary(rs.getInt("salary"));

                list.add(e);
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return list;
    }
   //分页查询
    @Override
    public List<Employee> findEmpByLimit(int currentPage, int pageSize) {
        List<Employee>list=null;
        Connection conn=null;
        Statement stt=null;
        ResultSet rs=null;

        try {
            list=new ArrayList<>();
            String sql="select * from employee2 limit "+(currentPage-1)*pageSize+","+pageSize+";";
            conn=JdbcUtils.getConnection();
            stt=conn.createStatement();
            rs=stt.executeQuery(sql);
            Employee e=null;
            while(rs.next()){
                e=new Employee();
                e.setId(rs.getInt("id"));
                e.setName(rs.getString("name"));
                e.setAge(rs.getInt("age"));
                e.setGender(rs.getString("gender"));
                e.setBirthday(rs.getString("birthday"));
                e.setSalary(rs.getInt("salary"));

                list.add(e);
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return list;
    }
   //查询总记录数
    @Override
    public int totalCount() throws SQLException {
        Connection conn = JdbcUtils.getConnection();
        String sql =
                "SELECT COUNT(id) FROM employee2;";
        Statement stt = conn.createStatement();
        ResultSet resultSet = stt.executeQuery(sql);
        int count =0;//统计变量
        while(resultSet.next()){
            count=resultSet.getInt(1);
        }
        JdbcUtils.close(stt, conn);
        return count;
    }

   //根据id查询信息

    @Override
    public Employee findEmpById(int a) {
         Employee e=null;
        Connection conn=null;
        Statement stt=null;
        ResultSet rs=null;


        try {
            conn=JdbcUtils.getConnection();
            String sql="SELECT * FROM employee2 WHERE id="+a+";";
            stt=conn.createStatement();
            rs=stt.executeQuery(sql);
            while(rs.next()){
                 int id=rs.getInt("id");
                 String name=rs.getString("name");
                String gender=rs.getString("gender");
                 int age=rs.getInt("age");
                String birthday=rs.getString("birthday");
                int salary=rs.getInt("salary");
                e=new Employee(id,age,name,gender,salary,birthday);
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return  e;
    }
}

测试类

package com.number1.test;

import com.number1.dao.EmployeeDao;
import com.number1.dao.impl.EmployeeDaoImpl;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.sql.SQLException;

@SuppressWarnings("all")
public class Test1 {
    private  EmployeeDao ed;
    @Before
    public  void init(){
        System.out.println("执行单元测试方法之前执行了");
        ed=new EmployeeDaoImpl();
        System.out.println(ed);
    }
    //添加
    @Test
    public void  testAdd() throws SQLException {
/*        Employee ee=new Employee();
        ee.setId(6);
        ee.setName("董九");
        ee.setAge(23);
        ee.setBirthday("19970806");
        ee.setSalary(5000);
        ed.add(ee);*/
    }
    
     //删除

    @Test
    public void  testDelete() throws SQLException {
   /*     ed.delete(1);*/
    }
    
    //修改

    @Test
    public void  testUpdate() throws SQLException {
/*        Employee ee=new Employee();
        ee.setName("王五");
        ed.update(ee,3);*/
    }
    
    //查询全部
    
    @Test
    public void  testFindAll(){
 /*       List<Employee>list= ed.findall();
        for(Employee e:list){
            System.out.println(e);
        }*/
    }
    
    //模糊查询

    @Test
    public void testfindEmpByName(){
/*        List<Employee>list= ed.findEmpByName("董九");
        for(Employee e:list){
            System.out.println(e);
        }*/
    }
    
    //分页查询
    
    @Test
    public void testfindEmpByLimit(){
    /*    List<Employee>list= ed.findEmpByLimit(2,2);
        for(Employee e:list){
            System.out.println(e);
        }*/
    }
    
    //查询总记录数
    
    @Test
    public void testtotalCount() throws SQLException {
/*        int count=ed.totalCount();
        System.out.println("共有"+count+"条数据");*/
    }
    
    //根据id查询信息

    @Test
    public void findEmpById() throws SQLException {
        System.out.println(ed.findEmpById(4));
    }
    @After
    public void close(){
        System.out.println("执行单元测试方法之后执行了");
    }
}

1.jdbc的本质是什么?

Jdbc是一个普通的Java类,是数据库厂商提供的驱动jar包,可以实现sun提供一套接口规范!
  	java.sql.Driver:驱动接口---->驱动jar包--->实现了这个接口
  	java.sql.Connection:数据库的连接会话--->驱动jar包--->ConnectionImpl实现了这个接口
  	...

2.jdbc的7大操作步骤,代码体现

// 7大步骤 后期--->开源框架:就是对原生Jdbc代码的封装+一些配置文件
//1)导入驱动jar包 --mysql-connnecto-java驱动jar包  
//2)注册驱动
Class.forName("com.mysql.jdbc.Driver") ; 
//3)获取数据库的连接对象
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/库名",
"root",
"123456") ;
//4)准备sql语句:DDL语句或者DML语句
String sql = "insert into employee(name,age,gender,birthday,address) values(xxx,xx,xx,xx,xx,xx)" ;
//5)通过连接对象获取执行对象Statement 
Statement stmt  = conn.createStatement() ;
//6)执行sql,通用的更新
int count = stme.executeUpdate(sql) ;
//7)释放资源
stmt.close() ;
conn.close() ;

3.jdbc针对DQL语句,遍历结果集

// 7大步骤 后期--->开源框架:就是对原生Jdbc代码的封装+一些配置文件
//1)导入驱动jar包 --mysql-connnecto-java驱动jar包  
//2)注册驱动
Class.forName("com.mysql.jdbc.Driver") ; 
//3)获取数据库的连接对象
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/库名",
"root",
"123456") ;
//4)准备sql语句:DDL语句或者DML语句
String sql = "select 指定的字段列表  from 表名" ;
//5)通过连接对象获取执行对象Statement 
Statement stmt  = conn.createStatement() ;
//6)执行sql,通用的查询操作
ResultSet rs = stmt.executeQuery(sql) ;

//遍历结果集
while(rs.next()){
    //获取数据
    //通用的写,列的名称获取/列的索引值获取
    XXX 变量= rs.getXXX("字段名称") ;
    //自己封装数据...
}

//7)释放资源
stmt.close() ;
conn.close() ;

4.自定义工具类JdbcUtils的步骤

配置类文件:
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/库名
user=root
password=123456
class JdbcUtils{
    private static String user = null ;
    private static String password = null ;
    private static String driverClass = null ;
    private static String url = null ;
    
    //定义static代码块
    static{
        //读取配置文件
        Properties prop = new Properties() ;
        //获取key对应的value,赋值给上面四个成员变量
        InputStream inputStream = JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties") ;
        user = prop.getProperty("user") ;
        password = prop.getProperty("password") ;
        url = prop.getPrpperty("url") ;
        driverClass = prop.getProperty("driverClass") ;
        //注册驱动
        Class.forName(driverClass) ;
    }
    
    
 
    private JdbcUtils(){}
    public static Connnection getConnection(){
        	Connection conn = DriverManager.getConnection(url,user,password) ;
        return conn ;
    }
    //释放资源
    //带三个参数:ResultSet ,Statment,Connection---针对DQL语句操作
    //带两个参数:Satement,Connection--->针对DML语句
}

5.junit单元测试的使用步骤

 	1)导入junit的核心包: 4.13.1以及依赖包
 	2)建立测试类---XXXTest
 	3)定义单元测试方法,在方法上加入@Test 
 	4)方法中要么Assert断言,要么直接测试指定功能(XXXDao--->添加,删除,修改,查询的功能)

视图View

    CREATE VIEW <视图名> AS <SELECT语句>

视图是一个虚拟表,非真实存在,其本质是根据SQL语句获取动态的数据集,并为其命名,用户使用时只需使用视 

图名称即可获取结果集,并可以将其当作表来使用。 

数据库中只存放了视图的定义,而并没有存放视图中的数据。这些数据存放在原来的表中。 

使用视图查询数据时,数据库系统会从原来的表中取出对应的数据。因此,视图中的数据是依赖于原来的表中的数据的。 

一旦表中的数据发生改变,显示在视图中的数据也会发生改变

例子

-- 创建视图
CREATE VIEW employee2_view AS 
SELECT 
  id,
  NAME,
  gender,
  age,
  birthday,
  salary 
FROM
  employee2 ;
-- 查看视图内容
SELECT* FROM employee2_view;
-- 查看视图结构
DESC employee2_view;
-- 查询当前库中所有表以及视图名称
SHOW TABLES;
-- 查询当前库中所有表以及视图名称以及表类型
SHOW FULL TABLES;
-- 修改视图的内容
ALTER VIEW employee2_view 
  AS 
  SELECT 
    id,
    NAME 
  FROM
    employee2 ;

-- 更新视图(用的少)
UPDATE 
  employee2_view 
SET
  NAME = '何求军' 
WHERE id = 2 ;

-- 删除视图(不会影响基础表,只是删除视图的定义)
DROP VIEW employee2_view ;
-- 重命名视图
RENAME TABLE employee2_view TO employee2_2_view;

使用Statement的弊端

1)sql注入

     原因:sql语句的实际参数存在字符串拼接,导致语句出现漏洞;(不安全)

2)执行效率低

     每一次将写的sql发送数据库,(写一个sql,发送一个次sql,频繁的操作库),高并发情况下,可能造成系统奔溃!

3)    
     开发中不会使用Statement去操作数据库,使用PreparedStatement预编译对象
     

就是以用户登录为例 最后无论输出的是密码和用户名正确还是不正确,都只输出登录成功或者登录失败两种结构。是一种不安全的方法

PreparedStatement(重点)

预编译对象
开发中使用:PreparedStatement---执行预编译sql语句    
select * from user where username = ? and passwod=?  ; //? 占位符符号
一条sql:insert into/update/delete /select--->有参数--->全部都是? 占位符号

登录注册PreparedStatement版本

//接口类
package UserTest2;


import java.sql.SQLException;

public interface UserDao2 {
    boolean log(User2 user) throws SQLException;
}
//实体类
package UserTest2;

public class User2 {

    private String username;
    private  String password;

    public User2() {
    }

    public User2(String username, String password) {
        this.username = username;
        this.password = password;
    }

    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 "User2{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}
//子实现类
package UserTest2;

import JdbcUtils.JdbcUtils;
import UserTest.User;

import java.sql.*;

public class UserDaoImpl2  implements UserDao2 {

    @Override
    public boolean log(User2 user) throws SQLException {
        Connection conn = null;
        PreparedStatement stt = null;
        ResultSet rs = null;

        String sql =
                "select * from userr where username= ?and password=?";
        conn = JdbcUtils.getConnection();
        stt = conn.prepareStatement(sql);
        stt.setString(1, user.getUsername());
        stt.setString(2, user.getPassword());
        rs = stt.executeQuery();
        ResultSet resultSet = stt.executeQuery();
        boolean next = resultSet.next();
        JdbcUtils.close(rs, stt, conn);
        return next;
    }
}


//测试类
package UserTest2;


import java.sql.SQLException;
import java.util.Scanner;

public class UserTest2 {
    public static void main(String[] args) throws SQLException {
        Scanner scanner = new Scanner(System.in);

        System.out.println("请输入您的用户名");
        String username=scanner.nextLine();
        System.out.println("请输入您的密码");
        String password=scanner.nextLine();

        UserDao2 ud2=new UserDaoImpl2();
        User2 u=new User2();
        u.setUsername(username);
        u.setPassword(password);
        boolean log = ud2.log(u);
        if(log){
            System.out.println("登录成功");
        }else{
            System.out.println("登录失败");
        }
    }
    }

PreparedStatement和Statement的区别?

1)共同点
     都是发送sql到数据库,都是执行对象,前者继承后者
2)不同点
    # 2-1)是否可造成sql注入,
    Statement 永远执行的静态sql语句,语句存在'硬编码' 和sql的字符串拼接,造成sql注入,不安全
    PreparedStatement永远执行参数化sql语句,参数都是“?”,占位符号。预防sql注入,提高sql的安全性
    # 2-2)执行效率
    Statement不会提高sql执行效率
    获取执行对象,然后将sql语句发送数据库。频繁操作访问数据库
    PreparedStatement 大大提高sql执行效率
    参数化sql是在获取PreparedStatement,时已经发送数据库了

数据库连接池(重点)

c3p0
dbcp
druid:德鲁伊---->阿里巴巴提供的 (开源的)
		druid.jar包
只是提供数据库连接池---不能连接数据库(要连接数据库---提供mysql驱动jar包)
JdbcUtils就需要优化了
		模拟线程 ThreadLocal<T> :  每一个线程都有自己的Connection
				set(T t):绑定内容
				remove():解绑
				T get() :获取指定的内容
				
步骤:
 1)导包 druid-1.1.10.jar包
 2)准备好连接池的配置文件
  driverClassName=com.mysql.jdbc.Driver//连接数据库的驱动类
  url=jdbc:mysql://localhost:3306/myee2302_db_2//连接数据库   的url地址:统一资源定位符
  username=root//用户名
  password=123456//密码
    //连接池一旦创建 初始化5个数量
initialSize=5//初始化数量(可变) 默认值 0
maxActive=10//最大激活(连接)数量 默认值 8  和最大空闲数量maxIdel相等
maxWait=3000//最大等待时间 默认值 -1(无等待时间) 3000毫秒也就是3秒 如果创建的连接对象超过最大连接数量。等待3s报错

 3)从连接池获取连接对象
提供jar包--->com.alibaba.druid.pool.DruidDataSource--->本质实现了一个接口javax.sql.DataSource
           --->Connection getConnection()
           

例子

package DruridDemo;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.util.Properties;

public class DruridDemo {
    public static void main(String[] args) throws Exception {
        //创建配置文件
        Properties prop = new Properties();
        //读取配置文件
        InputStream input = DruridDemo.class.getClassLoader().getResourceAsStream("drurid.properties");
        //加载字节输入流
        prop.load(input);
        //获取连接对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
        System.out.println(dataSource.getConnection());
        /*红字部分是日志:  四月 06, 2023 5:20:05 下午 com.alibaba.druid.pool.DruidDataSource info
信息: {dataSource-1} inited*/
        for(int x=0;x<=11;x++){
            Connection conn = dataSource.getConnection();
            System.out.println(conn);
            /*
com.mysql.jdbc.JDBC4Connection@71f2a7d5
com.mysql.jdbc.JDBC4Connection@2cfb4a64
com.mysql.jdbc.JDBC4Connection@5474c6c
com.mysql.jdbc.JDBC4Connection@4b6995df
com.mysql.jdbc.JDBC4Connection@2fc14f68
com.mysql.jdbc.JDBC4Connection@591f989e
com.mysql.jdbc.JDBC4Connection@66048bfd
com.mysql.jdbc.JDBC4Connection@61443d8f
com.mysql.jdbc.JDBC4Connection@445b84c0
com.mysql.jdbc.JDBC4Connection@61a52fbd
三秒后报错:Exception in thread "main" com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 3000, active 10, maxActive 10, creating 0*/
        }
    }
}


情况2:加条件if(x==3)
    结果如下
/*
四月 06, 2023 5:31:52 下午 com.alibaba.druid.pool.DruidDataSource info
信息: {dataSource-1} inited
com.mysql.jdbc.JDBC4Connection@71f2a7d5
com.mysql.jdbc.JDBC4Connection@2cfb4a64
closed-conn-88558700
com.mysql.jdbc.JDBC4Connection@4b6995df
com.mysql.jdbc.JDBC4Connection@2fc14f68
com.mysql.jdbc.JDBC4Connection@591f989e
com.mysql.jdbc.JDBC4Connection@66048bfd
com.mysql.jdbc.JDBC4Connection@61443d8f
com.mysql.jdbc.JDBC4Connection@445b84c0
com.mysql.jdbc.JDBC4Connection@61a52fbd
com.mysql.jdbc.JDBC4Connection@233c0b17*/

配置文件drurid.properties:
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/sanbao
username=root
password=yisanbao19970808
initialSize=5
maxActive=10
maxWait=3000

连接池工具类

package JdbcUtils;

import com.alibaba.druid.pool.DruidDataSourceFactory;
import javafx.beans.property.Property;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

public class DruridUtils {
    //静态实例-->java.lang.ThreadLocal<T>模拟线程,每一个用户都有自己的Connection
    private static ThreadLocal<Connection> t1 = new ThreadLocal<>();
    //声明一个DataSource接口类型
    private static DataSource ds;

    //构造方法私有
    private DruridUtils() {
    }

    static {
        try {//读取德鲁伊配置文件,让其自我封装
            InputStream input = DruridUtils.class.getClassLoader().getResourceAsStream("drurid.properties");
            //创建属性列表
            Properties prop = new Properties();
            //加载属性列表
            prop.load(input);
            //创建连接池
            ds = DruidDataSourceFactory.createDataSource(prop);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //获取DataSource数据源信息 (连接池的所有参数)
    private static DataSource getDataSource() {
        return ds;
    }

    //从连接池获取连接对象
    public static Connection getConnection() {
        //1)从本地线程中获取连接对象---ThreadLocal<T>--->T get():从当前线程中获取存储的内容
        Connection conn = t1.get();
        try {
            //2)如果当前conn对象为null,说明当前线程中没有要操作的连接对象
            if (conn ==null) {
                //3)从数据源(连接池中)获取Connection
                conn = ds.getConnection();
                //4)将从数据源中获取到的conn连接对象,绑定当当前线程中
                //ThreadLocal<T>--->public void set(T t):绑定
                t1.set(conn);
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return conn;
    }

    //释放资源
    public static void close(ResultSet rs, PreparedStatement stmt, Connection conn) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
                //从当前线程解绑
                t1.remove();  //ThreadLocal<T> :从线程中移出
            } catch (SQLException throwables) {
                throwables.printStackTrace();

            }
        }
    }
        //主要针对DDL/DML语句操作释放资源
   /* public static void close(Statement stmt,Connection conn){
        close(null,stmt,conn);
    }*/
        public static void close (PreparedStatement stmt, Connection conn){
            close(null, stmt, conn);
        }
        public static void main (String[]args){
            System.out.println(DruridUtils.getDataSource());
            System.out.println(DruridUtils.getConnection());
        }
    }

添加数据

package DruridDemo;

import JdbcUtils.DruridUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
@SuppressWarnings("ALL")
public class DruridTest {
    public static void main(String[] args) throws SQLException {
        Connection conn = DruridUtils.getConnection();
        String sql="insert into employee2(id,name,gender,age,birthday,salary)values(?,?,?,?,?,?)";
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setInt(1, 7);
        ps.setString(2, "林冲");
        ps.setString(3, "男");
        ps.setInt(4, 33);
        ps.setString(5, "19900807");
        ps.setInt(6, 7000);

        int i = ps.executeUpdate();
        System.out.println(i);
        DruridUtils.close(ps, conn);
    }
}

Jdbc控制事务

常用方法

Jdbc控制事务:
    public void setAutoCommit(boolean auto) ;参数为true,表示自动提交,如果是false,手动提交
    void rollback():事务回滚,撤销之前所有更改,必须释放连接对象,连接对象需要从线程中解绑
    void commit():提交事务,将更改数据永久保存,提交完毕,释放连接对象,需要从线程中解绑

  什么是事务?
 针对多个sql或者多张表的sql(增删改),要么同时执行成功,要么同时执行失败,应该将整个业务看成一个整体,一块执行!
 事务的特点:
      原子性,一致性,隔离性,持久性

  需求:
       转账业务:
             account账户表中:id为3的用户给id为4的账户进行转账500

例子老师

public class TranserDemo {
    public static void main(String[] args) {
        Connection conn = null ;
        PreparedStatement ps1=  null ;
        PreparedStatement ps2=  null ;
        try {
            //获取连接池中的初始化连接数量中的连接对象
             conn = DruidJdbcUtils.getConnection();

             //开启手动提交模式(开启事务)
            //public void setAutoCommit(boolean auto) ;参数为true,表示自动提交,如果是false,手动提交
            conn.setAutoCommit(false) ;


            //sql语句
            String sql1 = "update account set balance = balance - ? where id = ?" ;
            String sql2 = "update account set balance = balance + ? where id = ?" ;

            //发送参数化的sql获取编译对象
             ps1 = conn.prepareStatement(sql1) ;
             ps2 = conn.prepareStatement(sql2) ;

            //参数赋值
            ps1.setInt(1,500) ;
            ps1.setInt(2,3) ;

            ps2.setInt(1,500) ;
            ps2.setInt(2,4) ;

            //在预编译对象中执行
            int count = ps1.executeUpdate();
            int i = 10/0 ; //明显给了异常,实际开发中可能其他系统监控代码出现bug了也会造成 前面sql执行了,后面没有执行1
            int count2 = ps2.executeUpdate();
            System.out.println(count+"----"+count2) ;


           // void commit():提交事务,将更改数据永久保存,提交完毕,释放连接对象,需要从线程中解绑
          conn.commit(); //事务提交
        } catch (SQLException throwables) {
            //事务回滚
           // void rollback():事务回滚,撤销之前所有更改,必须释放连接对象,连接对象需要从线程中解绑
            try {
                conn.rollback();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            throwables.printStackTrace();
        } finally {
            DruidJdbcUtils.close(ps1,conn) ;
            DruidJdbcUtils.close(ps2,conn) ;
        }

    }
}

dbutils步骤和常用方法

注意事项:实体类的属性名称和字段类型的名称必须一致 否则查询语句的时候输出的是null,
	或者可以在查询的时候给字段别名但是别名也得和实体类属性名称一致;
	也依赖德鲁伊工具类
步骤:
      1)导包:
      2)创建执行器 QueryRunner-->底层是PreparStatement
      public QueryRunner(DataSource ds) 参数就是数据源--->自定义工具获取到了数据源 (自动提交)
     public QueryRunner():创建执行器,手动提交
     3)准备好sql语句
        DML语句---添加/修改/删除
                  insert into
                  update
                  delete from...

QueryRunner提供通用的更新操作:
        public int update(Connection conn, String sql, Object... params) throws SQLException  :手动提交
        public int update(String sql, Object... params):自动提交


        DQL语句--- 查询语句

 QueryRunner提供的通用查询操作
        public <T> T query(String sql, ResultSetHandler<T> rsh, Object... params) throws SQLException
        第一个参数:查询的sql语句
        第二个参数:ResultSetHandler结果集的处理
        它的子实现类:BeanHandler---->将查询的某一条记录封装到实体了中(JavaBean:是具体类,属性私有,对外提供setXXX()/getXXX)
        public BeanHandler(Class<T> type) --->  参数针对查询的记录--封装到类名.class中

        子实现类:BeanListHandler<T>    ---将查询的多条记录封装到List集合中,List集合都是当前类对象
        public BeanListHandler(Class<T> type)
         子实现类:
        ScalarHandler:通过聚合函数(count(列名称),其他max(xx),avg(xxx))查询单行单的列的数据的结果封装到Object类中,第三个参数:就是赋值的实际参数params,没有参数可以不写

例子老师

接口类

package com.qf.dao;

import com.qf.pojo.Employee;

import java.sql.SQLException;
import java.util.List;

/**
 * @author Kuke
 * @date 2023/4/7 11:12
 * 针对员工的数据访问接口(持久层)
 */
public interface EmployeeDao {

    /**
     * 查询所有员工
     * @return 返回员工列表
     */
    List<Employee> findAll() throws SQLException;

    /**
     * 根据员工编号查询员工
     * @param id 员工编号
     * @return 返回员工实体
     */
    Employee findEmpById(int id) throws SQLException;

    /**
     * 查询总记录数
     * @return 返回总条数
     */
    int getTotalCount() throws SQLException;
}

实体类

package com.qf.pojo;

import java.util.Date;

/**
 * @author 高圆圆
 * @date 2023/4/7 11:10
 * 员工实体
 */
public class Employee {
    /**
     *
     id int(11) NOT NULL
     name varchar(10) NULL
     gender varchar(3) NULL
     age int(11) NULL
     salary double NULL
     address varchar(20) NULL
     birthday date NULL
     */
    private int id ;
    private String name ;
    private String gender ;
    private int age ;
    private double salary ;
    private String adderss ;
    private Date birthday;

    public Employee() {
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public String getAdderss() {
        return adderss;
    }

    public void setAdderss(String adderss) {
        this.adderss = adderss;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", age=" + age +
                ", salary=" + salary +
                ", adderss='" + adderss + '\'' +
                ", birthday=" + birthday +
                '}';
    }
}

子实现类

package com.qf.dao.impl;

import com.qf.dao.EmployeeDao;
import com.qf.pojo.Employee;
import com.qf.utils.DruidJdbcUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.sql.SQLException;
import java.util.List;

/**
 * @author 高圆圆
 * @date 2023/4/7 11:13
 */
public class EmployeeDaoImpl  implements EmployeeDao {
    /**
     * 查询所有员工
     * @return 返回员工列表
     */
    @Override
    public List<Employee> findAll() throws SQLException {

        //使用apache提供开源工库实现
        //创建QueryRunner
        //public QueryRunner(DataSource ds)
        QueryRunner qr = new QueryRunner(DruidJdbcUtils.getDataSource()) ;

        //sql
        String sql = "select * from employee" ;


        //将查询的多条记录封装List集合,集合List存储每一个员工对象
        //public <T> T query(String sql, ResultSetHandler<T> rsh, Object... params)
        //子实现类:BeanListHandler<T>    ---将查询的多条记录封装到List集合中,List集合都是当前类对象
        List<Employee> list = qr.query(sql, new BeanListHandler<>(Employee.class));
        return list;
    }


    /**
     * 根据员工编号查询员工
     * @param id 员工编号
     * @return 返回员工实体
     */
    @Override
    public Employee findEmpById(int id) throws SQLException {
        //创建执行对象
        QueryRunner qr = new QueryRunner(DruidJdbcUtils.getDataSource()) ;
        //sql
        String sql = "select * from employee where id = ?" ;
        //执行查询: 将某一条记录封装到实体中
        /**
         *  它的子实现类:BeanHandler---->将查询的某一条记录封装到实体了中(JavaBean:是具体类,属性私有,对外提供setXXX()/getXXX)
         *                     public BeanHandler(Class<T> type) --->  参数针对查询的记录--封装到类名.class中
         */
        Employee emp = qr.query(sql, new BeanHandler<>(Employee.class), id);
        return emp;
    }

    /**
     * 查询总记录数
     * @return 返回总条数
     */
    @Override
    public int getTotalCount() throws SQLException {
        //执行对象
        QueryRunner qr = new QueryRunner(DruidJdbcUtils.getDataSource()) ;
       //sql
        String sql = "select count(id) from employee" ;
        //将查询的结果:当行单例的数据封装到Object中
        /**
         *  ScalarHandler:通过聚合函数(count(列名称),其他max(xx),avg(xxx))查询单行单的列的数据
         *                         的结果封装到Object类中
         *                         //public ScalarHandler()
         */
        Object object = qr.query(sql, new ScalarHandler<>());
        //5----取出来
        //前面学的万能转换法 字符串转int
        String s = String.valueOf(object);
        int totalCount = Integer.parseInt(s);

        return totalCount;
    }
}

测试类

package com.qf.test;

import com.qf.dao.EmployeeDao;
import com.qf.dao.impl.EmployeeDaoImpl;
import com.qf.pojo.Employee;
import org.junit.Before;
import org.junit.Test;

import java.sql.SQLException;
import java.util.List;

/**
 * @author 高圆圆
 * @date 2023/4/7 11:13
 * 测试
 */
public class EmployeeTest {

    private EmployeeDao ed ;
    @Before
    public void init(){
        ed = new EmployeeDaoImpl() ;
    }

    //查询所有
    @Test
    public void testFindAll() throws SQLException {
        List<Employee> all = ed.findAll();
        if(all!=null){
            for(Employee emp :all){
                System.out.println(emp);
            }
        }
    }


    //查询执行员工
    @Test
    public void testFindEmpById() throws SQLException {
        Employee emp = ed.findEmpById(6);
        System.out.println(emp);
    }

    //查询总记录数
    @Test
    public void testTotalCount() throws SQLException {
        int count = ed.getTotalCount();
        System.out.println(count);
    }
}

例子自己(无注释净化版)

接口类

package com.dao;

import com.pojo.Employee;

import java.sql.SQLException;
import java.util.List;

public interface EmployeeDao {

    /**
     * 查询所有员工
     * @return 返回员工列表
     */
    List<Employee> findAll() throws SQLException;


    /**
     * 根据员工编号查询员工
     * @param id 员工编号
     * @return 返回员工实体
     */
    Employee findEmpById(int id) throws SQLException;


    /**
     * 查询总记录数
     * @return 返回总条数
     */
    int getTotalCount() throws SQLException;

    /**
     * 添加员工
     * @param emp 员工实体
     */
    void addEmployee(Employee emp) throws SQLException;

    /**
     * 根据员工id修改员工信息
     * @param emp  员工实体
     * @throws SQLException
     */
    void updateEmployee(Employee emp) throws SQLException ;

    /**
     * 根据员工姓名模糊查询
     * @param name  关键字员工名称
     * @return 返回员工列表
     */
    List<Employee> findEmpByName(String name) throws SQLException;
}

实体类

package com.pojo;

public class Employee {
    private int id;
    private String name;
    private String gender;
    private int age;
    private String birthday;
    private int salary;

    public Employee() {
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Employee(int id, String name, String gender, int age, String birthday, int salary) {
        this.id = id;
        this.name = name;
        this.gender = gender;
        this.age = age;
        this.birthday = birthday;
        this.salary = salary;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getBirthday() {
        return birthday;
    }

    public void setBirthday(String birthday) {
        this.birthday = birthday;
    }

    public int getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", age=" + age +
                ", birthday='" + birthday + '\'' +
                ", salary=" + salary +
                '}';
    }
}

子实现类

package com.dao.impl;

import com.dao.EmployeeDao;
import com.pojo.Employee;
import com.utils.DruidJdbcUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.sql.SQLException;
import java.util.List;

public class EmployeeDaoImpl  implements EmployeeDao {

    @Override
    public List<Employee> findAll() throws SQLException {
        QueryRunner qr=new QueryRunner(DruidJdbcUtils.getDataSource());
        String sql="select * from employee2";
        List<Employee> list = qr.query(sql, new BeanListHandler<>(Employee.class));
           return list;
    }

    @Override
    public Employee findEmpById(int id) throws SQLException {
        QueryRunner qr=new QueryRunner(DruidJdbcUtils.getDataSource());
        String sql="select * from employee2 where id=?";
        Employee e = qr.query(sql, new BeanHandler<>(Employee.class), id);
        return e;
    }

    @Override
    public int getTotalCount() throws SQLException {
        QueryRunner qr=new QueryRunner(DruidJdbcUtils.getDataSource());
        String sql="select count(id) from employee2";
        Object object = qr.query(sql, new ScalarHandler<>());
        String s = String.valueOf(object);
        int s1 = Integer.parseInt(s);
        return s1;
    }

    @Override
    public void addEmployee(Employee emp) throws SQLException {
        QueryRunner qr=new QueryRunner(DruidJdbcUtils.getDataSource());
        String sql = "INSERT INTO  employee2(id,name,gender,age,birthday,salary)values(?,?,?,?,?,?)" ;
        int add = qr.update(sql, emp.getId(), emp.getName(), emp.getGender(), emp.getAge(), emp.getBirthday(), emp.getSalary());
        System.out.println("影响了"+add+"行");
    }

    @Override
    public void updateEmployee(Employee emp) throws SQLException {
        QueryRunner qr=new QueryRunner(DruidJdbcUtils.getDataSource());
        String sql="update employee2 set name=? where id=?";
        int j = qr.update(sql, emp.getName(), emp.getId());
        System.out.println("影响了"+j+"行");
    }

    @Override
    public List<Employee> findEmpByName(String name) throws SQLException {
        QueryRunner qr=new QueryRunner(DruidJdbcUtils.getDataSource());
        String sql="select * from employee2 where name  like ?";
        List<Employee> query = qr.query(sql, new BeanListHandler<>(Employee.class),name);

        return query;

    }
}

测试类

package com.test;

import com.dao.EmployeeDao;
import com.dao.impl.EmployeeDaoImpl;
import com.pojo.Employee;
import org.junit.Before;
import org.junit.Test;

import java.sql.SQLException;
import java.util.List;

public class EmployeeTest {
    EmployeeDao ed;
@Before
    public void init(){
    ed=new EmployeeDaoImpl();
}
@Test
    public void testadd() throws SQLException {
    Employee e=new Employee();
    e.setId(9);
    e.setName("路飞");
    e.setAge(18);
    e.setGender("男");
    e.setBirthday("20020304");
    e.setSalary(5000);
    ed.addEmployee(e);
}
@Test
    public void testfindall() throws SQLException {
    List<Employee> la = ed.findAll();
    System.out.println(la);
}
@Test
    public void testFindEmpById() throws SQLException {
    Employee empById = ed.findEmpById(3);
    System.out.println(empById);
}
@Test
    public void testToutleCount() throws SQLException {
    int totalCount = ed.getTotalCount();
    System.out.println(totalCount);
}
@Test
    public void testUpdate() throws SQLException {
    Employee e=new Employee();
    e.setName("特鲁路");
    e.setId(2);
    ed.updateEmployee(e);
}
@Test
    public void testFindEmpByName() throws SQLException {
    List<Employee> empByName = ed.findEmpByName("%飞%");
    if(empByName!=null){
        for (Employee e:empByName)
            System.out.println(e);
    }
}
}

TOMCAT安装办法

启动路径:TOMCAT安装路径下的bin目录的startup.bat

必须配置JDK和JRE的环境变量:

高级系统设置:下方的系统环境配置中新建:JAVA_HOME  JRE_HOME 路径分别是jdk和jre的安装路径  PATH列表里加入%JAVA_HOME%\bin;和%MYSQL_HOME%\bin; 注意不要置顶  否则path会打不开列表

TOMECAT乱码解决

TOMCAT安装路径下的conf目录的logging.properties  改变里面的java.util.logging.ConsoleHandler.encoding = gbk  最后的编码格式是GBK 而不是UTF-8

开启tomcat服务后编辑: http://你自己的的端口号:8080

常见问题:

1)端口被占用(Erron running'Tomcat8.5.66';
Address localhost:1099 is already in use)解决:
    netstat -aon|findstr 1099:查看被那个进程占用 
    taskkill -f -pid xxxx:杀死该进程  xxxx:被占用的端口号

2)local Falied 问题
     试着改下端口号或者再Web项目下新建一个html  报错我感觉可能是没创建文件
3)404问题:
    运行tomcat 404  在Web项目下新建Html文件些内容再运行 不能再WEB_INF里运行。默认index 的html文件(tmocat源代码就是这么写的)

Idea部署tomcate 创建web文件图解

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值