天天看點

7.Java基礎(SQL&JDBC&事務)

1.SQL簡明說明【以MySQL為例】

1.建表(複制表結構和内容)DDL
  Create table xxx as  select * from yyy  把yyy的内容和結構複制到xxx中了
  alter table 舊表名 rename to 新表名
  alter table xx add(name int ,id int)//可多個同時修改
   新增限制和已有資料沖突的時候,修改失敗
   增加一列,要加上預設值,否則會出錯
       
2.限制:Check :檢查,指定一個布爾表達式,用于指定對應列的值必須滿足該表達式
但是mysql并沒有這個限制;mysql 的information--schema 庫中的table--Constraints 儲存了限制資訊

3.索引:
    預設指定一個列名的索引,可多列使用一個索引
    sysql特有的删除索引 drop index 名稱
    一個表中隻能有一個主鍵索引
    create  index  索引名  on 表名(列名)
    drop index 索引名 on 表名
4.級聯:删除 當主表記錄從表記錄參照時,主表記錄不能被删除,隻能先從表中參照主表的内容全部删除後,記錄才能删除;
    foregin ... on delete Cascade //級聯操作或者  on  delete set null
    主表删除記錄,外表把對應的資料清空,或置空
    定義外鍵限制時定義主表和從表的級聯操作 on delete cascade 或者 on delete set null
5.視圖:本質上就是一組被命名的指令行語句
    create or replace view 試圖名
    as subquery
    一般不能用來修改視圖資料 可以通過with check option 強制指定
注意:
    unique 允許擁有多個空值 null != null
6.文法:
    distinct 去處重複行,(後面字段的重複),而不是比較對應記錄在資料裡面是否重複
    is null  指定值等于一
    sql中判斷兩個字段是否相等 使用單等号 =
    不能使用 <>
    指派使用:=
    标準sql 并沒有提供\具有轉義的作用
    like'\_%' escape '\'
    預設升序排列
    條件判斷文法:
         if(isnull,expr1,expr2) ?:
         case value
         when compare1 then result1
         when compare2 then result2
         ...
         else result3
         end
         第二種用法:
         case
         when boolean then result1
         when boolean2 then result2
         ...
         else
         result 3
         end
    having 與where的差別:
        1.不能在where 自居中過濾組,where子句僅用來過濾行,過濾組必須使用having
        2.不能在where 子句使用主函數,having子句才能使用組函數
    子查詢:
        1.from 後面作為臨時視圖 必須起一個别名
        2.where 後面過濾條件
        =any()  :in 相似
        >any() :大于最小值即可
        <any():小于最大值即可
    集合運算:
        1.兩個結果即所包含的資料列的數量必須相等
        2.兩個結果即所包含的資料列的資料類型也必須一一對應
            union 合
            minus 差 select 列 form表 minus select 列from 表 注意: mysql并不支援minus
            select 列 from 表 where(,,,) not in (select ,,,from 表名)
            intersect mysql也不支援
            select 列,列 from表 join 表on 列=列and 列=列
7.函數
    sin
    char_length
    Date_ADD(日期,interval 2 month)
    ADDDATE(日期,日)
    curdate()
    curtime()
    md5()
    isnull(列)
  但是盡量不要使用資料庫中的特定函數,否則不能跨平台
           

2.JDBC:

1.使用JDBC對象作用:
    callablestatement preparecall
    Connection:關于供職事務的方法:
    SavePoint setpoint() 建立一個節點
    SavePoint setpoint(String name)
    settransactionIsolation(int level 設定事務的隔離級别)
    rollback() 復原事務
    rollback(savepoing )将事務復原到指定的儲存點
    setAutoCommit(boolean) 是否關閉自動送出
    commit()送出
    mysql的驅動并不能支援所有的api方法
    executeLargeUpdate();//支援大于integer.maxValue的更新,但是驅動并沒有實作
    jdbc:指定資料庫驅動:// hostname:port/database
2.使用說明
    connection statemtn result 都重寫了autocloseable 接口 可以通過try語句關閉,try(){}即可
    preparestatemt 的引入:
        1加快執行效率預編譯
        2.防止sql 注入
        3.無須拼接字元串
  注: 占位符隻能代表普通值,不能用來代指列名 和表名 更不能代指關鍵字
3.存儲過程定義和JDBC調用:
    重新定義分隔符
    delimiter//
    create procedure xxx(a int ,b int ,out c int )
    begin
    set c =a+b;
    end
    ;
    //
    {call xxx(?,?,?)}
    st.registeroutparameter(3,Types.INTEGER)
    resultset 被稱為可以可滾動的結果集
  注:可以通過查詢結果重新更新,重新寫入到資料庫中;通過 updatexxx() 然後通過updaterRow 送出修改該
注: a.如果建立可更新的結果即,則使用查詢語句的資料通過長隻能來一個資料表,而且查詢結果即中的資料類必須包含主鍵列,否則會引起更新失敗
     b. blob Clob 以流的形式進行讀寫
4.結果集
    resultsetMetadata 可以通過resultset 的getMetaData()方法得到,
    常用方法:
    int getColumnCount() //傳回列數量
    String getColumnName(int column)//傳回列名
    int getColunmType(int) 傳回指定列的傳回類型
    resultsetMetadata的使用增大了系統的開銷,如果已經知道每列的類型可以 省略
    rowset 預設可滾動、可更新、可序列化的、可離線 ,已經将資料集度讀到記憶體,進行離線操作,操作完成後在同步到底層資料源
    rowset  的實作類 jdbcrowset(内部專用,以後可能删除) 沒有廣泛推廣,在java1.7中增加 rowsetProvider 用來擷取rowsetfactory 通過,rowsetfactory來得到 rowset,
    rowsetfactory.createJdbcRowSet()
    cachedRowset()
    等得到rowset可以通過seturl,setusername,setpassword
    使用resultset 的弊端:
    1.将resultset 結果集寫入javabean中,比較麻煩
    2.直接将結果集顯示,但是connection要一直打開,或者不能出現不可控情況
    rowset 可以很好的解決
    cachedRowset  crs .populate(result);// 對 resultset進行重新裝載為rowset
    并且rowset 可更新、可序列化的、可離線
    rs.updateString("列名","更改後";)
    rs.updateRow();
    con.setAutoCommit(false);
    rs.acceptChanges(conn);對連接配接中出現的變化,送出給資料庫
    未防止大量資料讀入記憶體, rowset 提供分頁功能
    rowset.setjpagesize()
    rowset.populate(rs,起始頁碼)
    rowset.nextpage() //conn 并沒有關閉
    rowset.priviouspage()//conn 并沒有關閉
5.手寫JDBC連接配接程式
   a.過程
    加載驅動類:jdbc具體實作類//    驅動類:就是實作的具體jdbc的jar檔案
    建立連接配接
    發送sql 查詢
    得到查詢結果
    實作了Driver接口
   b.實作
    Class.forName("")//根據具體路徑加載指定類
    DriverManager.getConnection(Url)//通過接口DriveManager來建立使用者和驅動之間的連接配接
    conn.creteStatemnt();//執行語句,傳回結果
    sql="";
    stmt.execute(sql);
   注意:
    建立連接配接就是一個socket連接配接,建立連接配接是比較耗時的
    連接配接對象内部其實包含了socket對象,是一個遠端的連接配接,比較好使,這是connection對管理的一個要點
    真正開放中,為了提高效率,都會使用連接配接池來管理連接配接對象
    statement接口:
        statement(父)
        PreparedStatement(子)預編譯 效率高,防止sql注入
        CallableStatement(子)
        statement隻能以拼接字元串的形式傳參
        容易發生sql注入的危險
    sql中使用占位符,?必須與前面的類型相同
        PreparedStatement ps = con.preparstament()
        ps.setString(1,"");//參數索引是從1開始而不是0
        ps.setString(2,"1234")
        hibernate是從0開始的
        setobject(1,"")
        setDate引用的是sql.date
    execute 的重載
        excute()傳回boolean是否有結果集
        excuteUpdate 傳回更新的行數 //insert update delete
        excuteQuery()//select
    ResultSet 疊代器
        ResultSet set = ps.excuteQuery();
        實際就是一個疊代器
        與jdbc相關,如果連接配接終端ResultSet将不存在
        while(re.next())是否含有下一條,從0開始
        rs.getint(1)取出第一列
        rs.getString(2)二列..
    關閉連接配接:
        finally{
            conn.close();
        }
        resultset->statment->connection
        将三個trycatch分開寫;一行的一列
    Batch
        對于大量的批處理,建議使用statement,因為prepare
        statement預編譯處理有限,如果資料量特别大時,會出現異常
        conn.setAutoCommit(false);//設為手動送出
        stmt o conn.createStatement();
        for(int if=0;i<20000;i++){
        stmt.addBatch(" insert into t_user(t_user()valuse('gao'+i,now()))")
        }
        stmt.excuteBatch();
    事務:
        conn.rollback()
        conn.setAutoCommit()//預設true 自動送出
        rollback寫在catch中
    Clob和Blob:
        CLOB(charater large object)
          大量的文本資料  常通過流的形式處理
          在資料庫中有相應的類型:tinytext、text、mediumtext、longtext 存儲 文章,小說
        ps.setColb(2,new FileRead( new FIle("sjk:/jkjk")))//   将程式中字元傳入到資料庫中的clob
            ps.setColb(2,new BufferedReader(Nnew InputStaremReader(new ByteArrayinputStream("字元串".getbytes()))))
            clob c = rs.getClob("myinfo";
                reader r = c.getCharcterSteram();
                while((temp=r.read())!=-1)
                {
                (char) temp;
                }
            )
        大檔案一般直接存在檔案伺服器中,很少使clob和blob
        tinyBolb、blob、mediumblob、longblob 存儲小圖檔、電影 可以将文本檔案流輸入到資料庫中
        控制台無法展示圖檔
        資源檔案 db.properties  folder
        讀取配置檔案 使用properties pros =null;//讀取和
        static Properties pros =  null;//可以幫助讀取和處理資源檔案中的資訊
        static {
               pro = new properties();
               pro.load(Thread.currentThread().getContextClassLoader.getResourceAsSteraem("db.properties"))
        }
        pro.getPropertieS("名稱")
           

3.事務

要麼同時成功,要麼同時失敗,是一個執行單元,起始于DML語句
結束于:
1.commit 或 rollback
2.ddl語句 Create table 自動執行commmit
3.執行dcl語句 grant語句 自動執行commmit
4.斷開與資料庫的連接配接
5執行一條dml但失敗,自動執行rollback語句
事務的四大特點ACID
原子性 :同時執行,同時失敗
一緻性:一條語句操作失敗,會滾到原有狀态
隔離性: 事務運作過程中産生的結果不被别人檢視
持久性:事務成功結束,将一直保持在硬碟中
級别:讀取已送出(預設)

送出: 顯示送出: commint
       隐式送出: 執行ddl 或者dcl
復原: 顯式復原 rollback
       自動復原: 系統錯誤 或者強制退出
一個mysql 指令行裝口代表一個連接配接session,在改穿夠設定的set autocommit =0,相當于關閉該練級的session 的自動送出,對其他連接配接不會産生影響
臨時使用一下 事務 但不關閉自動送出

mysql 可以使用begin 或者start transaction  
可以通過設定savepoint 儲存中間點
savepoint a;
rollback to a ; 復原到中間點
普通的送出奧、復原都會結束目前事務,但會滾到指定中間點因為依然處在事務中,是以不會結束目前事務
JDBC管理事務 通過connection
conn.setAutoCommit(false);
conn.commint;
conn.rollback;
實際上,當Connection 遇到一個未處理的sqlexception異常時,系統将會非正常退出,事務也會自動復原,但如果程式捕獲了該異常,則需要
setsavepoint()  Connection - savepoint
setsavepoint(String)  Connection
rollback(savepoint  save)
批量更新: 在resultsetmetadata中 檢視是否支援  supportsBatchUpdate();
批處理 要當成事務進行處理
stmt.addBatch(sql1);
stmt.addBatch(sql2);
最新驅動中并不支援excuteLargeBatch();


           

4.連接配接池

DBCP: apache 開發 ,但是依賴另外的jar檔案,可整合到Tomcat伺服器上,也可以和應用和程式獨立使用

C3P0:hibernate 推薦使用這個連接配接池,可以自動關閉不再使用的連接配接,不用導入 其他依賴的jar 檔案
           

5.ORM

ORM基本思想(object relationship Mapping)
    表結構跟類對應,表中的字段和類的屬性對應,表中記錄和對象對應
SORM架構(自定義的)
    使用list<Object[]> 存儲多條記錄
    使用map封裝list<map> map<map>
    使用javabean list<bean>   最常用
    map<string ,object>
    string 代指列名
    object 代指行列值
優勢:通過反射機制進行對應
           

繼續閱讀