本帖最后由 夕阳下的少年 于 2018-5-27 16:57 编辑
## WEB13-JSP模式&JDBC高级篇
### 使用MVC设计模式完成转账的案例:
Servlet :
`缺点`:`显示HTML元素的时候麻烦`
JSP:
`优点`: `显示数据方便`
`缺点`:`在封装数据和处理数据上麻烦`
JSP+ JavaBean:
`优点`:`显示数据和封装处理数据很方便`
`缺点`:`维护麻烦`
* JSP的模式一:JSp+JavaBean的模式
* JSP显示数据,使用JavaBean封装和处理数据
**JSP+Servlet+JavaBean:**
`优点`:`JSP用于显示数据JavaBean用于数据和处理数据Servlet控制`
* JSP的模式二: JSP+Servlet+JavaBean的模式,也被成为是MVC的设计模式.
* MVC:
* M:Model :模型层 JavaBean
* V: View视图层 JSP
* c:Contr后来了让:控制层 Servlet
```ht
####了解了解就行~~~
JSP + JavaBean
* 演示模式一的过程:
* 在模式一开发中提供了一些JSP的标签:<jsp:useBean> ,<jsp:setProperty >,<jsp:getProperty>
* 使用模式一进行简单的测试:
<%
// 接收数据:
/* String username = request.getParameter("username");
String password = request.getParameter("password");
// 封装数据:
User user = new User();
user.setUsername(username);
user.setPassword(password); */
%>
<jsp:useBean id="user" class="com.itheima.demo1.domain.User" scope="page"></jsp:useBean>
<%-- <jsp:setProperty property="username" name="user"/>
<jsp:setProperty property="password" name="user"/> --%>
<jsp:setProperty property="*" name="user"/><!-- 表单的元素的name属性的值与User中的属性名称一致 就可以自动封装 -->
<jsp:getProperty property="username" name="user"/>
```
**【JSP的开发模式二】:掌握**
```te
JSP + Servlet + JavaBean 称为MVC的设计模式.
MVC:
M:Model:模型层
V:View:视图层
C:Controller:控制层
```
**【Java中的反射技术】(掌握)**
* 类的加载器将class文件加载到虚拟机中(内存中) ,name有一个Class对象(代表是class文件加载到内存后行程的一个对象)
* 反射第一步或的class文件加载到内存的行程字节码文件的对象Class对象
【Java中的内省技术】(了解)
```html
内省:用来获得JavaBean的属性及属性的get或set方法.
JavaBean:就是一个满足了特定格式的Java类:
* 需要提供无参数的构造方法:
* 属性私有
* 对私有的属性提供public的get/set方法.
内省的代码:
public void demo1() throws Exception{
// 获得了Bean的信息
BeanInfo beanInfo = Introspector.getBeanInfo(User.class);
// 获得Bean的属性描述了
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
for(PropertyDescriptor pd:pds){
System.out.println(pd.getName());
/*pd.getReadMethod(); // 获得get方法
pd.getWriteMethod();// 获得set方法.
*/ }
}
使用内省封装一个MyBeanUtils:
public class MyBeanUtils {
public static void populate(Object obj,Map<String,String[]> map) throws Exception{
// 获得类的所有的属性的名称:
BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
// 获得类中所有的属性:
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor pd : pds) {
if(map.containsKey(pd.getName())){
Method method = pd.getWriteMethod();
// 执行set方法:
method.invoke(obj, map.get(pd.getName())[0]);
}
}
}
}
```
**【事务的概述】**
什么是事务;
* 事务指的是逻辑上的一组操作,组成这组操作的**各个逻辑单元要么一起成功,要么一起失败**
**【JDBC中的事务管理】(掌握)**
* JDBC的事务管理的APL:
* void setAutopsyCommit(Boolean autoCommit): 将此链接的自动提交模式设置为给定状态.
* void commit() :使所有上一次提交/回滚后进行的更改成为持久更改
* void rollback():取消当前事务中尽心的所有更改,并释放此Connection对象当前持有的所有数据封锁,
### DBUtils实现事务管理:
#### 事务特性
* 原子性:强调事务的不可分割.
* 一致性:强调的是事务的执行的前后,数据的完整性要保持一致.
* 隔离性:一个事务的执行不应该受到其他事务的干扰.
* 持久性:事务一旦结束(提交/回滚)数据就持久保持到了数据库
#### 如果不考虑事务的隔离性,引发一些安全性问题
Ø 一类读问题:
* `脏读 ` :一个事务读到另一个事务还没有提交的数据.
* `不可重复读 `:一个事务读到了另一个事务已经提交的update的数据,导致在当前的事务中多次查询结果不一致.
* `虚读/幻读 ` :一个事务读到另一个事务已经提交的insert的数据,导致在当前的事务中多次的查询结果不一致.
* 一类写问题:
* 引发两类丢失更新
#### 解决引发的读问题
设置事务的隔离级别:
* read uncommitted :未提交读.脏读,不可重复读,虚读都可能发生.
* read committed :已提交读.避免脏读.但是不可重复读和虚读有可能发生.
* repeatable read :可重复读.避免脏读,不可重复读.但是虚读有可能发生.
* serializable :串行化的.避免脏读,不可重复读,虚读的发生
#### 演示脏读的发生
* 分别开启两个窗口:A,B
* 分别查看两个窗口的隔离级别:select @@tx_isolation;
* 设置A窗口的隔离级别为:**read uncommitted**
* **set session transaction isolation level readuncommitted**
* **分别在两个窗口中开启事务**
* **start transaction;**
* 在B窗口完成转账的操作:
* **update account set money = money - 1000 wherename = '张森';**
* **update account set money = money + 1000 wherename = '凤姐'**
* **在A窗口查询数据:(钱已经到账---脏读**)
* **select \* from account; -- A事务读到了B事务还没有提交的数据**
#### 演示避免脏读,不可重复读发生
* 分别开启两个窗口:A,B*
* 分别查看两个窗口的隔离级别:select @@tx_isolation;
* 设置A窗口的隔离级别为:**read committed:**
* ** set session transactionisolation level read committed;**
* ** 分别在两个窗口中开启事务:**
* *** start transaction;**
* **在B****窗口完成转账的操作:**
* ** update account set money =money - 1000 where name = '****张森';**
* ** update account set money =money + 1000 where name = '****凤姐';**
* **在A****窗口中进行查询:**
* ** select \* from account; --** **避免脏读.**
* **在B****窗口提交事务:**
* ** commit;**
* **在A****窗口中再次查询:**
* ** select \* from account; --** **转账成功.(****不可重复读:****一个事务读到另一个事务中已经提交的update****的数据,****导致多次查询结果不一致.)**
#### 演示避免虚读的发生
```te
分别开启两个窗口:A,B
分别查看两个窗口的隔离级别:select @@tx_isolation;
设置A窗口的隔离级别为:serializable:
* set session transaction isolation level serializable;
在A,B两个窗口中分别开启事务:
* start transaction;
在B窗口中完成一个insert操作:
* insert into account values (null,'王老师',10000);
在A创建中进行查询的操作:
* select * from account; -- 没有查询到任何结果.
在B窗口提交事务:
* commit; -- A窗口马上就会显示数据.
``` |
|