2013-07-10 163 views
3

我需要從數據庫中選擇公司從其活動地址(address.address_status_id = 1)。如果地址不活動,地址欄應包含空值。加入子查詢

下面的查詢不正是我想要的:

select c.id, c.name, a.id, a.street 
from company c 
left join 
(select * from address where address_status_id = 1) a 
on c.id = a.company_id 

我用Java/QueryDSL嘗試這樣做:

JPAQuery query = new JPAQuery(entityManager); 
query = query.from(qCompany); 
query = query.leftJoin(company.addresses, new JPASubQuery().from(qAddress)  
.where(qAddress.addressStatusId.eq(AddressStatuss.ACTIVE.asBigDecimal())).list(qAddress)); 

但是JPA(並因此JPAQuery在QueryDSL)不支持a subquery in a JOIN clause

有沒有一種方法來重新修改SQL語句,以便它可以用JPA/QueryDSL表示?

編輯:如果它有所作爲,我們正在使用Oracle DB和Hibernate JPA提供程序。

回答

5

也許這樣

select c.id, c.name, a.id, a.street 
from Company c 
left join c.addresses a on a.addressStatusId = 1 

和Querydsl

query.from(c) 
    .leftJoin(c.addresses, a) 
    .on(a.addressStatusId.eq(1)) 
    .list(c.id, c.name, a.id, a.street) 
+0

Ouch,我們使用的是版本2.9,並且ON方法似乎不存在於其中。我看到它在3.2.0。在JPAQueryBase中。我們之前嘗試更新,但是在看到我們的代碼編譯所做的更改後再推遲。也許ON方法取代了WITH方法? –

+0

是的,.with(a.addressStatusId.eq(1))正是我想要的! –

+0

是的,'開'用'替換'。 –

1

我會使用Oracle DB JDBC。你可以得到那個here

根據你想要構建一個Applet或應用程序,你將不得不在微型和OCI版本的JDBC之間進行選擇。有關該here的更多信息。

我會假設你正在構建一個應用程序,因此我將在這個例子中使用OCI。

Class.forName("oracle.jdbc.OracleDriver"); 
Connection con = null; 
Statement stmt = null; 
ResultSet rset = null; 
try{ 
    con = DriverManager.getConnection("jdbc:oracle:oci:@//192.168.1.100", "user", "password"); 

    stmt = con.prepareStatement(); 

    rset = stmt.executeQuery("SELECT name, address, phonenumber FROM tbl_comanies"); 

    while(rset.next()){ 
     String name = rset.getString(1); 
     String address = rset.getString(2); 
     int phonenumber = rset.getInt(3); 
     //The number passed to the get...()-Method is the place in the SQL query. (Here, name=1, address=2, phonenumber=3) 
    } 
} catch (SQLException ex) { 
    System.out.println(ex.getMessage()); 
} finally { 
    try { 
     if(rset != null) 
      rset.close(); 
     if(stmt != null) 
      stmt.close(); 
     if(con != null) 
      con.close(); 
    } 
} 

希望這可以幫助你。

問候, 安迪

+0

太舊校園,JDBC就是出在我們的應用程序問題。 :) –

+0

你能解釋爲什麼它太舊了嗎?或者它爲什麼沒有問題? – AndMim

+1

有很多原因,這是完全不適合大型應用程序的原因,以及爲什麼ORM方法不再適用。您必須手動將您的ResultSet映射到您的Java業務類 - 這是一個容易出錯的噩夢。您的表和列名稱在字符串中進行了硬編碼,沒有編譯時間驗證和類型安全性。如果表格或列名稱在數據庫中發生了變化,那麼該怎麼辦?在運行特定代碼之前,您不會知道有什麼問題。你的代碼是依賴於數據庫的,如果你以後決定從Oracle切換到MySQL,該怎麼辦? –