2014年4月8日 星期二

sql 取得count 做 排序

SELECT a.fId,a.f志工Id,a.f志工名稱,a.f服務時數,dense_rank() over (PARTITION BY a.f志工Id  ORDER BY a.fId) Rank
FROM iLive.dbo.t志工服務 as a
INNER JOIN (SELECT TOP 10 f志工Id, count(*) as c
FROM iLive.dbo.t志工服務
GROUP BY f志工Id
ORDER BY count(*) desc) as b
ON a.f志工Id = b.f志工Id
ORDER BY b.c DESC

2014年4月1日 星期二

Liferay custom-sql 與JAVA 分離的 query做法

參考來源:
http://www.liferay.com/zh/community/wiki/-/wiki/Main/Custom+queries+in+Liferay
http://kamalkantrajput.blogspot.tw/2009/07/how-to-use-custom-sql-in-liferay.html
http://www.liferay.com/zh/community/wiki/-/wiki/Main/Service+Builder+Finders
http://www.liferay.com/zh/community/forums/-/message_boards/message/13117839



步驟1:
現在建立service.xml
<service-builder package-path="aaa.bbb.ccc">
<author>ddd</author>
<namespace>eee</namespace>

<entity name="MyData" uuid="true" local-service="true" remote-service="false">
<column name="mydataId" type="long" primary="true" />
<column name="userName" type="String" />
<column name="userAge" type="int" />
<column name="userPhone" type="String" />
<column name="userEmail" type="String" />
<column name="createDate" type="Date" />
<column name="modifiedDate" type="Date" />
</entity>
</service-builder>

步驟2:
建立一個finder類別
在 docroot/WEB-INF/src/aaa.bbb.ccc.service.persistence底下
建立一個 MyDataFinderImpl 的class 繼承到 BasePersistenceImpl<MyData>
命名一定得     "***FinderImpl"  否則他會不認識這個class; 無法產生子類別;
先build吧!



步驟3:
在 docroot/WEB-INF/src 底下
建立一個custom-sql  的 folder
裡面放兩個xml檔案 default.xml   mydata.xml

default.xml
<?xml version="1.0" encoding="UTF-8"?>
<custom-sql>
<sql file="custom-sql/mydata.xml" />
</custom-sql>


mydata.xml
<?xml version="1.0" encoding="UTF-8"?>
<custom-sql>
<sql
id="aaa.bbb.ccc.service.persistence.MyDataFinder.findLatestMyData">
<![CDATA[
SELECT *
FROM
ccc_mydata
ORDER BY
createDate
DESC
LIMIT ?
]]>
</sql>
</custom-sql>
這裡是取創立日期最近的前幾筆;
?符號 是有點像 PreparedStatement 用問號帶參數;

黃色字體 是待會在finderImpl類別會使用到的id識別  method;

步驟4:
public class MyDataFinderImpl extends BasePersistenceImpl<MyData> implements MyDataFinder {

public static final String FIND_LATEST_MYDATA = MyDataFinder.class.getName()
+ ".findLatestMyData";

public List findByTopCreateDate(int delta) throws SystemException {
Session session = null;
try {
session = openSession();

String sql = CustomSQLUtil.get(FIND_LATEST_MYDATA);
SQLQuery q = session.createSQLQuery(sql);
q.addEntity("MyData", MyDataImpl.class);

QueryPos qPos = QueryPos.getInstance(q);

qPos.add(delta);

return (List)q.list();
}catch (Exception e){
throw new SystemException(e);
}
finally {
closeSession(session);
}
}
}
一定要先  implements MyDataFinder
否則你會花好多時間才知道原來少了這個動作;(過乃倫~)

.findLatestMyData這裡就是對應到mydata.xml 裡面的sql id
這樣他就能取到你的sql 查詢字串;

delta 就是待會要讓使用者輸入變數代為參數用的;
想要取得前幾筆 都行;
更多的技巧 見資料來源
Impl類的 記得修改完後 要重新build




步驟5:
在自己的MyDataLocalServiceImpl 建立一個method:

public List findByTopCreateDate(int delta, int begin, int end) throws SystemException{
    return MyDataFinderUtil.findByTopCreateDate(delta);
    }
就可以使用剛剛建立的Finder method;





步驟6:
接下來就到尾聲了;
在自己的jsp 頁面試試看 是否有成功;

List mdList = MyDataLocalServiceUtil.findByTopCreateDate(deltaSetLatest, searchContainer.getStart(), searchContainer.getEnd());

if(mdList.size() > 0){
for(int j = 0; j < mdList.size();j++){

MyData md = (MyData)mdList.get(j);
Date mdCreateDate = md.getCreateDate();

System.out.print(mdCreateDate + "\r\n");
}
}