一些Hibernate的用法筆記(2)

這篇博客來自我自己的博客,歡迎多點上來wishselfly's blog

在一些實際的開發環境中,我們查詢一張表,可能需要關聯到另外一張表的信息,不是那種已經存在于數據庫表的字段中的數據,可能是需要統計的一些數據,例如我需要知道這個用戶在系統下面到底有多少中角色,寫成SQL可能是

select {ac.*},
       (select count(*) from account_role_rel where account_role_rel.account_id=ac.id) role_count
       from account ac 
       where
       ac.id=?

對于像上述查詢語句中,這種查出來為純數字的變量,而且不存在于實體當中的變量,我們可以通過addScalar的方式捕獲出來

那么我們在DAO中轉換當前SQL語句查詢結果的代碼如下:

SQLQuery q = session.createSQLQuery(
    "select {ac.*}," +
       "(select count(*) from account_role_rel where account_role_rel.account_id=ac.id) role_count " +
       "from account ac " +
       "where" +
       "ac.id=1"
);
q.addEntity("ac", AccountModel.class);
//可以通過StandardBasicTypes設置額外捕獲的參數的類型
q.addScalar("role_count", StandardBasicTypes.INTEGER);
 
//獲取到的內容為Object[]{AccountModel, role_count}
return q.uniqueResult();

StandardBasicTypes里面有很多基本類型:


還記得我們之前聲明的用戶和角色的關聯表:



現在我們需要聲明AccountRoleRelModel.java,我需要在里面Join上RoleModel和AccountModel的實體:

/**
* 用戶與角色的關聯表的實體
*/
@Entity
@Table(name = "account_role_rel")
public class AccountRoleRelModel {
    private Integer id;
    private AccountModel account;
    private RoleModel role;
 
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Integer getId() {
        returnn this.id;
    }
 
    @OneToOne    //這里可以改成ManyToOne,相對,下面的JoinColumn需要加上insertable=false, updatable=false
    @JoinColumn(name = "account_id", referencedColumnName = "id")
    public AccountModel getAccount() {
        return this.account;
    }
 
    @OneToOne
    @JoinColumn(name = "account_id", referencedColumnName = "id")
    public RoleModel getRole() {
        return this.role;
    }
 
    //setter省略
}

這種時候,我們在編寫DAO的時候,我們可以通過addJoin加入對應實體的映射:

@Repository()
public class AccountRoleRelDAO {
 
    @PersistenceContext
    public EntityManager em;
 
    @Transactional(readOnly = true)
    public List<Object[]> getCashAccount(int accountId) {
        Session session = em.unwrap(Session.class);
        SQLQuery q = session.createSQLQuery(
                "select {account_role_rel.*}," +
                        "{account.*}," +
                        "{role.*} " +
                        "from account_role_rel " +
                        "inner join role on "  +
                        "role.id=account_role_rel.role_id " +
                        "inner join account on " +
                        "account.id=account_role_rel.account_id " +
                        "where account_role_rel.account_id=:accountId"
        );
        q.setParameter("accountId", accountId);
        q.addEntity("account_role_rel", AccountRoleRelModel.class);
 
        /* public abstract SQLQuery addJoin(String tableAlias, String path)
         * Declare a join fetch result.
         * Parameters:
         * tableAlias - The SQL table alias for the data to be mapped to this fetch
         * path - The association path ([owner-alias].[property-name]).
         */
        //根據上述定義,addJoin的第一個參數,應該是需要join的表在SQL語句中的名字,如果我們給對應表聲明了別名的話,這里填的應該是別名
        //后面應該是主表在SQL中的名字,有別名用別名,然后.后面接實體中,Join的模型的變量的名字
        //例如AccountRelModel中我們聲明AccountModel Join的變量名為account
        //因此這里填的是account_role_rel.account
        q.addJoin("account", "account_role_rel.account");
        //同上
        q.addJoin("role", "account_role_rel.role");
        //返回的內容List<Object[AccountRelModel, AccountModel, RoleModel]>,順序根據上面addEntity、addJoin的順序產生對應的Object[]內用的順序
        return (List<Object[]>) q.list();
    }
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容