第七周总结
1.MySQL级联操作/数据库的备份和还原/多表查询
-- 级联操作CASCADE
USE mydb_04;
SELECT * FROM emploee ;
SELECT * FROM dept ;
-- 为什么使用级联操作
-- 修改员工表(从表)的数据:dept_id
-- 不能直接修改/删除当前字段,除非当前这个表字段和主表的id字段没有关联关系,才能修改!
-- 删除员工表的id为9的人 (删除:先删除从表,在删除主表)
DELETE FROM emploee WHERE id = 9 ;
-- 删除部门 :删除4号部门
DELETE FROM dept WHERE id = 4;
-- 删除部门为3号部门
DELETE FROM dept WHERE id = 3 ;
-- Cannot delete or update a parent row: a foreign key constraint fails (`mydb_04`.`emploee`, CONSTRAINT `dept_emp_fk` FOREIGN KEY (`dept_id`) REFERENCES `dept` (`id`))
-- 结论:删除或者修改主表:不能操作的----必须先对从表数据进行删除或者修改!
-- 加入级联操作----修改或者删除主表 (从表的数据会随着主表的操作而变化!)
-- sql语句先将外键约束删除
ALTER TABLE emploee DROP FOREIGN KEY dept_emp_fk;
-- 添加级联操作(级联修改和级联删除)
ALTER TABLE emploee ADD
CONSTRAINT dept_emp_fk FOREIGN KEY (dept_id)
REFERENCES dept(id) ON DELETE CASCADE ON UPDATE CASCADE ;
-- 级联修改:
-- 需求:将1号部门变成5号部门 ,跟1号部门相关的员工的部门编号也会变化
UPDATE dept SET id = 5 WHERE id = 1 ;
-- 需求:删除2号部门,跟2号部门相关的员工也会被干掉
DELETE FROM dept WHERE id = 2 ;
SELECT * FROM dept ;
SELECT * FROM emploee ;
-- 当前员工表的dept_id(部门编号) 完全依赖于 部门表id
-- 数据库的备份和还原
-- 备份
-- 1)命令行的方式:进入dos
-- 备份的语法格式 mysqldump -u用户名 -p密码 数据库的名称 > 保存的路径
-- 2)使用推行界面化的方式来进行数据库的备份
-- 进入到sqlyog工具中--- 在数据库的上面右键---选择备份
-- 还原数据库
-- 1)进入dos之后:登录的msyql数据库中
-- 登录成功之后,删除当前mydb_04这个数据库
-- source 之前备份的sql文件路径-- 回车
-- 2)图形界面化的方式
-- 在sqlyog中删除当前mydb_04数据库,然后右键选择 以sql的转存文件来导入...
-- 多表查询
-- 通过查询两张或者两张以上的表时使用的sql语句---多表查询
CREATE DATABASE mydb_05 ;
USE mydb_05;
# 创建部门表
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,'2013-02-24',1);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('猪八戒','男 ',3600,'2010-12-02',2);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('唐僧','男',9000,'2008- 08-08',2);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('白骨精','女 ',5000,'2015-10-07',3);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('蜘蛛精','女 ',4500,'2011-03-14',1);
-- 需求:要查询员工表以及部门表中的所有数据
-- select * from 表名1,表名2;
SELECT
*
FROM
emp,dept;
-- 存在问题:产生了一个笛卡尔乘积
-- A表中有n条数据,B表中有m条数据,select * from A,B; ----n*m=总条数
-- 解决上面笛卡尔积的方案
-- 满足条件:
-- 1)查询哪个表 员工表和部门表
-- 2)查询指定表中的哪些字段 查询所有
-- 3)这些表的连接接条件是什么 员工表的dept_id部门编号依赖于部门表的主键id
-- 多表查询---内连接
-- 隐式内连接
/*
select
列名列表
from
表名列表
where
连接条件;
*/
SELECT
*
FROM
emp,
dept
WHERE
emp.dept_id = dept.id ;
-- 多表查询,查询指定字段
SELECT
emp.name ,-- 员工名称
emp.gender, -- 员工性别
emp.salary, -- 员工工资
emp.join_date, -- 入职日期
dept.name -- 部门名称
FROM
emp, -- 员工表
dept -- 部门表
WHERE
emp.dept_id = dept.id ; -- 连接 条件
-- 在查询时候,写表名太麻烦了,使用别名操作
SELECT
t1.*, -- 员工表所有数据
t2.name -- 部门名称
FROM
emp t1,
dept t2
WHERE
t1.dept_id = t2.id ;
-- 显示内连接
/*
select
列名列表
from
表名1
inner(可以省略) join
表名2
on
连接条件
*/
SELECT
t1.name,
t1.gender,
t1.salary,
t1.join_date,
t2.name
FROM
emp t1
INNER JOIN -- 显示内连接
dept t2
ON
t1.dept_id = t2.id ;
-- inner关键字可以省略
SELECT
t1.*,
t2.name
FROM
emp t1
JOIN
dept t2
ON
t1.dept_id = t2.id ;
SELECT * FROM dept ;
SELECT * FROM emp ;
-- 多表查询之:外连接查询
-- 左外/右外
INSERT INTO emp(NAME,gender,salary,join_date) VALUES('如来佛祖','男',10000,'2019-11-11') ;
-- 需求:查询员工表和部门表的所有信息
-- 使用隐式内连接
SELECT
t1.*,
t2.name
FROM
emp t1,
dept t2
WHERE
t1.dept_id = t2.id ; -- 部门编号和部门表id关联
-- 内连接查询已经不满足要求!
-- 左外连接:将左表的数据全部查询并且还有查询交集部分(连接条件) (推荐方式)
/*
select
字段列表
from
左表(表名1)
left outer join
右表(表名2)
on
连接条件
*/
SELECT
t1.*,
t2.name
FROM
emp t1
LEFT OUTER JOIN -- outer 可以省略
dept t2
ON
t1.dept_id = t2.id ;
SELECT
t1.*,
t2.name
FROM
emp t1
LEFT JOIN
dept t2
ON
t1.dept_id = t2.id ;
SELECT * FROM emp ;
-- 右外连接查询:将右边全部显示以及多个表的交集部分数据(连接条件)
/*
select
字段列表
from
左表(表名1)
right outer join
右表(表名2)
on
连接条件
*/
SELECT
t1.name,
t2.*
FROM
dept t1
RIGHT OUTER JOIN
emp t2
ON
t1.id = t2.dept_id ;
-- 多表查询之:子查询: select 嵌套select语句
/*
select
字段列表
from
表名1
where 表达式(<,<=,>=,>,=)
select
字段列表
from 表名...
*/
-- 三种情况
-- 单行单列
-- 单行多列
-- 多行多列
-- 需求:查询员工工资最高的员工信息
SELECT * FROM emp ;
-- 1)查询员工工资最高的是多少
SELECT
MAX(salary)
FROM
emp ;
-- 2)查询员工工资是10000的这个信息
SELECT
*
FROM
emp
WHERE
salary = 10000 ;
-- 简化:数学:a = 2 ; a+b = 2 + b ---代入!
SELECT
*
FROM
emp
WHERE
salary =
(SELECT
MAX(salary)
FROM
emp
) ;
-- 需求:查询员工工资低于平均工资的员工信息
-- 1)查询平均工资是多少
SELECT
AVG(salary) '平均薪资'
FROM
emp ;
-- 2)带条件查询工资低于6550的员工信息
SELECT
t1.name,
t1.gender,
t1.salary,
t1.join_date
FROM
emp t1
WHERE
salary <= 6550 ;
-- 一步走
SELECT
t1.*
FROM
emp t1
WHERE
t1.salary <=
(
SELECT
AVG(salary)
FROM emp
);
SELECT * FROM emp ;
2.JDBC
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
/**
* JDBC的基本使用:本质就是sun公司提供的一套接口规范:数据库厂商提供的驱动实现类
*
* 1)导包---mysql-connector-java-5.1.37-bin.jar
* 2)注册驱动
* 3)获取数据库连接对象
* 4)准备sql
* 5)通过数据库连接对象获取执行对象
* 6)执行sql语句
* 7)返回结果
* 8)释放资源
*/
public class JdbcDemo {
public static void main(String[] args) throws Exception {
//1)导入驱动jar包
//2)注册驱动
Class.forName("com.mysql.jdbc.Driver") ;
//3)获取数据库连接对象
//java.sql 类 DriverManager :驱动管理类(就是JDBC驱动服务)
//public static Connection getConnection(String url, String user,String password)
//url:统一资源定位符号:是链接的具体哪个数据库名
//user:数据库的用户名
//password:数据库的密码
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/mydb_05", "root", "123456") ;
//4)准备sql语句
//操作mydb_05里面账户表;account
String sql = "update account set balance = balance + 500 where id = 1" ;
//5)通过数据库连接对象Cononection获取执行对象java.sql.Statement:执行静态sql语句
//Statement createStatement():创建执行对象并将sql准备发送数据库中
Statement stmt = conn.createStatement() ;
//6)执行sql:执行对象Statement
//int executeUpdate(String sql)
//执行给定 SQL 语句,该语句可能为 INSERT、UPDATE 或 DELETE 语句
//7)返回结果:返回值:影响的行数
int count = stmt.executeUpdate(sql) ;
System.out.println("影响了"+count+"行");
//8)释放资源
stmt.close();
conn.close();
}
}
2.1jdbc中涉及相关的核心类以及核心接口的API
1. com.mysql.jdbc.Driver ---->class 驱动类
implements java.sql.Driver 接口 (驱动程序)
Class.forName("com.mysql.jdbc.Driver") ;为了保证向下兼容性(JDK6以前)
com.mysql.jdbc.Drvier----->这个类一加载,静态代码也会随之加载
static{
DriverManager.registerDriver(Driver driver) ---- 这里面已经注册过了
}
2.获取数据连接对象
核心类
DriverManager -------->驱动管理类----管理JDBC驱动程序服务!
成员方法
public static void registerDriver(Driver driver):注册驱动
public static Connection getConnection(
String url,
String user,
String password):获取数据库的连接对象
通过创建系统资源发送到数据库的一种url请求
参数1:
url:统一资源定位符
协议://域名或者ip地址:端口号/链接具体地址
jdbc:mysql://localhost:3306/数据库名称
参数2:用户名:root用户
参数3:密码
3.Connection---java.sql.Connection
与指定的数据库的一种会话!----通过系统资源获取
成员方法
有关事务管理相关的方法
void setAutoCommit(boolean autoCommit):设置数据库的提交方式 :
参数为true:表示自动提交
参数为false:表示禁用自动提交
void rollback():事务的回滚
void commit():事务的提交
与数据库执行对象相关方法
Statement createStatement():创建Statement对象,将指定sql发送到数据库中
PreparedStatement prepareStatement(String sql):将
类似于
insert into account values(?,?,?) ; sql语句先进行预编译
4.Statement ----java.sql.Statement
执行对象:执行静态sql语句
静态的sql语句
insert into account values(1,'张三',1000),(2,'李四',1000);
update account set balance = balance -500 where id = 1 ;
成员方法
int executeUpdate(String sql) : 通过Statement将静态sql语句发送到数据库中进行操作
执行增删该
ResultSet executeQuery(String sql):执行查询语句select...
select * from student ;
5.PreparedStatement ----java.sql.PreparedStatement:预编译对象
insert into account values(?,?,?) ;
int executeUpdate():对预编译对象中sql语句直接操作!
6.ResultSet ----java.sql.ResultSet:表示数据库结果集的数据表
成员方法
boolean next():判断下一行是否存在有效数据!
XXX getXXX(int columnIndex):根据列的索引值获取表中结果数据:索引值1开始
如果是第一列,则为1
....第二列,则为2
XXX getXXX(String columnLabel):根据列的名称获取
2.2手动jdbc工具类的封装-针对原生Jdbc的封装
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
/**
*
* 手动jdbc工具类的封装
* 针对原生Jdbc的封装
*/
public class JdbcUtils {
//成员变量的位置
public static String url = null ;
public static String user = null ;
public static String password = null ;
//提供一个属性
public static String driverClass = null ;
//提供一个静态代码块
//在加载JdbcUtils类的时候,静态代码中的内容优先执行
static {
try {
//创建一个属性集合类对象
Properties prop = new Properties() ;
//将jdbc.properties的配置文件内容加载到prop属性集合中
InputStream inputStream = JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties") ;
//load(Reader r)
//load(InputStream in)
prop.load(inputStream);
//System.out.println(prop);
//通过prop的键获取值
url = prop.getProperty("url") ;
user = prop.getProperty("user") ;
password = prop.getProperty("password") ;
driverClass = prop.getProperty("driverClass") ;
//注册驱动
Class.forName(driverClass) ;
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//构造方法私有化
private JdbcUtils() {}
//静态功能
//获取连接对象--封装
public static Connection getConnection() {
//需要通过驱动管理类获取 DriverManager
//三个参数需要放在配置文件 xx.properites----将三个参数:jdbc.properties
try {
Connection conn = DriverManager.getConnection(url, user, password);
return conn ;
} catch (SQLException e) {
e.printStackTrace();
}
return null ;
}
//关闭资源---封装
//针对DQL语句进行操作:释放资源
public static void close(ResultSet rs,Statement stmt,Connection conn) {
if(rs!=null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(stmt!=null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//针对DDL/DML:增删改 释放资源
public static void close(Statement stmt,Connection conn) {
close(null, stmt, conn);
}
}
2.2.1 jdbc.properties配置文件
url=jdbc:mysql://localhost:3306/mydb_05
user=root
password=123456
driverClass=com.mysql.jdbc.Driver
2.3使用jdbc完成基本dml删除语句
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
/**
* 使用jdbc完成基本dml删除语句
*/
public class JDBCDemo {
public static void main(String[] args) {
Statement stmt = null ;
Connection conn = null ;
try {
//1)导入jar包
//2)注册驱动
Class.forName("com.mysql.jdbc.Driver") ;
//3)获取数据库的链接对象
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/mydb_05",
"root",
"123456");
System.out.println(conn);
//4)准备sql语句
String sql = "delete from account where id = 1" ;
//5)通过连接对象获取执行对象
stmt = conn.createStatement() ;
//6)执行更新
int count = stmt.executeUpdate(sql) ;
if(count>0) {
System.out.println("删除成功,影响了"+count+"行");
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally {
//7)释放资源
if(stmt!=null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
2.4使用JDBC操作DDL语句在mydb_05数据中创建一张学生表
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
/**
* 使用JDBC操作DDL语句
* 在mydb_05数据中创建一张学生表
* 字段
* name
* age
* gender
* address
*/
public class JDBCDemo2 {
private static Connection conn;
private static Statement stmt;
public static void main(String[] args) {
try {
//1)导包
//2)注册驱动
Class.forName("com.mysql.jdbc.Driver") ;
//获取连接
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/mydb_05", "root", "123456");
//准备sql
String sql = "create table student("
+ "id int primary key auto_increment,"
+ "name varchar(10),"
+ "age int,"
+ "gender varchar(2),"
+ "address varchar(20)"
+ ");" ;
//String sql
//DML语句
//insert into...
//update 表名 set 字段 = 值 where 条件
//delete from 表名 where条件
stmt = conn.createStatement();
//执行更新
int count = stmt.executeUpdate(sql) ;
System.out.println(count);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally {
if(stmt!=null) {
try {
stmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(conn!=null) {
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
2.5操作DQL语句查询
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/**
* 使用JDBC
*
* 操作DQL语句查询
*/
public class jdbcDemo {
public static void main(String[] args) {
Connection conn = null ;
Statement stmt = null ;
ResultSet rs = null ; // 结果集
try {
//注册驱动
Class.forName("com.mysql.jdbc.Driver") ;
//获取连接
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/mydb_05",
"root",
"123456") ;
//准备sql语句
String sql = "select * from student" ;
//获取执行对象
stmt = conn.createStatement() ;
//执行查询
rs = stmt.executeQuery(sql) ;
//boolean next():来判断是否存在有效数据,返回值true:存在有效数据
//判断
/*
if(rs.next()) {
//获取数据
//通过列的索引值获取
//xxx getXXX(int columNum)
int id = rs.getInt(1) ; //id值//第一列
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"+age+"\t"+gender+"\t"+address);
}
if(rs.next()) {
//获取数据
//通过列的索引值获取
//xxx getXXX(int columNum)
int id = rs.getInt(1) ; //id值//第一列
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"+age+"\t"+gender+"\t"+address);
}
if(rs.next()) {
//获取数据
//通过列的索引值获取
//xxx getXXX(int columNum)
int id = rs.getInt(1) ; //id值//第一列
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"+age+"\t"+gender+"\t"+address);
}
*/
//加入循环改进while循环
/*
while(rs.next()) {
//获取数据
//通过列的索引值获取
//xxx getXXX(int columNum)
int id = rs.getInt(1) ; //id值//第一列
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"+age+"\t"+gender+"\t"+address);
}
*/
//方式2:获取数据
while(rs.next()) {
//通过列的名称获取数据
// ///xxx getXXX(String columName)
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"+age+"\t"+gender+"\t"+address);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally {
//释放资源
if(rs!=null) {
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(stmt!=null) {
try {
stmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(conn!=null) {
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
2.6加入封装好的jdbc工具类针对DML语句增删改
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import com.qf.utils.JdbcUtils;
/**
* 加入封装好的jdbc工具类针对DML语句
* 增删改
* DQL
* 查询
*/
public class JdbcDemo {
public static void main(String[] args) {
Connection conn = null ;
Statement stmt = null ;
try {
//1)获取连接对象
conn = JdbcUtils.getConnection() ;
//2)准备sql语句
String sql = "insert into student(name,age,gender,address) values('赵又廷',49,'男','西安市碑林区'),('朱亚文',38,'男','西安市碑林区')" ;
//3)获取执行对象
stmt =conn.createStatement() ;
//4)执行更新
int count = stmt.executeUpdate(sql) ;
if(count>0) {
System.out.println("影响了"+count+"行");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//释放资源
JdbcUtils.close(stmt, conn);
}
}
}
2.7 小题
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import com.qf.entity.Employee;
import com.qf.utils.JdbcUtils;
/**
* 需求:
* 现在有一个员工类:Employee
* 属性:
* 有员工编号id
* 员工姓名name
* 员工性别gender
* 员工工资salary
* 员工的入职日期join_date
* 需要查询mydb_05数据库下面的emp表,将查询的结果封装到员工类中
* 将员工类存储ArrayList<Employee>,遍历集合展示所有员工数据
* 分析:
* 1)创建一个实体类 Employee中属性(小写)需要和数据库中的表emp的字段名称对应
* 2)定义一个方法
* public ArrayList<Employee> findAll(){}
*
* 2.1)创建一个空的集合
* 2.2)使用封装的工具类:JdbcUtils工具类获取数据库连接
* 2.3)准备sql select * from emp ;
* 2.4)通过连接对象获取Statement对象 执行对象
* 2.5)执行查询 ResultSet executeQuery(String sql)
* 2.6)遍历ResultSet:结果集的数据表
* 2.7)创建员工类对象
* 2.8)从ResultSet获取每一条数据封装到Employee员工类中
* 2.9)将员工类添加到集合中
* 3)遍历ArrayList集合
*/
public class JdbcTest {
public static void main(String[] args) {
ArrayList<Employee> arrayList = findAll() ; //查询员工表的所有数据
//增强for
if(arrayList!=null) {
for(Employee emp :arrayList) {
System.out.println(emp.getId()+"\t"+
emp.getName()+"\t"+emp.getGender()+"\t"+emp.getSalary()+"\t"+
emp.getJoin_date());
}
}
}
public static ArrayList<Employee> findAll() {
Connection conn = null ;
Statement stmt = null ;
ResultSet rs = null ;
try {
//创建一个ArrayList<Employee>集合对象
ArrayList<Employee> list = new ArrayList<Employee>() ;
//声明一个Employee变量
Employee emp = null ;
//获取数据库的链接对象
conn = JdbcUtils.getConnection() ;
//准备sql语句
String sql = "select * from emp" ;
//获取执行对象
stmt = conn.createStatement() ;
//执行查询
rs = stmt.executeQuery(sql) ;
//遍历结果集
while(rs.next()) {
//创建员工类对象
emp = new Employee() ;
//获取数据
//通过列的名称获取数据
int id = rs.getInt("id") ;
String name = rs.getString("name") ;
String gender = rs.getString("gender") ;
int salary = rs.getInt("salary") ;
Date join_date = rs.getDate("join_date") ;
//转换:Date--SimpleDateFormart--->String
//格式化操作!
//封装员工类对象
emp.setId(id);
emp.setName(name);
emp.setGender(gender);
emp.setSalary(salary);
emp.setJoin_date(join_date);
//需要emp员工类对象添加到集合中
list.add(emp) ;
}
return list ;
} catch (SQLException e) {
e.printStackTrace();
}finally {
JdbcUtils.close(rs, stmt, conn);
}
return null;
}
}
2.8 PreparedStatement引入
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;
import com.qf.utils.JdbcUtils;
/**
* 需求:
* 键盘录入用户名和密码,模拟用户登录操作
* 后台---有一张user表:用户表
* 如果键盘录入的用户名和密码和数据库中user表中用户名和密码一致,登录成功!
* 否则,"用户名或者密码错误"
*
* 问题:
* 使用Statemet对象:存在严重问题:SQL注入: 不安全的行为
* select * from user where username = 'sdfsd' and password = 'a' or 'a' = 'a'
* 用户名和密码完全不一致,依然可以登录成功!
*
* Statement对象:
* 弊端
* 1)执行效率差
* 每一次发送sql语句之前,获取Statement
* executeUpdate(String sql)
* executeQuery(String sql)
* 2)存在安全漏洞:sql注入 存在字符串拼接导致的!
* 一旦后台被攻击,可以sql注入行为篡改数据!
*
*
* 提交执行效率以及防止sql注入
* sun公司提供了一个接口:
* PreparedStatement
* 将参数化的sql语句先进行预编译(在PreparedStatement对象中 内存中)
* 参数化的sql语句不存在硬编码的拼接!
*/
public class StatementTest {
public static void main(String[] args) {
//创建键盘录入对象
Scanner sc = new Scanner(System.in) ;
//提示并录入数据
System.out.println("请输入用户名:");
String username = sc.nextLine() ;
System.out.println("请输入密码:");
String password = sc.nextLine() ;
//调用方法
boolean flag= isLogin(username,password) ;
if(flag) {
System.out.println("恭喜您,登录成功!");
}else {
System.out.println("登录失败,您的用户名或者密码有误!");
}
}
private static boolean isLogin(String username, String password) {
Connection conn = null ;
Statement stmt = null ;
ResultSet rs = null ;
try {
//获取数据库的链接对象
conn = JdbcUtils.getConnection() ;
//准备sql
//通过用户名和密码查询用户---查询某一条件记录---如果有内容:存在
String sql = "select * from user where username = '"+username+"' and password = '"+password+"' " ;
System.out.println(sql);
//获取执行对象:Statement
stmt = conn.createStatement() ;
//执行查询
rs = stmt.executeQuery(sql) ;
return rs.next(); //有有记录:返回true
} catch (SQLException e) {
e.printStackTrace();
}finally {
JdbcUtils.close(rs, stmt, conn);
}
return false;
}
}
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;
import com.qf.utils.JdbcUtils;
/**
* 引入PreparedStaement (以后都用这个!)
*基本使用
*
*有效防止sql注入/可以提高开发效率
*/
public class PreparedStatementTest {
public static void main(String[] args) {
//创建键盘录入对象
Scanner sc = new Scanner(System.in) ;
//提示并录入数据
System.out.println("请输入用户名:");
String username = sc.nextLine() ;
System.out.println("请输入密码:");
String password = sc.nextLine() ;
//调用方法
boolean flag= isLogin(username,password) ;
if(flag) {
System.out.println("恭喜您,登录成功!");
}else {
System.out.println("登录失败,您的用户名或者密码有误!");
}
}
private static boolean isLogin(String username, String password) {
Connection conn = null ;
PreparedStatement stmt = null ; //预编译对象
ResultSet rs = null ;
try {
//获取数据库的链接对象
conn = JdbcUtils.getConnection() ;
//准备sql
//通过用户名和密码查询用户---查询某一条件记录---如果有内容:存在
//准备参数化的sql语句
//?:表示占位符号
String sql = "select * from user where username = ? and password = ?" ;
System.out.println(sql);
//获取预编译对象
//Connection
//PreparedStatement prepareStatement(String sql)
//将参数化的sql语句发送数据库进行预编译
stmt = conn.prepareStatement(sql) ;
//给占位符号赋值:参数赋值
//void setXXX(int parameterIndex,实际参数)
//参数1:?是第几个占位符
//参数2:实际参数
stmt.setString(1, username);
stmt.setString(2, password);
//执行查询/更新
//PreparedStatement:接口
//int executeUpdate()
//ResultSet executeQuery()
rs = stmt.executeQuery() ;
//执行查询
return rs.next(); //有有记录:返回true
} catch (SQLException e) {
e.printStackTrace();
}finally {
JdbcUtils.close(rs, stmt, conn);
}
return false;
}
}
2.9使用预编译对象PreparedStatement来将给员工表添加一条数据
package com.qf.jdbc_05;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.qf.utils.JdbcUtils;
/**
* 使用预编译对象PreparedStatement来将给员工表添加一条数据
* DML语句
* insert into 表名...
*/
public class PreparedStatementDemo {
public static void main(String[] args) {
Connection conn = null ;
PreparedStatement stmt = null ;
try {
//获取数据库连接对象
conn = JdbcUtils.getConnection() ;
//准备sql语句
//参数化 的sql
String sql =
"insert into emp (name,gender,salary,join_date) values(?,?,?,?)" ;
//获取预编译对象并将sql发送到数据库进行编译
stmt = conn.prepareStatement(sql) ;
//参数赋值
stmt.setString(1, "诸葛亮2");
stmt.setString(2, "男");
stmt.setInt(3, 12000);
// String s = "2020-11-10" ;
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd") ;
// Date date = sdf.parse(s) ;
//第三方工具:Convert接口---转换器:String---Date //Date---String
stmt.setString(4, "2011-11-10");
//执行更新
int count = stmt.executeUpdate() ;
System.out.println("影响了"+count+"行");
} catch (SQLException e) {
e.printStackTrace();
}finally {
JdbcUtils.close(stmt, conn);
}
}
}
3.连接池
连接池 :
* 连接对象可以重复利用(固定的 /可重用的)-----使用完毕之后会再次归还到连接池中
* 自动参与连接
*
* sun提供了接口 java.sql.DataSource:物理数据源的链接----代替了DriverManager工具(jdbc的一组服务)
* 成员方法
* Connection getConnection();
*
* 驱动类的厂商提供:
* c3p0核心jar包 源码包 --- 日志记录
* druid核心jar包 源码包
* dbcp核心jar包...
Statement和PreparedStatement的区别
执行对象
Statement操作的静态sql语句
DDL/DML语句
insert into concat values(1,'张三','13666668888','男','西安')
DQL语句 select * from concat where id = 1 ;
通过id查询一条信息 通过id查询联系人信息
public Concat findContcatById(int id)
通过连接对象获取Statement
Statement发送sql到数据库中,操作sql语句效率低,executeUpdate(String sql) executeQuery(String sql)
存在字符串拼接,造成sql注入
PreparedStatement:预编译对象
通过连接对象获取预编译对象的同时将参数化的sql发送数据库进行预编译!
相对Statement对象,执行效率高
能够有效防止sql注入
连接对象.prepareStatement(String sql)---->PreparedStatement
DDL/DML语句
insert into concat values(?,?,?,?,?) 占位符号全部英文
update concat set name = ? where id = ? ;
DQL语句 select * from concat where id = ? ;
通过setXXX(占位符的索引值,实际参数) 对占位符号进行赋值
3.1c3p0
c3p0连接池----相关的jar包
*
* 1)导入jar包
* c3p0-0.9.5.2.jar -核心jar包
* mchange-commons-java-0.2.12.jar c3p0的依赖包
* 2)需要将c3p0核心配置文件存储在src目录下 自动读取
* 两种方式
* c3p0.properties
* c3p0-config.xml ----- spring,springmvc,mybatis主流框架xml文件配置方式
*
*
* 3)配置文件中提了一些
* 基本参数
* driverClass:数据库驱动实现
* jdbcUrl 连接特定的数据库
* user用户名
* password 密码
*
*
* 连接池的参数信息
* initialPoolSize :初始化连接数量
* maxPoolSize:最大连接数量
* checkoutTimeout:超时时间 单位为毫秒 如果超过最大连接数量,在指定时间连接不上,就会出现问题了
import java.sql.Connection;
import java.sql.SQLException;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class C3p0Demo2 {
public static void main(String[] args) throws SQLException {
//创建c3p0连接池对象
ComboPooledDataSource dataSource = new ComboPooledDataSource() ;
//获取连接对象
Connection conn = null ;
for(int x = 1 ; x <=11 ; x ++) {
//获取连接对象
if(x==3) {
//释放一个
conn.close(); //close不是直接释放,将conn对象归还到连接池中
}
conn = dataSource.getConnection() ;
System.out.println(conn+":"+x);
}
}
}
3.2Druid
import java.io.InputStream;
import java.sql.Connection;
import java.util.Properties;
import javax.sql.DataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
/**
* --1) 导入核心jar包
druid-1.0.9.jar --- DruidDataSource
2)在src目录执行核心配置文件
jdbc.properites (名称可以随便起)
有一些基本参数信息
连接池的信息
druid里面内置的属性名字
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb_02
username=root
password=123456
连接池的默认配置信息
initialSize=5 初始化连接数量5
maxActive=10 最大激活数量10个
maxWait=3000 最大的等待时间
3)获取连接对象呢?
使DruidDataSourceFactory:德鲁伊的物理数据源的工厂类
静态方法
public static DataSource createDataSource(Properties properties){}
创建物理数据源对象
*/
public class DruidDemo {
public static void main(String[] args) throws Exception {
//测试下
//创建属性集合类对象
Properties prop = new Properties() ;
//读取src下面的druid.properties文件
ClassLoader classLoader = DruidDemo.class.getClassLoader() ;
InputStream inputStream = classLoader.getResourceAsStream("druid.properties") ;
//将文件内容加载到属性集合类中
prop.load(inputStream);
System.out.println(prop);
//druid连接池获取连接对象
//DruidDataSourceFactory
// public static DataSource createDataSource(Properties properties){}
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop) ;
//获取连接对象
Connection conn = dataSource.getConnection() ;
System.out.println(conn);
}
}
3.2.1DruidUtils
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import javax.sql.DataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
/**
* 封装工具类
*
* 1)使用连接池获取连接对象 ----Druid连接池
* DruidDataSourceFactory.createDataSource(Properties prop)--->javax.sql.DataSource
*
* 2)封装获取连接的方法
* mygetConnection()-----DataSource对象可以调用getConnection()
* 3)释放资源
* ...
*/
public class MyJdbcUtils {
//成员位置声明
private static DataSource ds ;
private MyJdbcUtils() {}
static {
try {
//创建一个属性集合类对象
Properties prop = new Properties() ;
//读取druid.properties 核心配置文件
InputStream inputStream = MyJdbcUtils.class.
getClassLoader().getResourceAsStream("druid.properties") ;
//加载到prop
prop.load(inputStream);
//通过Druid连接池提供 的工厂类创建物理数据源DataSource
ds = DruidDataSourceFactory.createDataSource(prop) ;
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
//获取数据库连接
public static Connection getConnection() {
Connection conn = null ;
try {
conn = ds.getConnection() ;
return conn ;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null ;
}
//获取DataSource的方法
public static DataSource getDataSource() {
return ds;
}
//释放资源的方法
public static void close(ResultSet rs,PreparedStatement stmt,Connection conn) {
if(rs!=null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(stmt!=null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void close(PreparedStatement stmt,Connection conn) {
close(null, stmt, conn);
}
//开启事务
/*
public static void startTransaction(Connection conn) {
if(conn!=null) {
try {
conn.setAutoCommit(false);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
*/
3.2.2druid.propertiees配置文件
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb_05
username=root
password=123456
initialSize=5
maxActive=10
maxWait=3000
3.3使用单元测试
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
//导入junit单元测试的注解Test
import org.junit.Test;
public class CalcTest2 {
//使用单元测试
/**
* 1)定义一个方法:没有任何形式参数没有具体返回值类型
* 2)@Test
*/
@Test
public void test1() {
//针对计数器类的某个功能测试
//创建计算器类对象
Calc c = new Calc() ;
int sum = c.add(3, 2) ;
System.out.println(sum);
// Assert:断言 :期望值和实际值是否匹配,如果不匹配 单元测试失败!
//Assert.assertEquals(expected, actual);
//测试数组中一些数据
}
@Test
public void test2() {
//使用断言Assert测试
//assertEquals(expected, actual);
//创建计算器类对象
Calc c = new Calc() ;
int result = c.add(1, 2) ;
System.out.println(result);
//使用断言
//参数1:期望值
//参数2:实际值
Assert.assertEquals(3, result);
}
@Before //在执行单元测试之前优先执行这个方法
//环境的加载 /某些数据的初始化
public void init() {
System.out.println("数据初始了...");
}
@After//在执行单元测试方法之后执行
//处理临时数据 释放资源
public void destory() {
System.out.println("临时数据处理完毕...");
}
}
3.4DbUtils_工具类
apache提供的开源类库:工具类 对jdbc简单的封装
commons-dbutils-1.7.jar 核心jar包
1)导入包
2)执行对象:
QueryRunner
ResultSetHandler:处理程序 接口
实现类
需要将查询某条记录封装成对象 :BeanHandler<?>
需要将查询的多条记录(查询所有)封装List集合对象:BeanListHandler<?>
查询的单行单列的数据:查询总记录数/....
ScalarHandler<>
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import javax.sql.DataSource;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
/**
* 封装工具类
*
* 1)使用连接池获取连接对象 ----Druid连接池
* DruidDataSourceFactory.createDataSource(Properties prop)--->javax.sql.DataSource
*
* 2)封装获取连接的方法
* mygetConnection()-----DataSource对象可以调用getConnection()
* 3)释放资源
* ...
*
*
* @author zhangyang
*
*/
public class MyJdbcUtils {
//成员位置声明
private static DruidDataSource ds ; //直接使用具体的子实现类:DruidDataSource
private MyJdbcUtils() {}
static {
try {
//创建一个属性集合类对象
Properties prop = new Properties() ;
//读取druid.properties 核心配置文件
InputStream inputStream = MyJdbcUtils.class.
getClassLoader().getResourceAsStream("druid.properties") ;
//加载到prop
prop.load(inputStream);
//通过Druid连接池提供 的工厂类创建物理数据源DataSource
ds = (DruidDataSource) DruidDataSourceFactory.createDataSource(prop) ;
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
//获取数据库连接
public static Connection getConnection() {
Connection conn = null ;
try {
conn = ds.getConnection() ;
return conn ;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null ;
}
//获取DataSource的方法
public static DataSource getDataSource() {
return ds;
}
//释放资源的方法
public static void close(ResultSet rs,PreparedStatement stmt,Connection conn) {
if(rs!=null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(stmt!=null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void close(PreparedStatement stmt,Connection conn) {
close(null, stmt, conn);
}
//开启事务
/*
public static void startTransaction(Connection conn) {
if(conn!=null) {
try {
conn.setAutoCommit(false);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
*/
public static void main(String[] args) {
DataSource ds = MyJdbcUtils.getDataSource() ;
System.out.println(ds);
Connection conn = MyJdbcUtils.getConnection() ;
System.out.println(conn);
}
}
配置文件
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb_05
username=root
password=123456
initialSize=5
maxActive=10
maxWait=3000
3.4.1Dao
import java.sql.SQLException;
import java.util.List;
import com.mysql.jdbc.SQLError;
import com.qf.entity.User;
/**
* 针对用户数据库访问接口层
*/
public interface UserDao {
//dao层添加用户的操作
int addUser(User user) throws SQLException;
//删除用户操作
void deleteUser(int id);
//修改用户
void updateUser(User user);
//通过id查询用户
User getUserById(int id);
//查询所有用户
List<User> getAll();
//总记录数
int getCount();
}
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import com.qf.dao.UserDao;
import com.qf.entity.User;
import com.qf.utils.MyJdbcUtils;
//数据库访问的接口实现层
public class UserDaoImpl implements UserDao {
/**
* QueryRunner两个通用方法
* update(sql,...):更新 ----int 影响了多少行
* 如果当前sql语句存在参数
* update(String sql,Object...paramerters):参数2:是对实际参数进行赋值
* query(sql,...):查询 ---- 根据业务需求:
* 将某一条记录封装到对象中:BeanHandler类
*/
@Override
public int addUser(User user) throws SQLException {
//创建执行对象
QueryRunner qr = new QueryRunner(MyJdbcUtils.getDataSource()) ;
//准备sql语句:必须是参数化sql
String sql = "insert into user(name,gender,address,phone) values(?,?,?,?)" ;
//执行更新
int count = qr.update(sql,
user.getName(),
user.getGender(),
user.getAddress()
,user.getPhone());
return count ;
}
@Override
public void deleteUser(int id) {
}
@Override
public void updateUser(User user) {
}
@Override
public User getUserById(int id) {
return null;
}
@Override
public List<User> getAll() {
try {
//创建执行对象
QueryRunner qr = new QueryRunner(MyJdbcUtils.getDataSource()) ;
//准备sql
String sql = "select * from user" ;
//执行查询
// query(String sql,RequesltSetHandler<?> rs,Object...params)
//参数1:sql语句
//参数2:结果集的处理程序:接口
//参数3:当前sql语句的参数
//BeanListHandler<?>(Class<?> claszz)
List<User> list =
qr.query(sql, new BeanListHandler<User>(User.class)) ;
return list;
} catch (SQLException e) {
e.printStackTrace();
}
return null ;
}
@Override
public int getCount() {
return 0;
}
}
3.4.2Service
package com.qf.service;
import java.sql.SQLException;
import java.util.List;
import com.qf.entity.User;
/**
* 针对用户操作的业务接口层
*/
public interface UserService {
//用户添加操作
public int add(User user) throws SQLException ;
//删除用户
public void delete(int id) ;
//修改操作
public void update(User user) ;
//查询:
//通过id查询某个用户
public User findUserById(int id) ;
//查询所有
public List<User> findAll() ;
//查询总记录数
public int getTotalCount() ;
}
import java.sql.SQLException;
import java.util.List;
import com.qf.dao.UserDao;
import com.qf.dao.impl.UserDaoImpl;
import com.qf.entity.User;
import com.qf.service.UserService;
/**
* 针对用户操作的业务接口实现层
*/
public class UserServiceImpl implements UserService {
//需要调用dao层方法
UserDao ud = new UserDaoImpl() ;
@Override
public int add(User user) throws SQLException {
return ud.addUser(user) ;
}
@Override
public void delete(int id) {
ud.deleteUser(id) ;
}
@Override
public void update(User user) {
ud.updateUser(user) ;
}
@Override
public User findUserById(int id) {
return ud.getUserById(id);
}
@Override
public List<User> findAll() {
return ud.getAll();
}
@Override
public int getTotalCount() {
return ud.getCount();
}
}
3.4.3Entity
/**
* 用户实体类
*
*/
public class User {
//提供属性:需要和数据库表中字段对应
private int id ;
private String name ;
private String gender ;
private String address ;
private String phone ;
public User() {
super();
// TODO Auto-generated constructor stub
}
public User(int id, String name, String gender, String address, String phone) {
super();
this.id = id;
this.name = name;
this.gender = gender;
this.address = address;
this.phone = phone;
}
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 String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", gender=" + gender + ", address=" + address + ", phone=" + phone
+ "]";
}
}
3.4.4Test
import java.sql.SQLException;
import java.util.List;
import org.junit.Test;
import com.qf.entity.User;
import com.qf.service.UserService;
import com.qf.service.impl.UserServiceImpl;
public class UserTest {
@Test
public void testAddUser() throws SQLException {
//调用业务层
UserService us = new UserServiceImpl() ;
User user = new User() ;
user.setName("李文擘");
user.setGender("男");
user.setAddress("软件园");
user.setPhone("13666666666");
int count = us.add(user) ;
System.out.println("影响了"+count+"行");
}
@Test
public void testFindAll() {
//调用业务层
UserService us = new UserServiceImpl() ;
List<User> list = us.findAll() ;
if(list!=null) {
for(User user:list) {
System.out.println
(user.getId()+"\t"+user.getName()+"\t"
+user.getGender()+"\t"+user.getAddress()
+"\t"+user.getPhone());
}
}
}
}
4.Html
前端三剑客
HTML
Hyper Text Markup Language:超文本标记语言
普通记事本----以.html保存
工具:
webStrom/Hbuilder/Hbuilder-x
超文本标记----->
针对字体,图片,音频,视频进行标记
CSS
Js(JavaScript)
Servlet :Java服务器端程序的开发
4.1常用的HTML文本标签
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>文本标签</title>
<!--
常用的HTML文本标签
标签标题:h1-h6
段落标签:p
段落缩进标签:blockquote
水平线标签:hr
换行标签:br
滚动标签:marquee
上下标:sup和sup
原样输出标签:pre
列表标签:
有序列表 :ol li
无序列表:ul li
块标签div
行内标签 span
加粗标签:strong
斜体标签:em
字体标签:font
居中标签:center
-->
</head>
<body>
<!-- 段落标签p :闭合标签 -->
<p>
张冲很帅张冲很帅张冲很帅张冲很帅张冲很帅张冲很帅张冲很帅
</p>
<p>
this is a first p
</p>
<!-- 段落缩进标签 -->
<blockquote>
xxx背景,xxx
</blockquote>
<!-- 水平线标签hr-->
<hr />
<!-- 标题标签h1-h6 -->
<h1>我和我的祖国</h1>
<h2>我和我的祖国</h2>
<h3>我和我的祖国</h3>
<h4>我和我的祖国</h4>
<h5>我和我的祖国</h5>
<h6>我和我的祖国</h6>
<!-- <h7>我和我的祖国</h7> -->
<!-- 换行标签 -->
hello,html <br />
hello,html2
<!--
滚动标签:marquee :没有指定滚动方向:默认从右到左
behavior:滚动行为(方式)
slide:滚动到某一边停止
alternate:来回滚动(两端)
scroll:穿梭滚动
direction:滚动方向
scrollamount:滚动速度
-->
<marquee behavior="scroll" direction="right"
scrollamount="20" bgcolor="pink">尼古拉斯-高圆圆</marquee>
<!-- 原样输出标签pre -->
<pre>
function checkUsername(){
alert("hello") ;
}
</pre>
<!-- 上下标标签 -->
数学表达式 X^2 X<sup>2</sup><br />
化学公式: H2O H<sub>2</sub>O
<!-- 列表标签 -->
<!-- 有序列表 ol li -->
你喜欢的女明星?
<ol type="I">
<li>高圆圆</li>
<li>张佳宁</li>
<li>王晓晨</li>
</ol>
<!-- 无序列表 ul li -->
您喜欢的足球明星?
<ul type="square">
<li>c罗</li>
<li>姆巴佩</li>
<li>克劳泽</li>
</ul>
<!-- 粗体和斜体标签 -->
<strong>中国</strong>
<em>沁园春</em>
<!-- 字体标签 -->
<center><!-- 居中标签 -->
<font color="deeppink" size="5">川普</font>
</center>
<!-- 块标签div
div+css 层级布局
div1
div2
块标签占一行内容的:div1/div2属于块标签中文本内容
-->
<div>div1</div>
<div>div2</div>
<!-- 行内标签 -->
<span>span1</span>
<span>span2</span>
</body>
</html>
4.2图像标签
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>图像标签</title>
<!--
图像标签img
src :连接到图片资源地址
width:指定图片的宽度
height:指定图片的高度
单位:指定像素 px
指定百分比:占当前 50% 宽度和高度占整个分辨率的百分比
title:当鼠标悬浮图片上的提示文字
alt:替换文本
图片资源失效的时候,起作用
如果一个html页面中有3个图片(网络图片),请求某个服务器,会发送几次请求!
4个请求
1)请求页面 http://域名:端口号/当前html资源文件地址
2)每一个图片src---加载图片
都会发送一次请求
-->
</head>
<body>
<h3>this is img target</h3>
<!--
img-->
<a name="img"></a>
<img src="img/1.jpg" title="这是小米手机" width="100%" height="100%" alt="小米手机" /><br />
<!-- <img src="img/2.jpg" /> -->
</body>
</html>
4.3超链接标签
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>超链接标签</title>
<!--
超链接
a标签
href属性:跳转到资源地址
本地资源地址/网络资源地址/指定的服务器地址
不指定target属性:默认当前窗口直接打开地址
_blank:新建窗口打开资源文件
_self(默认值):当前窗口直接打开
http协议的执行流程:
在C:\Windows\System32\drivers\etc\hosts文件
hosts记录了网站域名以及ip地址
127.0.0.1 localhost
如果hosts文件有访问的域名并且对应ip 直接本地打开文件
如果找不到,调用网卡来联网操作----DNS服务器(网络运营商)
仓库
ip1 域名1
ip2 域名2
ip3 域名3
10.12.156.66 www.baidu.com
直接访问百度服务器----回显百度首页
thunder://:迅雷协议
如果本地有客户端软件--直接打开迅雷软件
mailto :邮件协议
超链接的应用场景:
1)链接后台地址/本地资源地址 url :统一资源定位符
2)锚链接来使用
在同一个html页面的使用
a)打锚点: 定义一个标记位置
<a name="锚点名称"></a>
b)创建一个跳转链接
<a href="#锚点名称">跳转</a>
不同html页面的使用
a)在另一个页面的某个位置打锚点: 定义一个标记位置
b)在当前页面上创建跳转标记
<a href="跳转页面地址#锚点名称">跳转</a>
-->
</head>
<body>
<h3>this is a target</h3>
<!-- 从下面跳转上来 -->
<a name="top"></a>
<!-- 2)创建跳转链接 -->
<a href="#foot">[跳转底部]</a><br />
<a href="01_图像标签.html#img" target="_blank">点击跳转</a><br />
<a href="http://www.baidu.com">[跳转到百度]</a><br />
<a href="http://www.movie.com">普通通道 <<八佰>></<></a><br />
<a href="thunder://www.movie.com">高速通道<<八佰>></<></a><br />
<a href="http://localhost:8080/Pay_/order/confirm">[连接到支付宝支付地址]</a>
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
<br/><br/><br/><br/><br/><br/><br/><br/>
<br/><br/><br/><br/>
<!-- 创建标记 -->
<a name="foot"></a>
<a href="#top"><font color="red">[跳转顶部]</font></a>
<center>2020-11-12~2021-11-12 版权所有<sup>©</sup></center>
</body>
</html>
4.4表格标签
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>表格标签</title>
<!--
table
属性:border:边框大小
width:表格宽度
height:表格的高度
align:表格在浏览器的位置
左 中 右
cellspacing:设置表格边框线和单元格之间的距离
cellpadding:设置单元格和单元格的距离
子标签
caption:表格的标题标签
tr:行标签
td:单元格
th:表头标签:自动居中并且适当加粗
单元格的合并:
合并行:rowspan 占了几个单元格
合并列:colspan 占了几个单元格
-->
</head>
<body>
<table border="1" width="500px" cellpadding="0" height="500px"
align="center" bgcolor="pink" cellspacing="0">
<caption>xxx学习的成绩管理</caption>
<!-- 三行,每一行中有3个单元格 -->
<tr>
<th>学号</th>
<th>姓名</th>
<th>性别</th>
<th>数学成绩</th>
<th>英语成绩</th>
<th>平均分</th>
</tr>
<tr align="center">
<td>1</td>
<td>张三</td>
<td>男</td>
<td rowspan="2">90</td>
<td>78</td>
<td>80</td>
</tr>
<tr align="center">
<td>2</td>
<td>李四</td>
<td>女</td>
<!-- <td>89</td> -->
<td>100</td>
<td>90</td>
</tr>
<tr align="center">
<td>3</td>
<td>王五</td>
<td>男</td>
<td colspan="2">89</td>
<!-- <td>65</td> -->
<td>70</td>
</tr>
</table>
</body>
</html>
4.5表格标签2
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>表格标签2</title>
</head>
<body>
<table border="1" width="500px" cellpadding="0" height="500px"
align="center" bgcolor="pink" cellspacing="0">
<caption>xxx学习的成绩管理</caption>
<!-- 三行,每一行中有3个单元格 -->
<tr>
<th>学号</th>
<th>姓名</th>
<th>性别</th>
<th>数学成绩</th>
<th>英语成绩</th>
<th>平均分</th>
</tr>
<tr align="center">
<td>1</td>
<td>张三</td>
<td>男</td>
<td rowspan="2">90</td>
<td>
<table border="1" cellspacing="0" width="100%" height="100%">
<tr>
<td>11</td>
<td>12</td>
</tr>
<tr>
<td>21</td>
<td>22</td>
</tr>
<tr>
<td>31</td>
<td>32</td>
</tr>
</table>
</td>
<td>80</td>
</tr>
<tr align="center">
<td>2</td>
<td>李四</td>
<td>女</td>
<!-- <td>89</td> -->
<td>100</td>
<td>90</td>
</tr>
<tr align="center">
<td>3</td>
<td>王五</td>
<td>男</td>
<td colspan="2">89</td>
<!-- <td>65</td> -->
<td>70</td>
</tr>
</table>
</body>
</html>
4.6 表单标签1
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>表单标签1</title>
<!--
表单标签form
属性
action: url 本地地址/后台地址
method:提交方式
常用的get/post
应用场景
注册
用户填写基本信息---前台校验------提交到后台的地址
查询当前用户是否存在,如果不存在用户才能注册!
登录
输入用户名和密码,在后台查询数据库中是否存在这个用户名和密码
存在,才可以登录;没有注册,先要注册!
get方式和post方式的区别?
get方式:
1)直接将数据提交url地址(地址栏上)
后台地址?username=zhangsan&password=123
2)不适合提交隐私数据
3)由于是提交在地址栏上,它提交的数据大小有限制
Post方式
1)不会将用户数据提交在地址栏上
存在 请求头下面
实体内容
form data
username=xxx&password=123456
提交方式:get/post 密码数据---使用MD5加密/springSecurity
123456 md5
2)相当于get方式,相对安全
3)它不是直接提交在地址栏上,提交的数据大小没有限制!
-->
</head>
<body>
<h3>this is a form target</h3>
<form action="server.html" method="post">
<!--
value:输入框的默认值
placeholder:h5属性存在效果:输入内容,自动获取焦点
登录/注册:表单项中必填的属性:name
name属性:给系统后台写的内容
-->
用户名:<input type="text" placeholder="请输入用户名" name="username" /><br />
密 码:<input type="password" name="password" placeholder="请输入密码"><br />
<input type="submit" value="注册" />
</form>
</body>
</html>
4.7表单标签2
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>表单标签2</title>
<!--
常见的表单子项
input标签
type="text" 文本输入框
type="password" 密码输入框
type="hide" name="id" 隐藏域: 没有效果,可以携带数据
type="date" 日期组件
type="radio" 单项按钮
type="checkbox"复选框
type="file" 文件上传
type="submit" 提交按钮
type="reset" 重置按钮
type="button" value="单击按钮"
select标签 :下拉菜单
子标签:option:下拉选项
textarea:文本域
书写文字描述
按钮相关的
button标签 文本内容就是当前按钮的名称
-->
</head>
<body>
<form action="server.html" method="get">
<!-- name属性必填-->
用户名:<input type="text" placeholder="请输入用户名" name="username" /><br />
密码:<input type="password" placeholder="请输入密码" name="password" /><br />
<input type="hidden" name="id" /><br />
出生日期:<input type="date" name="birthday" /><br />
用户邮箱:<input type="email" name="email" /><br />
电话号码:<input type="tel" name="phone" /><br />
<!--
同一组类型信息:指定相同的name属性:
checked="checked" 选中的状态
-->
性别:
<input type="radio" name="gender" checked="checked" value="男" />男
<input type="radio" name="gender" value="女" />女
<br/>
爱好:
<input type="checkbox" name="hobit" value="足球" />足球
<input type="checkbox" name="hobit" value="篮球" />篮球
<input type="checkbox" name="hobit" value="lol" />lol
<input type="checkbox" name="hobit" value="乒乓球" />乒乓球
<br />
文件上传:
<input type="file" name="file" /><br />
所在省份:
<select name="pro">
<option>请选择</option>
<option>陕西省</option>
<option>山西省</option>
<option>广东省</option>
</select>
<br />
自我描述:
<textarea rows="5" cols="20" name="text">
自我介绍...
</textarea>
<br />
按钮:
<input type="button" value="点我试试"/><br />
<!-- <button>点击</button> -->
<br />
<input type="submit" value="注册" /> <input type="reset" />
</form>
</body>
</html>
4.8格式优雅的表单
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>格式优雅的表单</title>
<!--
表单标签嵌套表格标签
css代码
-->
<style>
/* table{
background-image: url(img/2.jpg);
background-repeat: no-repeat;
} */
</style>
</head>
<body>
<form action="#" method="get">
<table align="center" width="500px" height="500px" >
<tr align="center">
<td>用户名</td>
<td>
<input type="text" name="username" />
</td>
</tr>
<tr align="center">
<td>密码</td>
<td>
<input type="passoword" name="pwd" />
</td>
</tr>
<tr align="center">
<td>性别</td>
<td>
<input type="radio" value="男" name="gender" />男
<input type="radio" value="女" name="gender" />女
</td>
</tr>
</table>
</form>
</body>
</html>
4.9框架标签
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>框架标签</title>
<!--
frame标签:框架标签
一个frame中包含一个html页面
如果整个xx系统组成可能很多html页面组成---使用frameset框架集标签
frameset框架集标签
属性:
rows
cols
-->
</head>
<frameset rows="20%,*,10%">
<frame src="header.html" />
<frameset cols="15%,*">
<frame src="menu.html" />
<frame src="main.html" name="main" />
</frameset>
<frame src="footer.html" />
</frameset>
<!-- <body>
</body> -->
</html>
5.CSS
5.1CSS选择器
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>CSS选择器</title>
<style>
/*标签选择器*/
/*
div{
font-size: 20px ;
color: red;
}
*/
/*class选择器*/
/*
.ch1{
font-size: 30px;
color: green;
}
*/
/*id选择器
标签中id属性值不能同名,必须唯一
*/
/*
#d1{
font-size: 36px;
color: blue;
}
*/
/*并集选择
选择器,选择器2{ //控制多个标签
css样式代码
}
*/
/*
#d1,#d2{
font-size: 35px;
color: blue;
/*文本修饰*/
/*
text-decoration: underline;
}
*/
/*交集选择器---后代选择器
选择器1 选择器2{
css样式代码;
}
*/
/*
#d1 span{
font-size: 20px;
color: greenyellow;
}
*/
/*通用选择器
*:通配符
*{
css样式代码
}
*/
*{
color:red ;
}
</style>
</head>
<body>
<div id="d1" class="ch1">
<span>
span1
<span>span2标签</span>
</span>
</div>
<div id="d2">div2</div>
<div>div3</div>
<span>span标签</span>
</body>
</html>
5.2伪类选择器—锚伪类 — 超链接
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>伪类选择器---锚伪类 --- 超链接</title>
<!--
描述标签状态
link状态:鼠标没有访问的状态
hover:鼠标经过标签状态
active:激活状态 鼠标点击但是没有松开的状态
visited:已经的访问过的:点击后松开的状态
格式
选择器:状态{
css样式代码
}
-->
<style>
/*没有访问过的状态*/
a:link{
font-size: 20px;
color: red;
}
/*访问过的状态,点击了并松开了 visited*/
a:visited{
font-size: 20px;
color: darkgray;
text-decoration: none;
}
/*鼠标经过状态:hover*/
a:hover{
font-size: 25px;
color: green;
/*文本修饰*/
text-decoration: none;
}
/*鼠标激活状态:点击但是没有松开的状态 active*/
a:active{
font-size: 30px;
color: blue;
text-decoration: underline;
}
</style>
<!--
提示:在 CSS 定义中,a:hover 必须被置于 a:link 和 a:visited 之后,才是有效的。
提示:在 CSS 定义中,a:active 必须被置于 a:hover 之后,才是有效的。
-->
</head>
<body>
<a href="01_CSS选择器.html">点击跳转</a>
</body>
</html>
5.3伪类练习
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test</title>
<!--
写一个三行三列的表格,鼠标经过每一行背景色变成蓝色
提示:
CSS背景样式
background-color:blue;
-->
<style>
table tr:hover{
background-color: blue;
}
tr td:hover{
/* 变成小手样式*/
cursor: pointer;
}
</style>
</head>
<body>
<table border="1px" width="500px" height="500px" align="center"
cellspacing="0">
<tr align="center">
<td>1</td>
<td>张三</td>
<td>20</td>
</tr>
<tr align="center">
<td>2</td>
<td>李四</td>
<td>30</td>
</tr>
<tr align="center">
<td>3</td>
<td>王五</td>
<td>26</td>
</tr>
</table>
</body>
</html>
5.4CSS文本属性
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS文本属性</title>
<style>
body{
/*color:设置文本颜色*/
color: red;
/*direction:设置文本方向:
默认值:ltr*/
direction: ltr;
/*line-height:设置行高 :行间距*/
/* line-height: 5px; */
/*letter-spacing:字符间距*/
letter-spacing: 10px;
/*设置的对齐方式 text-align*/
text-align: center;
/*text-decoration:设置文本修饰
none:默认值
line-through:中划线
overline:上划线
underline:下划线
*/
text-decoration:none;
/* word-spacing:单词间距
系统默认两个字组成一个单词
*/
word-spacing: 10px;
}
</style>
</head>
<body>
今天 天气 不错!
</body>
</html>
5.5CSS字体属性
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS字体属性</title>
<style>
body{
/*font-family :字体系列
是字体库中的有字体
*/
/*
font-family: "楷体";
*/
/*font-size:字体大小*/
/*
font-size: 30px;
*/
/*font-style:字体风格
默认值:normal :正常的字体
*/
/*
font-style: italic;
*/
/* font-style: oblique; */
/*font-weight:设置字体的粗细程度
bold 等价700px 适当加粗
*/
/*
font-weight: bold;
*/
/*
font字体的简写属性:将所有的字体属性在声明中定义
font:font-style font-weight font-size font-family
*/
font:italic bold 40px "楷体";
}
</style>
</head>
<body>
中国
</body>
</html>
5.6CSS背景属性
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS背景属性</title>
<style>
body{
/*背景颜色:background-color*/
/*
background-color: darkgray;
*/
/*background-image:设置图像为背景*/
/*
background-image: url(img/高圆圆.jpg);
*/
/*background-repeat:设置图像是否重复以及如何重复
repeat:水平方向/垂直方向重复
repeat-x:水平方向重复
repeat-y:垂直方向重复
no-repeat:不重复
*/
/* background-repeat: no-repeat; */
/*
如果设置图像不重复,默认的位置 top left
backgroun-position:top left
图像的位置
top
center
bottom
图像放置在浏览器的位置
left
center
right
*/
/* background-position: top left; */
/*
背景的简写属性:background
background:background-color background-position
background-repeat background-image
*/
background: red top center no-repeat url(img/高圆圆.jpg);
}
</style>
</head>
<body>
</body>
</html>
5.7CSS列表
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS列表</title>
<style>
ul{
/*list-style-type :设置列表前面的标记图形*/
/* list-style-type: none; */
/*list-style-image:自定义图形*/
/* list-style-image: url(img/start.jpg); */
/*list-style简写属性
list-tyle:list-style-type list-style-image
*/
list-style: none url(img/start.jpg);
}
</style>
</head>
<body>
你喜欢的人?
<ul type="disc">
<li>高圆圆</li>
<li>文章</li>
<li>朱亚文</li>
</ul>
</body>
</html>
5.8CSS表格属性
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS表格属性</title>
<style>
table{
/*border-collapse :设边框和单元之间空隙
指定为collapse
*/
border-collapse: collapse;
}
</style>
</head>
<body>
<table border="1px" width="500px" height="500px" align="center">
<tr align="center">
<td>1</td>
<td>张三</td>
<td>20</td>
</tr>
<tr align="center">
<td>2</td>
<td>李四</td>
<td>30</td>
</tr>
<tr align="center">
<td>3</td>
<td>王五</td>
<td>26</td>
</tr>
</body>
</html>
5.9CSS边框
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS边框</title>
<!--
边框属性:
边框的宽度,颜色,样式
-->
<style>
#d1{
/*边框有四个边:给四个边分别设置颜色
注意事项:
1) 某个边框没有设置颜色,宽度或者样式,它会补齐对边的颜色,宽度以及样式
2)默认的方向:边框的颜色/边框的宽度/边框的样式:上 右 下 左
border-top-color
border-left-color
border-right-color
border-bottom-color
*/
/*
border-top-color: #F00;
border-left-color: #00F;
border-right-color: #0F0;
border-bottom-color: #c90;
*
/*边框颜色的简写属性*/
/* border-color: #F00; */
/*
边框的宽度:四个边框的宽度大小
border-top-width
border-left-width
border-right-width
border-bottom-width
*/
/* border-width: 10px; */
/*
border-top-width: 10px;
border-left-width: 20px;
border-right-width: 30px;
border-bottom-width: 40px;
*/
/*
边框的四个边要想显示出来必须设置
边框的样式属性:必须存在
border-top-style
border-left-stylee
border-rigth-style
border-bottom-style
*/
/*
border-top-style: solid;
border-left-style: double;
border-right-style: dotted;
border-bottom-style: dashed;
*/
/*边框样式的简写属性*/
/* border-style: solid; */
/*边框的简写属性:
border:border-width border-style border-color
*/
border:5px solid #000;
width: 100px;
height: 100px;
}
</style>
</head>
<body>
<div id="d1">div1</div>
</body>
</html>
5.10>CSS浮动
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS浮动</title>
<style>
#dl1{
width: 200px;
height: 200px;
border:1px solid #000 ;
background-color: #F00;
/*
浮动属性:float
值:left:左浮动 right:有浮动
一旦元素设置了浮动属性,就会脱离文档流
*/
float:left;
}
#dl2{
width: 200px;
height: 200px;
border:1px solid #000 ;
background-color: #00F;
float:left;
}
#dl3{
width: 200px;
height: 200px;
border:1px solid #000 ;
background-color: #0F0;
}
#clear{
/*清除浮动属性
clear:
left:左边不浮动
right:右边不浮动
both:左右两边浮动
*/
}
#clear{
clear:both;
}
</style>
</head>
<body>
<div id="dl1">div1</div>
<div id="dl2">div2</div>
<!-- 没有文本内容div -->
<div id="clear"></div>
<div id="dl3">div3</div>
</body>
</html>