黑马程序员技术交流社区

标题: [石家庄校区] JSP - JDBC高级篇学习交流 [打印本页]

作者: 夕阳下的少年    时间: 2018-5-27 16:56
标题: [石家庄校区] JSP - JDBC高级篇学习交流
本帖最后由 夕阳下的少年 于 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窗口马上就会显示数据.
```





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2