天天看點

day13-(事務&mvc&反射補充)

回顧:
jsp:
  java伺服器頁面
  jsp的腳本
  jsp的注釋
    html注釋
    java注釋
    jsp注釋
      <%-- --%>
  jsp的指令
    page:聲明頁面一些屬性
      重要的屬性:
        import
        pageEncoding
        contentType
      了解屬性
        isErrorPage:一旦他的值為true jsp頁面就是可以使用exception内置對象
    include:靜态包含,(内容)
    taglib:導入标簽庫
    
  jsp的内置對象 9個
    out 
    request
    response
    session
    
    exception
    page
    config
    application
    pageContext
  jsp的域對象
    pageContext
    request
    session
    application
  jsp的動作标簽
    jsp:forward 請求轉發
    jsp:include 動态包含(運作結果)
el:
  從jsp2.0使用的内置表達式語言
  替代<%=...%>
  作用:
    1.擷取域中的資料
      簡單
        ${域.域中屬性名}
        ${域中屬性名}:若找不到傳回一個""
        注意:
          若屬性名字中有"."等特殊符号的時候
            必須使用 ${域["域中屬性名"]}
      複雜
        數組和list ${域中名稱[index]}
        map   ${域中的名稱.鍵}
      javabean導航
        javabean:
          1.必須公共的類
          2.私有字段
          3.提供公共的通路字段的方法  get|set|is
            一旦提供公共的方法之後,get|set|is後面的名稱首字母小寫,這個東西稱之為bean屬性
              例如:getName()  name就是一個bean屬性
          4.提供一個無參構造器
          5.一般會實作序列化接口
          
        ${域中的屬性名.bean屬性}
    2.執行運算
      注意:
        +
        empty
        三元運算符
  el的内置對象:
    cookie
      ${cookie.cookie名稱.value}
    pageContext
      在jsp頁面動态的擷取項目路徑 /day11
        ${pageContext.request.contextPath}
jstl:
  jsp 标準标簽庫
  apache組織
  使用步驟:
    1.導入jar包
    2.在頁面上導入标簽庫
  core:核心包
    c:if 判斷
    c:forEach 循環
//
分層和事務
案例-使用mvc思想完成轉賬操作
需求:
  在一個頁面上有彙款人 收款人 轉賬金額.一旦轉賬之後,彙款人金額減少,收款人金額增多.使用事務控制起來.
技術分析:
  mvc思想
  事務
///
mvc思想
  servlet-->缺點:生成html内容太麻煩
    |
  jsp--->缺點:閱讀起來不友善,維護比較困難
    |
  jsp+javabean:
      jsp的model1:
        jsp:接受請求,展示資料
        javabean:和資料打交道 
    |
  jsp+javabean+servlet
      jsp的model2:
        jsp:展示資料
        javabean:和資料打交道
        servlet:接受請求,處理業務邏輯
      就是MVC思想的展現
MVC:
  就是将業務邏輯,代碼,顯示相分離的一種思想
  M:model 模型 作用:主要是封裝資料,封裝對資料的通路
  V:view  視圖 作用:主要是用來展示資料 一般是jsp擔任的
  C:ctrl  控制 作用:接受請求,找到相應的javabean完成業務邏輯
/
jsp設計模式1 model1:(了解)
  javabean+jsp
  javabean在model1使用(了解)
    <!-- 接受值 -->
    <jsp:useBean id="u" class="com.itheima.domain.User"></jsp:useBean><!--相當于  User u=new User()-->
    <jsp:setProperty property="name" name="u"/><!--相當于  u.setName(...)-->
    <jsp:setProperty property="password" name="u"/>

    <!-- 列印值-->
    <jsp:getProperty property="name" name="u"/>
//
反射:
  1.擷取class對象
    方式1:
      Class clazz=Class.forName("全限定名")
    方式2:
      Class clazz=類名.class;
    方式3:
      Class clazz=對象.getClass;
  2.可以擷取對應類的構造方法(了解)
    Constructor con = clazz.getConstructor(Class .. paramClass);
    Person p = (Person) con.newInstance(參數);
  3.可以通過clazz建立一個對象(了解)
    clazz.newInstance();//相當于調用的無參構造器
  4.可以通過clazz擷取所有的字段 getFiled()(了解中的了解)
  5.可以通過clazz擷取所有的方法
    Method m = clazz.getMethod("sleep");//擷取公共的方法
    Method m = clazz.getDeclaredMethod("sleep");//擷取任意的方法
    
    注意:若是私有的方法 必須讓該方法可以通路
      m.setAccessible(true);
  6.Method對象的invoke是有傳回值,他的傳回值就是目标方法執行的傳回值
總結:
  有了class對象之後,無所不能.

javabean在model2中使用
  BeanUtils:可以看作封裝資料一個工具類
    使用步驟:
      1.導入jar包
      2.使用BeanUtils.populate(Object bean,Map map);
  
/
分層:javaee的三層架構
  web
    作用:
      展示資料 ----jsp
      
      
      -----servlet-------
      接受請求
      找到對應的service,調用方法 完成邏輯操作
      資訊生成或者頁面跳轉
  service 業務層
    作用:
      完成業務操作
      調用dao
  dao(data access object 資料通路對象)
    作用:
      對資料庫的curd操作
/
/
事務:
  就是一件完整的事情,包含多個操作單元,這些操作要麼全部成功,要麼全部失敗.
  例如:轉賬
    包含轉出操作和轉入操作.
  mysql中的事務:
    mysql中事務預設是自動送出,一條sql語句就是一個事務.
    開啟手動事務方式
      方式1:關閉自動事務.(了解)
        set autocommit = off;
      方式2:手動開啟一個事務.(了解)
        start transaction;-- 開啟一個事務
        commit;-- 事務送出
        rollback;-- 事務復原
    擴充:
      oracle中事務預設是手動的,必須手動送出才可以.
    
    例如:建立資料庫和表
      create database day13;
      use day13;
      create table account(
        name varchar(20),
        money int
      );
      
      insert into account values('aa','1000');
      insert into account values('bb','1000');
      
    完成 aa給bb轉500;
      update account set money = money - 500 where name='aa';
      update account set money = money + 500 where name='bb';
    
  java中的事務:
    Connection接口的api:★
      setAutoCommit(false);//手動開啟事務
      commit():事務送出
      rollback():事務復原
    
    擴充:了解 Savepoint還原點
      void rollback(Savepoint savepoint) :還原到那個還原點
      Savepoint setSavepoint() :設定還原點
 /
 步驟分析:
  1.資料庫和表
  2.建立一個項目 day1301
  3.導入jar包和工具類
    驅動 jdbcUtils
    c3p0及其配置檔案和工具類
    dbutils
  4.建立一個account.jsp 表單
  5.accountservlet:
    接受三個參數
    調用accountservice.account方法完成轉賬操作
    列印資訊
  6.account方法中:
    使用jdbc不考慮事務
    調用dao完成轉出操作
    調用dao完成轉入操作
  7.dao中
      
  一旦出現異常,錢飛了.
  要想避免這事情,必須添加事務,在service添加事務.
  為了保證所有的操作在一個事務中,必須保證使用的是同一個連接配接
  在service層我們擷取了連接配接,開啟了事務.如何dao層使用此連接配接呢????
    方法1:
      向下傳遞參數.注意連接配接應該在service釋放
    方法2:
      可以将connection對象綁定目前線程上
      jdk中有一個ThreadLocal類,
      ThreadLocal 執行個體通常是類中的 private static 字段,
      它們希望将狀态與某一個線程(例如,使用者 ID 或事務 ID)相關聯。 
  ThreadLocal的方法:
    構造:
      new ThreadLocal()
    set(Object value):将内容和目前線程綁定
    Object get():擷取和迪昂前線程綁定的内容
    remove():将目前線程和内容解綁
  内部維護了map集合
    map.put(目前線程,内容);
    map.get(目前線程)
    map.remove(目前線程)
/
DButils:
  1.建立queryrunner
  2.編寫sql
  3.執行sql
QueryRunner:
  構造:
    new QueryRunner(DataSource ds):自動事務
    new QueryRunner():手動事務
  常用方法:
    update(Connection conn,String sql,Object ... params):執行的cud操作
    query(Connection conn....):執行查詢操作
  注意:
    一旦使用手動事務,調用方法的時候都需要手動傳入connection,并且需要手動關閉連接配接

事務總結:
  事務的特性:★★★
    ACID
    原子性:事務裡面的操作單元不可切割,要麼全部成功,要麼全部失敗
    一緻性:事務執行前後,業務狀态和其他業務狀态保持一緻.
    隔離性:一個事務執行的時候最好不要受到其他事務的影響
    持久性:一旦事務送出或者復原.這個狀态都要持久化到資料庫中
  不考慮隔離性會出現的讀問題★★
    髒讀:在一個事務中讀取到另一個事務沒有送出的資料
    不可重複讀:在一個事務中,兩次查詢的結果不一緻(針對的update操作)
    虛讀(幻讀):在一個事務中,兩次查詢的結果不一緻(針對的insert操作)
  通過設定資料庫的隔離級别來避免上面的問題(了解)
    read uncommitted    讀未送出  上面的三個問題都會出現
    read committed    讀已送出  可以避免髒讀的發生
    repeatable read   可重複讀  可以避免髒讀和不可重複讀的發生
    serializable    串行化   可以避免所有的問題
  
  
  了解
    示範髒讀的發生:
      将資料庫的隔離級别設定成 讀未送出
        set session transaction isolation level read uncommitted;
      檢視資料庫的隔離級别
        select @@tx_isolation;
    避免髒讀的發生,将隔離級别設定成  讀已送出
      set session transaction isolation level read committed;
      不可避免不可重複讀的發生.
    
    避免不可重複讀的發生 經隔離級别設定成 可重複讀
      set session transaction isolation level  repeatable read;
      
    示範串行化 可以避免所有的問題
      set session transaction isolation level  serializable;
      鎖表的操作.
    
  四種隔離級别的效率
    read uncommitted>read committed>repeatable read>serializable
  四種隔離級别的安全性
    read uncommitted<read committed<repeatable read<serializable
    
  開發中絕對不允許髒讀發生.
    mysql中預設級别:repeatable read
    oracle中預設級别:read committed

  java中控制隔離級别:(了解)
    Connection的api
      void setTransactionIsolation(int level) 
        level是常量
 

///
///

///
上午回顧:
jsp的設計模式
  model1:jsp+javabean(了解)
  model2:jsp+servlet+javabean
    jsp:展示資料
    servlet:接受請求,處理業務邏輯
    javabean:封裝資料,封裝對資料的通路
MVC:
  将業務邏輯 代碼 顯示相分離
  M:model 模型  封裝資料,封裝對資料的通路
  V:view  視圖  展示資料,目前jsp擔任
  C:ctrl  控制  接受請求
三層架構:
  web:
    作用:
      展示資料
      
      接受請求
      調用service
      頁面跳轉,資訊的生成
  service
    作用:
      處理業務邏輯
      調用dao
  dao
    作用:
      對資料庫的curd操作
///
反射:
  1.擷取class對象
  2.通過class擷取構造器
  3.通過class擷取字段
  4.通過class擷取指定的方法
  5.可以執行方法
/
事務:
  就是一件完整的事情,可以包含多個操作單元,這些單元要麼全部成功,要麼全部失敗
mysql中的事務(了解)
  預設自動送出. 
  控制事務:
    1.關閉自動事務
    2.手動打開一個事務
      start transaction;
      commit;
      rollback;
java中事務:(★)
  Connection的api
    setAutoCommit(false):手動開啟事務
    commit():事務送出
    rollback():事務復原
/
如何使用同一個connection
  1.向下傳遞
  2.将連接配接綁定到目前線程
    ThreadLocal
      set(Object value)
      Object get()
      remove()
//
DBUtils中事務控制
  QueryRunner:
    構造:
      new QueryRunner(Datasource ds)://自動事務.調用方法的不需要傳入connection,資源不用我們釋放.
      new QueryRunner()://手動事務.調用方法的必須傳入connection,需要手動送出事務或者復原事務.必須手動的釋放資源
/
事務的特性 ★★★
  ACID
  原子性 一緻性 隔離性 持久性
不考慮隔離性會出現的讀問題★★
  髒讀  不可重複度 虛讀
資料庫的隔離級别
  read uncommitted 讀未送出 不能避免任何問題
  ★read committed   讀已送出 避免髒讀
  ★repeatable read 可重複度 避免髒讀和不可重複讀的發生
  serializable 串行化 避免所有的問題
  
/
servlet
  會建立一個servlet
  會更改web.xml
  servletContext:
    全局管理者 上下文
      資源共享(域對象)
      擷取資源檔案
        getRealPath()
        getResourceAsStream()
      擷取mimetype
        getMimeType()
  面試題:
    serlvet的生命周期
rr
  response:往浏覽器寫東西
    重定向:response.sendRedirect(絕對路徑)
    定時重新整理:refresh
      setHeader("refresh","秒數;url=跳轉路徑")
      meta
    getWriter():字元流
    getOutputStream():位元組流
    檔案下載下傳:
      setContentType(mime類型)
      setHeader("content-disposition","attachment;filename="+檔案名);
      
  request:擷取浏覽器發送過來的資料
    擷取參數:3個
    中文亂碼:
      通用的方式
        new String(名字.getBytes("iso-8859-1"),"utf-8");
      針對post請求
        request.setCharacterEncoding("utf-8");
    請求轉發(域對象)
      request.getRequestDispatcher(内部路徑).forward(..);
      
cookie和session
  cookie:浏覽器端會話技術
    常用方法:
      new Cookie(String key,String value);
      寫回浏覽器
        response.addCookie(Cookie c)
      擷取cookie
        request.getCookies()
      cookie的api
        getName()
        getValue()
        
        setMaxAge(int 秒)
        setPath(String path)
  session:伺服器端的會話技術
    常用方法:
      擷取session
        request.getSession
    域對象:私有的資料
      建立:
      銷毀:
        伺服器非正常關閉
        session逾時
        手動删除:
          session.invalidate()
    
jsp el jstl
  jsp的指令 include taglib
  jsp的内置對象 面試題
  jsp:forward
  jsp:include
  
  el:全部
    擷取資料
    執行運算
    
  jstl:
    if
    foreach