www.test.com?id=1 与form表单不同的是,uri中的id=1可能是从a标签中直接获取的
RESTful是一种前后端交互的规范API。可以理解为“一种约定成俗的编程习惯”。
通常情况,只涉及到前后端请求方法上的约定。
本质上是通过幂等来区分
幂等:概念源于离散数学,用于判断两个关系是否幂等。可理解为“重复操作不改变结果”。
GET、PUT、DELETE都是幂等的
POST非幂等
一般情况下,可以按照功能区分。
增:POST 删:DELETE 改:PUT 查:GET
会涉及到一点点后端控制器的知识
功能 | 请求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
GET:URL后跟参数 POST:报文中空一行,再跟参数
序号 | 特殊字符 | 含义 | 十六进制值 |
---|---|---|---|
1. | + | URL 中+号表示空格 | + |
2. | 空格 | URL中的空格可以用+号或者编码 | %20 |
3. | / | 分隔目录和子目录 | %2F |
4. | ? | 分隔实际的 URL 和参数 | %3F |
5. | % | 指定特殊字符 | % |
6. | # | 表示书签 | %23 |
7. | & | URL 中指定的参数间的分隔符 | %26 |
8. | = | URL 中指定参数的值 | %3D |
中文会自动进行编码
流程如下
封装式代码结构:
以上内容作为总结性的文字参考,没有具体代码。 具体代码可查看尚硅谷java300集进行学习
JDBC只是Java提供的对外接口,具体的实现由数据库公司来实现。比如mysql或Oracle。
//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,否则报错!
将多个事情组成一个事件集,这个事件集内的所有事件要么同时执行成功,要么同时失败,则称为事务。 是数据库操作的一个执行单元。
mysql默认自动提交事务,且每条语句都在单独的事务中 mysql相关操作
隔离级别分为:
不看定义,我们通过名字来理解。 个人以为英语更容易解释:
首先确定一个前提,既然称为“隔离”,那肯定至少有两个对象,一个“被隔离者”,一个“未被隔离者”。 因此,隔离级别都是用于描述两个事务之间的关系。
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的对象序列化不是一个东西。“序列”最常见的含义是“有顺序的列”,因此,他的意思就是指,所有事务按顺序执行,一旦对一个数据开启了事务,其他人就只能排队等候。 这种自然能够排除任何数据错误,同样的,效率最低,几乎不使用。
设置隔离级别:必须在开启事务之前。 Connection.setTransactionIsolation(int level);
事务开始于:
事务结束于:
注意: JDBC默认自动提交事务,若设为手动提交,只有提交之后才会真正执行DDL语句。 因此: commit()才是事务的结束,execute和statement不是。
一般来说,通过try-catch,在catch中回滚。
java.sql提供的方法,通过Savepoint可以实现部分提交、部分回滚。
需求:AB(必须),CD(可选)
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();
}
}
Character Large Object,顾名思义,用于存储大量的文本数据。
大字段有些特殊,不同的数据库处理的方式不一样,大字段的操作常常以流的方式来处理,而非一般的字段,一次即可读出数据。
mysql中对应的相关类型:
Binary Large Object,顾名思义,用于存储大量的二进制数据
也是通过流来处理
mysql中对应的相关类型:
"池"这个概念,不应该陌生。接触最早的“池”就是常量池:用于存放常量,当程序使用该常量的时候,直接从常量池中取,而不是新建一个。因此多个常量(如String指向的字符串常量)具有相同地址。 因此,“连接池”是用于存放数据库连接的,当程序需要连接的时候,就从连接池中获取,不需要就放回。
目的:与数据库建立连接实际上非常耗费资源,提前构建连接池能够大大提高数据交互效率。
DBCP(DataBase Connection Pool)数据库连接池,是java数据库连接池的一种,由Apache开发,通过数据库连接池,可以让程序自动管理数据库连接的释放和断开。
C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate,Spring等。
由于Spring的缘故,因此博主学习的时候用的是C3P0。但是不同的连接池的使用方法基本上没啥差别。
目前在用阿里的druid
使用步骤:
<?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配置生效原理即可,后面学习框架配置会更加简单。