會話(Session)

2018-12-24 22:20 更新

會話是對應用中具體業(yè)務操作觸發(fā)的一系列與數(shù)據(jù)庫之間的交互過程的封裝,通過建立一個臨時通道,負責與數(shù)據(jù)庫之間連接資源的創(chuàng)建及回收,同時提供更為高級的抽象指令接口調(diào)用,基于會話的優(yōu)點:

開發(fā)人員不需要擔心連接資源是否正確釋放;

嚴格的編碼規(guī)范更利于維護和理解;

更好的業(yè)務封裝性;

  • 會話對象參數(shù):

    • 數(shù)據(jù)庫連接持有者(IConnectionHolder):

      指定本次會話使用的數(shù)據(jù)源連接;

    • 會話執(zhí)行器(ISessionExecutor):

      以內(nèi)部類的形式定義本次會話返回結果對象并提供Session實例對象的引用;

  • 開啟會話示例代碼:

    // 使用默認數(shù)據(jù)源開啟會話
    User _result = JDBC.get().openSession(new ISessionExecutor<User>() {
        public User execute(ISession session) throws Exception {
            // TODO 此處填寫業(yè)務邏輯代碼
            return session.findFirst(EntitySQL.create(User.class));
        }
    });
    
    // 使用指定的數(shù)據(jù)源開啟會話
    IConnectionHolder _conn = JDBC.get().getConnectionHolder("oracledb");
    // 不需要關心_conn對象的資源釋放
    IResultSet<User> _results = JDBC.get().openSession(_conn, new ISessionExecutor<IResultSet<User>>() {
        public IResultSet<User> execute(ISession session) throws Exception {
            // TODO 此處填寫業(yè)務邏輯代碼
            return session.find(EntitySQL.create(User.class));
        }
    });
    
  • 基于ISession接口的數(shù)據(jù)庫操作:

    示例代碼是圍繞用戶(User)數(shù)據(jù)實體完成的CRUD(新增、查詢、修改、刪除)操作來展示如何使用ISession對象,數(shù)據(jù)實體如下:

        @Entity("user")
        public static class User extends BaseEntity<User, String> {
    
            @Id
            @Property
            private String id;
    
            @Property(name = "user_name")
            private String username;
    
            @Property(name = "pwd")
            private String pwd;
    
            @Property(name = "sex")
            private String sex;
    
            @Property(name = "age")
            private Integer age;
    
            // 忽略Getter和Setter方法
    
            public static class FIELDS {
                public static final String ID = "id";
                public static final String USER_NAME = "username";
                public static final String PWD = "pwd";
                public static final String SEX = "sex";
                public static final String AGE = "age";
            }
            public static final String TABLE_NAME = "user";
        }
    
    • 插入(Insert):

      User _user = new User();
      _user.setId(UUIDUtils.UUID());
      _user.setUsername("suninformation");
      _user.setPwd(DigestUtils.md5Hex("123456"));
      _user.setAge(20);
      _user.setSex("F");
      // 執(zhí)行數(shù)據(jù)插入
      session.insert(_user);
      
      // 或者在插入時也可以指定/排除某些字段
      session.insert(_user, Fields.create(User.FIELDS.SEX, User.FIELDS.AGE).excluded(true));
      
    • 更新(Update):

      User _user = new User();
      _user.setId("bc19f5645aa9438089c5e9954e5f1ac5");
      _user.setPwd(DigestUtils.md5Hex("654321"));
      // 更新指定的字段
      session.update(_user, Fields.create(User.FIELDS.PWD));
      
    • 查詢(Find):

      • 方式一:通過數(shù)據(jù)實體設置條件(非空屬性之間將使用and條件連接),查詢所有符合條件的記錄;

        User _user = new User();
        _user.setUsername("suninformation");
        _user.setPwd(DigestUtils.md5Hex("123456"));
        // 返回所有字段
        IResultSet<User> _users = session.find(_user);
        // 或者返回指定的字段
        _users = session.find(_user, Fields.create(User.FIELDS.ID, User.FIELDS.AGE));
        
      • 方式二:通過自定義條件,查詢所有符合條件的記錄;

        IResultSet<User> _users = session.find(
                EntitySQL.create(User.class)
                        .field(User.FIELDS.ID)
                        .field(User.FIELDS.SEX), 
                // 設置Order By條件
                Where.create()
                        .orderDesc(User.FIELDS.USER_NAME));
        
      • 方式三:分頁查詢;

        IResultSet<User> _users = session.find(
                EntitySQL.create(User.class)
                        .field(User.FIELDS.ID)
                        .field(User.FIELDS.SEX),
                Where.create()
                        .orderDesc(User.FIELDS.USER_NAME),
                // 查詢第1頁,每頁10條記錄,統(tǒng)計總記錄數(shù)
                Page.create(1).pageSize(10).count(true));
        
      • 方式四:僅返回符合條件的第一條記錄(FindFirst);

        // 查詢用戶名稱和密碼都匹配的第一條記錄
        User _user = session.findFirst(EntitySQL.create(User.class), 
                Where.create(
                        Cond.create()
                                .eq(User.FIELDS.USER_NAME).param("suninformation")
                                .eq(User.FIELDS.PWD).param(DigestUtils.md5Hex("123456"))));
        

      :更多的查詢方式將在后面的 “查詢(Query)” 章節(jié)中詳細闡述;

    • 刪除(Delete):

      • 根據(jù)實體主鍵刪除記錄:

        User _user = new User();
        _user.setId("bc19f5645aa9438089c5e9954e5f1ac5");
        //
        session.delete(_user);
        
        //
        session.delete(User.class, "bc19f5645aa9438089c5e9954e5f1ac5");
        
      • 根據(jù)條件刪除記錄:

        // 刪除年齡小于20歲的用戶記錄
        session.executeForUpdate(
                SQL.create(
                        Delete.create(User.class).where(
                                Where.create(
                                        Cond.create()
                                                .lt(User.FIELDS.AGE).param(20)))));
        
    • 統(tǒng)計(Count):

          // 統(tǒng)計年齡小于20歲的用戶記錄總數(shù)
      
          // 方式一:
          long _count = session.count(User.class, 
                  Where.create(
                          Cond.create()
                                  .lt(User.FIELDS.AGE).param(20)));
      
          // 方式二:
          _count = session.count(
                  SQL.create(
                          Delete.create(User.class).where(
                                  Where.create(
                                          Cond.create()
                                                  .lt(User.FIELDS.AGE).param(20)))));
      
    • 執(zhí)行更新類操作(ExecuteForUpdate):

      該方法用于執(zhí)行ISession接口中并未提供對應的方法封裝且執(zhí)行操作會對數(shù)據(jù)庫產(chǎn)生變化的SQL語句,執(zhí)行該方法后將返回受影響記錄行數(shù),如上面執(zhí)行的刪除年齡小于20歲的用戶記錄:

          int _effectCount =session.executeForUpdate(
                  SQL.create(
                          Delete.create(User.class).where(
                                  Where.create(
                                          Cond.create()
                                                  .lt(User.FIELDS.AGE).param(20)))));
      

    :以上操作均支持批量操作,具體使用請閱讀API接口文檔和相關源碼;

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號