這篇博客來自我自己的博客,歡迎多點上來wishselfly's blog
在一些實際的開發(fā)環(huán)境中谆膳,我們查詢一張表叭爱,可能需要關聯(lián)到另外一張表的信息,不是那種已經存在于數(shù)據(jù)庫表的字段中的數(shù)據(jù)漱病,可能是需要統(tǒng)計的一些數(shù)據(jù)买雾,例如我需要知道這個用戶在系統(tǒng)下面到底有多少中角色,寫成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=?
對于像上述查詢語句中杨帽,這種查出來為純數(shù)字的變量漓穿,而且不存在于實體當中的變量,我們可以通過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設置額外捕獲的參數(shù)的類型
q.addScalar("role_count", StandardBasicTypes.INTEGER);
//獲取到的內容為Object[]{AccountModel, role_count}
return q.uniqueResult();
StandardBasicTypes里面有很多基本類型:
還記得我們之前聲明的用戶和角色的關聯(lián)表:
現(xiàn)在我們需要聲明AccountRoleRelModel.java注盈,我需要在里面Join上RoleModel和AccountModel的實體:
/**
* 用戶與角色的關聯(lián)表的實體
*/
@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]).
*/
//根據(jù)上述定義,addJoin的第一個參數(shù)胧砰,應該是需要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]>乌妒,順序根據(jù)上面addEntity汹想、addJoin的順序產生對應的Object[]內用的順序
return (List<Object[]>) q.list();
}
}