前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java学习笔记-全栈-Java基础-13-JavaWeb基础

Java学习笔记-全栈-Java基础-13-JavaWeb基础

作者头像
devi
发布2021-08-18 15:23:06
3920
发布2021-08-18 15:23:06
举报
文章被收录于专栏:搬砖记录

1. 前后端交互基础

  • 通过超链接跳转传递数据

www.test.com?id=1 与form表单不同的是,uri中的id=1可能是从a标签中直接获取的

  • 通过form表单

1.1 form

  • aciton:请求服务器资源(URL),对应控制器的Mapping
  • name:后端使用,区分唯一(可重名,后端用容器接收)
  • id:前端使用,区分唯一

1.2 引用路径的区别

  • 1)href:指定资源路径,将当前元素与资源之间建立联系
  • 2)src:指向外部资源路径,将该资源应用到当前元素中替换作用
  • 3)action:将本页面的请求传递给目标路径

1.3 RESTful

RESTful是一种前后端交互的规范API。可以理解为“一种约定成俗的编程习惯”。

通常情况,只涉及到前后端请求方法上的约定。

本质上是通过幂等来区分

幂等:概念源于离散数学,用于判断两个关系是否幂等。可理解为“重复操作不改变结果”。

GET、PUT、DELETE都是幂等的

  • 同一个GET无论多少次,获得的资源都是一样的
  • 同一个PUT无论多少次,更新结果依旧一样
  • 同一个DELETE结果都是一样的,那就是“该对象”被删除,不会有副作用。

POST非幂等

  • 同一个POST,请求多次,每个请求都会各自生成一个结果,因此非幂等。

一般情况下,可以按照功能区分。

增:POST 删:DELETE 改:PUT 查:GET

REST-CRUD设计实例

会涉及到一点点后端控制器的知识

功能

请求Uri

对应返回视图

请求方式

访问后的操作

查找所有user

users

userlist

Get

从数据库获得数据,在页面显示所有user

来到添加页面

user

useradd

get

从数据库中获取必要的提示数据(比如可以填写的部门)在页面展示

添加user

user

重定向:userlist

post

提交后从user中实现Dao增加,然后回到userlist显示最新数据

来到修改页面(回显)

User/1

useradd

get

利用PathVariable查询数据,然后将其回显到ueradd页面

修改user

User

重定向:userlist

put

在useradd中修改完毕后put到user,user中更新后返回到userlist显示最新数据

删除一个user

User/1

重定向:userlist

delete

利用PathVariable实现删除,并返回uselist显示最新数据

添加页面和修改页面可以一页两用: 浏览器单击“添加”按钮的时候,只能回显部分必要的提示数据(model为null); 单击“修改”按钮的时候,能通过@pathvariable(Spring注解)查询到对应model:可通过model是否为null,分别展示不同的细节。

由于浏览器版本: 对于put、delete请求,需要在post表单内使用进行请求转换(固定写法) <input type=“hidden” name="_method" value=“delete”/>

在springboot2.x以上,Delete请求还得配置 spring.mvc.hiddenmethod.filter.enabled=true

1.4 GET和POST在报文上的区别

GET:URL后跟参数 POST:报文中空一行,再跟参数

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

1.5 URL中的特殊字符

序号

特殊字符

含义

十六进制值

1.

+

URL 中+号表示空格

+

2.

空格

URL中的空格可以用+号或者编码

%20

3.

/

分隔目录和子目录

%2F

4.

?

分隔实际的 URL 和参数

%3F

5.

%

指定特殊字符

%

6.

#

表示书签

%23

7.

&

URL 中指定的参数间的分隔符

%26

8.

=

URL 中指定参数的值

%3D

中文会自动进行编码

2. 手写web服务器

流程如下

2.1 获取请求协议

  • 创建serversocket
  • 建立连接,获取客户端的socket
  • 通过输入流获取请求协议
  • 分解请求协议中的内容

2.2 返回响应协议

  • 准备内容
  • 获取字节数组长度
  • 拼接响应协议,注意空格与换行
    • \r : return 到当前行的最左边。
    • \n: newline 向下移动一行,并不移动左右
    • Linux中\n表示回车+换行;
    • Windows中\r\n表示回车+换行。
    • Mac中\r表示回车+换行。
  • 使用输出流输出

封装式代码结构:

  • 内部: - 动态添加content - 根据字节码拼接响应头 - 根据状态码返回相应协议
  • 外部: - 传入content和状态码

2.3 Servlet,XML

  • 通过url获取配置文件,反射成所需的class,再用servlet处理业务。
  • 使用servlet(response,request),解耦代码,实现封装

以上内容作为总结性的文字参考,没有具体代码。 具体代码可查看尚硅谷java300集进行学习

3. JDBC的使用

JDBC只是Java提供的对外接口,具体的实现由数据库公司来实现。比如mysql或Oracle。

3.1 建立连接

代码语言:javascript
复制
//1.加载驱动类
Class.forName("com.mysql.jdbc.Driver");

//2.使用manager链接数据库,实际时使用socket进行远程连接,较耗时,真正开发中都是用连接池来管理连接对象
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/study?serverTimezone=UTC","root","123456");

凡是引入mysql-url的(无论是直接使用JDBC还是框架中引入mysql),都要加上serverTimezone=UTC,否则报错!

3.2 常用接口

  • 1.Statement:用于执行静态的SQL语句并返回它生成结果的对象,
    • a)三种实现类
      • i.Statement:只能发送不带参数的简单sql语句,一般只用于批处理
        • 1.addBatch(“sql语句”),插入语句
        • 2.executeBatch(),执行批量插入
      • ii.preparedStatement:效率高,防止SQL注入,普通需求使用这个
      • iii.CallableStatement:继承自ii,由方法prePareCall创建,用于调用存储过程
    • b)常用Statement方法
      • i.Execute(),运行所有语句,返回是否有结果集
      • ii.executeQuery();运行select语句,然后resultSet结果集
      • iii.executeUpdate();运行insert/update/delete操作,返回更新行数
  • 2.ResultSet接口:
    • a)Statement执行sql语句时返回resultset结果集
    • b)Resultset提供的检索不同类型字段的方法,常用的有
      • i.getString();获得在数据库里面时varchar、char等类型对象
      • ii.getFloat();
      • iii.getDate();
      • iv.getBoolean();
  • 3.依序关系使用对象及连接
    • a)Resultset->statement->connection

3.3 事务

将多个事情组成一个事件集,这个事件集内的所有事件要么同时执行成功,要么同时失败,则称为事务。 是数据库操作的一个执行单元

mysql默认自动提交事务,且每条语句都在单独的事务中 mysql相关操作

  • start transaction 开启事务
  • Rollback 回滚事务
  • Commit 提交事务

ACID

  • A:atomicity原子性
    • 象征事件集是一个整体,不可分可,同生共死(要么…要么…)。
  • C:consistency一致性
    • 无论执行失败或成功,事务执行前后,数据应当是完整的,一致的。
  • I:isolation隔离性
    • 通过数据串行化,使得在同一时间仅有一个请求用于同一数据。保证在并发的情况下,多个用户对同一个数据进行操作的时候,不会相互影响。
  • D:durability持久性
    • 在事务完成以后,该事务对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。即使数据库发生故障也不应该对其有任何影响。

事务的隔离级别

隔离级别分为:

  • (脏读)READ UNCOMMITTED
  • (不可重复读)READ COMMITTED
  • (虚读\幻读)REPEATABLE READ
  • (序列化)SERIALIZABLE

不看定义,我们通过名字来理解。 个人以为英语更容易解释:

首先确定一个前提,既然称为“隔离”,那肯定至少有两个对象,一个“被隔离者”,一个“未被隔离者”。 因此,隔离级别都是用于描述两个事务之间的关系。


read uncommitted --> 读取了未提交的(数据)(oracle默认):一个事务读取了另一个事务未提交的数据,这就是“脏”(引用于汉语中的“贪脏了不属于你的东西”)


read committed --> 读取了已提交的(数据):这个比较难理解,事实上他还有个发生前提:先读了一个数据,然后再读的时候,才读取了已提交的。也就是说,在这个过程中,有第二者插手。 例子 A读取到存款还有10元,准备进行消费; B此时消费了5元; A消费的时候,本来刚刚查询的是10元,但是消费的时候(也进行了查询操作)却余额不足两次一样的查询数据却不一样此时就是读取了已提交的,因此也称为“不可重复读”(重复读出现了不一致数据)

mysql默认级别是repeatable read,是可以解决这个问题的,所以初学者可能有疑惑,为什么会发生这种事情。因为这个级别,是允许两个事务同时对数据进行修改的


repeatable read --> 可重复读(mysql默认):既然可重复读,也就是说,当一个事务在进行读取的时候,不允许被其他事务修改。 还是上面那个例子: A读取到存款还有10元,准备进行消费; B此时想进行消费(修改操作),但是由于A正在操作,因此B操作失败。 A成功进行消费。 repeatable read用于锁定修改操作(Update),但是无法锁定插入操作(Insert) 当A进行重复读的时候,若在重复读期间,第三方进行了插入操作(这是被允许的),此时就出现了“幻觉”。 如: A查询存款为10元;但他有点不放心,决定再查一次 此时B存了5元; A刷新查询,发现变成了15!刚才出现幻觉了吗?(幻读)


serializable --> 序列化:此处的序列化跟java的对象序列化不是一个东西。“序列”最常见的含义是“有顺序的列”,因此,他的意思就是指,所有事务按顺序执行,一旦对一个数据开启了事务,其他人就只能排队等候。 这种自然能够排除任何数据错误,同样的,效率最低,几乎不使用


  • 1、READ UNCOMMITTED: 赃读、不可重复读、虚读都有可能发生。
  • 2、READ COMMITTED: 避免赃读。不可重复读、虚读都有可能发生。(oracle默认的)
  • 4、REPEATABLE READ:避免赃读、不可重复读。虚读有可能发生。(mysql默认)
  • 8、SERIALIZABLE: 避免赃读、不可重复读、虚读。 级别越高,性能越低,数据越安全

JDBC中的事务隔离级别设置

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

设置隔离级别:必须在开启事务之前。 Connection.setTransactionIsolation(int level);

JDBC中的事务

事务开始于:

  • 执行一条DML语句(INSERT、UPDATE或DELETE)
  • 前一个事务结束后,又输入了另一条DML语句

事务结束于:

  • 执行COMMIT(提交)或ROLLBACK(回滚)语句
  • 执行DDL语句(create、alter、drop和 truncate),将自动执行COMMIT。
  • 断开数据库连接
  • 执行DML语句,该语句失败了,则会自动执行ROLLBACK。

注意: JDBC默认自动提交事务,若设为手动提交,只有提交之后才会真正执行DDL语句。 因此: commit()才是事务的结束,execute和statement不是。

一般来说,通过try-catch,在catch中回滚。

JDBC使用事务

  • Connection.setAutoCommit(false); 开启事务
  • Connection.rollback(); 回滚事务
  • Connection.commit(); 提交事务
在这里插入图片描述
在这里插入图片描述

Savepoint

java.sql提供的方法,通过Savepoint可以实现部分提交、部分回滚

需求:AB(必须),CD(可选)

代码语言:javascript
复制
Connection conn = null;
Savepoint savepoint = null;  //保存点,记录操作的当前位置,之后可以回滚到指定的位置。(可以回滚一部分)
try{
  //1 获得连接
  conn = ...;
  //2 开启事务
  conn.setAutoCommit(false);
  A
  B
  savepoint = conn.setSavepoint();
  C
  D
  //3 提交事务
  conn.commit();
} catche(){
  if(savepoint != null){   //CD异常
     // 回滚到CD之前
     conn.rollback(savepoint);
     // 提交AB
     conn.commit();
  } else{   //AB异常
     // 回滚AB
     conn.rollback();
  }
}

3.4 JDBC中的特殊对象

CLOB

Character Large Object,顾名思义,用于存储大量的文本数据。

大字段有些特殊,不同的数据库处理的方式不一样,大字段的操作常常以流的方式来处理,而非一般的字段,一次即可读出数据。

mysql中对应的相关类型:

  • TINYTEXT
  • TEXT
  • MEDIUMTEXT
  • LONGTEXT

BLOB

Binary Large Object,顾名思义,用于存储大量的二进制数据

也是通过流来处理

mysql中对应的相关类型:

  • TINYBLOB
  • BLOB
  • MEDIUMBLOB
  • LONGBLOB

3.5 数据库连接池

原理

"池"这个概念,不应该陌生。接触最早的“池”就是常量池:用于存放常量,当程序使用该常量的时候,直接从常量池中取,而不是新建一个。因此多个常量(如String指向的字符串常量)具有相同地址。 因此,“连接池”是用于存放数据库连接的,当程序需要连接的时候,就从连接池中获取,不需要就放回。

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

目的:与数据库建立连接实际上非常耗费资源,提前构建连接池能够大大提高数据交互效率。

常用数据库连接池

DBCP(DataBase Connection Pool)数据库连接池,是java数据库连接池的一种,由Apache开发,通过数据库连接池,可以让程序自动管理数据库连接的释放和断开。

C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate,Spring等。

由于Spring的缘故,因此博主学习的时候用的是C3P0。但是不同的连接池的使用方法基本上没啥差别。

目前在用阿里的druid

使用步骤:

  1. 添加jar包
  2. 编写配置文件c3p0-config.xml,放在classpath中,或classes目录中
代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
  <default-config>
	<property name="driverClass">com.mysql.jdbc.Driver</property>
	<property name="jdbcUrl">jdbc:mysql://localhost:3306/day12</property>
	<property name="user">root</property>
	<property name="password">123456</property>
    <property name="initialPoolSize">10</property>
    <property name="maxIdleTime">30</property>
    <property name="maxPoolSize">100</property>
    <property name="minPoolSize">10</property>
  </default-config>
</c3p0-config>

配置的属性可以通过顾名思义理解(如maxPoolSize就是指池中最大连接数),在此不再赘述,不懂得可以百度。

<property name=“driverClass”>com.mysql.jdbc.Driver</property> 这句话在高版本的框架会警告已经完成自动配置,可以不写

3. 编写工具类,使用

此处无需耗费过多的时间,掌握连接池的原理,以及xml配置生效原理即可,后面学习框架配置会更加简单。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/12/16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 前后端交互基础
    • 1.1 form
      • 1.2 引用路径的区别
        • 1.3 RESTful
          • REST-CRUD设计实例
        • 1.4 GET和POST在报文上的区别
          • 1.5 URL中的特殊字符
          • 2. 手写web服务器
            • 2.1 获取请求协议
              • 2.2 返回响应协议
                • 2.3 Servlet,XML
                • 3. JDBC的使用
                  • 3.1 建立连接
                    • 3.2 常用接口
                      • 3.3 事务
                        • ACID
                        • 事务的隔离级别
                        • JDBC中的事务隔离级别设置
                        • JDBC中的事务
                        • JDBC使用事务
                        • Savepoint
                      • 3.4 JDBC中的特殊对象
                        • CLOB
                        • BLOB
                      • 3.5 数据库连接池
                        • 原理
                        • 常用数据库连接池
                    相关产品与服务
                    云数据库 SQL Server
                    腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档