JavaWeb介绍
对勾都要重点学习
- Tomcat + HTTP + Servlet
- Request + Response
- JSP
- Cookie + Session
- Filter + Listener
- 综合案例
Juit测试
@test
class addtest(){
}
用断言判定结果是否正确
Assert.assertEquals(期望的结果,程序运算的结果)不一样就会抛出黄色警告
@Before
被Before修饰的方法会在test方法执行前被自动执行
@After
被After修饰的方法会在测试方法执行后自动执行,用于释放资源
反射
- 框架设计的灵魂
注解
本质就是一个接口,该接口默认继承Annotation接口
自定义注解格式: public @interface 注解名称{ }
属性:接口中的抽象方法
要求:
-
属性的返回值类型有下列取值
- 基本数据类型
- String
- 枚举
- 注解
- 以上数据类型的数组
-
定义了属性,在使用时需要给属性赋值
- 如果定义属性时,使用default关键字给默认初始化值,则使用注解时,可以不进行属性的赋值
- 如果只有一个属性需要赋值,并且属性的名称是value,则value可以省略,直接定义值即可
- 数组赋值时,值使用{}包裹,如果数组只有一个值,则省略{}
一、JDBC
- JDBC就是使用java语言操作关系型数据库的一套API
1.简介
用java语言操作关系型数据库的一套API 全程 java Database Connectivity Java数据连接
同一套代码,操作不同的关系型数据库,JDBC就是一套标准的接口来连接各种数据库
2.快速入门
给idea项目添加jar包:https://blog.csdn.net/weixin_44031029/article/details/109284132
先给当前的项目文件中添加jar驱动包,然后改为局部模块
// 8.0版本后的jar驱动文件,mysql5之后这行代码可以不写
Class.forName("com.mysql.cj.jdbc.Driver");
//之前
Class.forName("com.mysql.jdbc.Driver");
/*---------------------------JDBC操作数据库步骤-----------------------*/
package com.mypro.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
/*
JDBC快速入门
*/
public class JDBCDemo {
public static void main(String[] args) throws Exception {
//1. 注册驱动 jar包版本用的是Class.forName("com.mysql.jdbc.Driver");,8.0版本之后的要用下面这个
Class.forName("com.mysql.cj.jdbc.Driver");
//2.获取连接
String url = "jdbc:mysql://localhost:3306/heima";
String username = "root";
String password = "123456";
//定义mysql路径,用户名和密码,方便登录
Connection conn = DriverManager.getConnection(url, username, password);
//3.定义SQL
String sql = "update account set money = 2000 where id = 1";
//4.获取执行sql的对象statement
Statement stmt = conn.createStatement();
//5.执行sql的对象statement
int count = stmt.executeUpdate(sql);
//6.处理结果
System.out.println(count);
//7.释放资源
stmt.close();
conn.close();
}
}
3.API详解
1.DriverManager
- 注册驱动
- 获取数据库连接
上面的栗子中,获取路径时出现了三个参数,url(连接路径),user(用户名),password(密码).这里对url做一个讲解
// url 连接路径
/*
语法: jdbc:mysql://ip地址(域名):端口号/数据库名称?参数键值对1&参数键值对2...
示例: jdbc:mysql://localhost:3306/heima ip地址可以用localhost替代
细节:
1.如果连接的是本机的mysql服务器,并且mysql服务默认端口是3306,则url可以简写为: jdbc:mysql:///数据库名称?参数键值对
2.配置useSSL=false参数,禁止安全连接方式,解决警告提示
*/
//localhost代替ip地址
String url = "jdbc:mysql://localhost:3306/heima";
//本地mysql简写
String url = "jdbc:mysql:///heima";
//加上键值对
String url = "jdbc:mysql:///heima?useSSL=false";
2.Connection
数据库连接对象,作用:
- 获取执行SQL的对象
- 管理事务
// 普通执行SQL对象 !!
Statement createStatement()
//预编译SQL的执行SQL对象,防止SQL注入 !!
preparedStatement prepareStatement(sql)
//执行存储过程的对象
CallableStatement prepareCall(sql)
// 事务管理
//Mysql事务管理 默认自动提交
开启事务:begin/start transaction
提交事务:commit
回滚事务:rollback
//JDBC事务管理:Connection接口中定义了三个对应方法
//开启事务
setAutoCommit(boolean autoCommit): true为自动提交事务,false手动
//提交事务
commit()
//回滚事务
rollback()
/*-------------------------------处理事务案例----------------------------------*/
package com.mypro.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCDemo3_Connection {
public static void main(String[] args) throws Exception {
//1. 注册驱动 jar包版本用的是Class.forName("com.mysql.jdbc.Driver");,8.0版本之后的要用下面这个
Class.forName("com.mysql.cj.jdbc.Driver");
//2.获取连接
String url = "jdbc:mysql://localhost:3306/heima";
String username = "root";
String password = "123456";
//定义mysql路径,用户名和密码,方便登录
Connection conn = DriverManager.getConnection(url, username, password);
//3.定义SQL
String sql1 = "update account set money = 4000 where id = 1";
String sql2 = "update account set money = 2000 where id = 2";
//4.获取执行sql的对象statement
Statement stmt = conn.createStatement();
//------------------------- 事务管理----------------------------------
try {
//开启事务
conn.setAutoCommit(false);
//5.执行sql的对象statement
int count1 = stmt.executeUpdate(sql1);
int count2 = stmt.executeUpdate(sql2);
//6.处理结果
System.out.println(count1);
System.out.println(count2);
//提交事务
conn.commit();
} catch (Exception e) {
conn.rollback();
throw new RuntimeException(e);
}
//7.释放资源
stmt.close();
conn.close();
}
}
3.Statement
作用:用于执行sql语句
//执行SQL语句
int executeUpdate(sql):执行DML、DDL语句
//返回值:1.DML语句影响的行数 2.DDL语句执行后,执行成功也可能返回0
ResultSet executeQuery(sql)执行DQL语句
返回值 : ResultSet结果集对象
4.ResultSet(结果集对象)
作用:1.封装了DQL查询语句的结果
ResultSet stmt.executeQuery(sql):执行SQL语句,返回ResultSet对象
//获取查询结果
Boolean next:(1)将光标从当前位置向前移动一行 (2)判断当前行是否为有效行
返回值:
true 有效行,当前行有数据 false 无效行,当前行没数据
xxx getXxx(参数):获取数据
xxx:数据类型;如int getInt(参数) String getString(参数)
参数:
int 列的编号,从1开始 String列的名称
使用步骤:
- 游标向下移动一行,并判断改行是否有数据:next()
- 获取数据:getXxx(参数)
//循环判断游标是否是最后一行末尾
while(rs.next()){
//获取数据
rs.getXxx(参数);
}
//----------------------------------------案例--------------------------------
/**
* 执行DQL,查询account账户表数据,封装为Account对象中,并且存储到ArrayList集合中
* 1.定义实体类Account
* 2.查询数据,封装到Account对象中
* 3.将Account对象存入到ArrayList集合中
*
*
* @throws Exception
*/
@Test
public void testResultSet2() throws Exception {
Class.forName("com.mysql.cj.jdbc.Driver");
//2.获取连接
String url = "jdbc:mysql://localhost:3306/heima";
String username = "root";
String password = "123456";
//定义mysql路径,用户名和密码,方便登录
Connection conn = DriverManager.getConnection(url, username, password);
//3.定义SQL
String sql = "select * from account";
//4.获取statement对象
Statement stmt = conn.createStatement();
//5.执行sql
ResultSet rs = stmt.executeQuery(sql);
//创建一个集合
List<Account> list = new ArrayList<>();
//6.处理结果,遍历rs中的所有数据
//6.1光标向下一行并且判断是否有数据
//因为get中有方法的重载,所以可以直接写字段名
while (rs.next()) {
//每循环一遍创建一个对象,将下面的数据放入对象中,然后存入集合
Account account = new Account();
//6.2获取数据 getXxx
int id = rs.getInt("id");
String name = rs.getString("name");
double money = rs.getDouble("money");
//给对象赋值
account.setId(id);
account.setName(name);
account.setMoney(money);
//将对象存入集合
list.add(account);
}
System.out.println(list);
//7.释放资源
rs.close();
stmt.close();
conn.close();
}
}
5.PreparedStatement(执行SQL语句的对象)
继承自statement,作用:
- 预编译SQL语句并执行:预防SQL注入问题
SQL注入:通过操作输入来修改事先定义好的SQL语句,用以达到执行代码对服务器进行攻击的方法
//1.获取preparedStatement对象
//SQL语句中的参数值,使用?占位符替代
String sql = "select * from user where username = ? and password = ?";
//通过Connection对象获取,并传入对应的sql语句
PreparedStatement pst = conn.prepareStatement(sql);
//2.设置参数值
PreparedStatement 对象:setXxx(参数1,参数2):给?赋值
Xxx:数据类型;如setInt(参数1,参数2)
参数:
参数1:?的位置编号,从1开始
参数2:?/的值
//3.执行SQL
executeUpdate(); / executeQuery() 不需要在传递sql
4.数据库连接池
1.简介
- 数据库连接池是个容器,负责分配、管理数据库连接
- 它允许应用程序重复使用一个现有的数据库连接,而不是在重新建立一个
- 释放空间时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接二引起的数据库连接遗漏
好处:
- 资源重用
- 提升系统响应速度
- 避免数据库连接遗漏
标准接口:DataSource
- 官方提供的数据库连接池标准接口,由第三方组织实现此接口
- 功能:获取连接 Connection getConnection()
常见的数据库连接池:DBCP、C3P0 、Druid
Druid:是阿里巴巴开源的数据库连接池项目,功能强大,性能优,是java语言最好的数据库连接池之一
2.Driud使用步骤
- 导入jar包 druid-1.1.12jar
- 定义配置文件
- 加载配置文件
- 获取数据库连接池对象
- 获取连接
配置driud文件
-
下载driud.jar包:https://blog.csdn.net/YyjYsj/article/details/108854572
-
将jar包放入同自己的项目的文件中
- 因为要放入多个jar包,可以创一个文件夹专门放包
-
加载配置文件:在src目录下写一个druid.properties文件
1.
-
#配置文件中的内容 driverClassName=com.mysql.cj.jdbc.Driver #自己SQL文件的注册驱动 # mysql的连接,根据自己本机来设置 url=jdbc:mysql:///heima?useSSL=false&useServerPrepStmts=true username=root password=123456 # 初始化连接数量 initialSize=5 # 最大连接数 maxActive=10 #最大等待时间 maxWait=3000
-
-
在java类中代码实现
-
package com.mypro.druid; import com.alibaba.druid.pool.DataSourceClosedException; import com.alibaba.druid.pool.DruidDataSourceFactory; import javax.sql.DataSource; import java.io.FileInputStream; import java.sql.Connection; import java.util.Properties; /** * Druid数据库连接池演示 */ public class DruidDemo { public static void main(String[] args) throws Exception { // 1.导入jar包 //2.定义配置文件 //3.加载配置文件 Properties prop = new Properties(); //本地的druid.properties文件目录 prop.load(new FileInputStream("D:/idea-2022/mypro/MyWeb_test/src/druid.properties")); //4.获取连接池对象 DataSource dataSource = DruidDataSourceFactory.createDataSource(prop); //5.获取数据库连接 Connection Connection connection = dataSource.getConnection(); System.out.println(connection); System.out.println(System.getProperty("user.dir")); } }
-
5.实现品牌数据的增删改查案例
1.MySQL数据库准备
# 创建品牌信息table
create table tb_brand
(
id int primary key auto_increment,
brand_name varchar(20),
company_name varchar(20),
ordered int,
description varchar(100),
status int
);
insert into tb_brand
values (null, '三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0),
(null, '华为', '华为技术有限公司', 100, '华为致力于把数字世界带入每个人,每个家庭,每个组织,构建万物互联的智能世界', 1),
(null, '小米', '小米科技有限公司', 50, 'are you ok', 1);
2.idea中Brand类创建
package com.mypro.pojo;
/**
* 品牌信息
* <p>
* 实体类中,基本数据类型建议使用其对应的包装类型
*/
public class Brand {
//主键
private Integer id;
//品牌名称
private String brandName;
//企业名称
private String companyName;
//排序字段
private Integer ordered;
//描述信息
private String description;
//状态 0禁用 1启用 用Integer而不用int是因为int有默认值0,可能对业务产生影响,Integer默认值是null
private Integer status;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getBrandName() {
return brandName;
}
public void setBrandName(String brandName) {
this.brandName = brandName;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public Integer getOrdered() {
return ordered;
}
public void setOrdered(Integer ordered) {
this.ordered = ordered;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
@Override
public String toString() {
return "Brand{" +
"id=" + id +
", brandName='" + brandName + '\'' +
", companyName='" + companyName + '\'' +
", ordered=" + ordered +
", description='" + description + '\'' +
", status=" + status +
'}';
}
}
3.查询所有数据
- 获取connection
- 定义SQL:select * from tb_brand;
- 获取PreparedStatement对象
- 设置参数:不需要
- 执行SQL
- 处理结果:将每一个对象放入集合中 List
- 释放资源
/**
* 查询所有
* 1. SQL: select * from tb_brand;
* 2. 是否需要参数,这里不需要
* 3. 结果存入 : brands<list>
*
* @throws Exception
*/
@Test
public void testSelectAll() throws Exception {
//注册驱动连接java和MySql
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql:///heima";
String username = "root";
String password = "123456";
//1.获取Connecion
Connection conn = DriverManager.getConnection(url, username, password);
//2.定义sql查找语句
String sql = "select * from tb_brand;";
//3.获取执行sql对象的statement对象
PreparedStatement preparedStatement = conn.prepareStatement(sql);
//4.执行sql
ResultSet rs = preparedStatement.executeQuery();
//创建一个集合存储对象
List<Brand> brands = new ArrayList<>();
Brand brand = null;
//游标判断,是否找到数据,一个一个检索
while (rs.next()) {
brand = new Brand();
//获取数据
int id = rs.getInt("id");
String brandName = rs.getString("brand_name");
String comName = rs.getString("company_name");
int order = rs.getInt("ordered");
String description = rs.getString("description");
int status = rs.getInt("status");
brand.setId(id);
brand.setBrandName(brandName);
brand.setCompanyName(comName);
brand.setOrdered(order);
brand.setDescription(description);
brand.setStatus(status);
//装载集合
brands.add(brand);
}
System.out.println(brands);
//资源释放
rs.close();
preparedStatement.close();
conn.close();
}
4.添加数据
/**
* 添加
* 1. SQL: insert into tb_brand(brand_name,company_name,ordered,description,status)
* values(?,?,?,?,?); 问号个数与表中参数个数一样
* 2. 是否需要参数,需要,除了id的所有参数 id由数据库自动生成,设置auto_increment;
* 3. 结果 : boolean
*
* @throws Exception
*/
@Test
public void testAdd() throws Exception {
//接受页面提交的参数
String brandName = "香飘飘";
String companyName = "香飘飘";
int ordered = 1;
String description = "绕地球一圈";
int status = 1;
//注册驱动连接java和MySql
Class.forName