我正在尝试使用自定义 sql 从 liferay 6.0.6 中的多个表中获取数据,但现在我只能显示一个表中的数据。有人知道该怎么做吗。谢谢
更新:我确实找到了这个链接http://www.liferaysavvy.com/2013/02/getting-data-from-multiple-tables-in.html但对我来说它不起作用,因为它给出了一个错误 BeanLocator is null,并且看来这是liferay 6.0.6中的一个错误
我正在尝试使用自定义 sql 从 liferay 6.0.6 中的多个表中获取数据,但现在我只能显示一个表中的数据。有人知道该怎么做吗。谢谢
更新:我确实找到了这个链接http://www.liferaysavvy.com/2013/02/getting-data-from-multiple-tables-in.html但对我来说它不起作用,因为它给出了一个错误 BeanLocator is null,并且看来这是liferay 6.0.6中的一个错误
以下技术也适用于 liferay 6.2-ga1。
我们将考虑我们在 portlet 项目fooproject
中。假设您有两个表:文章和作者。以下是您的实体service.xml
:
<entity name="Article" local-service="true">
<column name="id_article" type="long" primary="true" />
<column name="id_author" type="long" />
<column name="title" type="String" />
<column name="content" type="String" />
<column name="writing_date" type="Date" />
</entity>
<entity name="Author" local-service="true">
<column name="id_author" type="long" primary="true" />
<column name="full_name" type="String" />
</entity>
此时运行服务构建器以生成持久层和服务层。
您必须使用Liferay 文档中描述的自定义 SQL 查询来从多个数据库中获取信息。
这是您的代码fooproject-portlet/src/main/ressources/default.xml
:
<?xml version="1.0"?>
<custom-sql>
<sql file="custom-sql/full_article.xml" />
</custom-sql>
以及中的自定义请求fooproject-portlet/src/main/ressources/full_article.xml
:
<?xml version="1.0"?>
<custom-sql>
<sql
id="com.myCompany.fooproject.service.persistence.ArticleFinder.findByAuthor">
<![CDATA[
SELECT
Author.full_name AS author_name
Article.title AS article_title,
Article.content AS article_content
Article.writing_date AS writing_date
FROM
fooproject_Article AS Article
INNER JOIN
fooproject_Author AS Author
ON Article.id_author=Author.id_author
WHERE
author_name LIKE ?
]]>
</sql>
</custom-sql>
如您所见,我们要获取作者姓名、文章标题、文章内容和文章日期。
因此,让我们让服务构建器生成一个可以存储所有这些信息的 bean。如何 ?通过将其添加到service.xml
! 注意:bean 的字段和查询返回的字段名称必须匹配。
<entity name="ArticleBean">
<column name="author_name" type="String" primary="true" />
<column name="article_title" type="String" primary="true" />
<column name="article_content" type="String" />
<column name="article_date" type="Date" />
</entity>
注意:在这里定义哪个字段是主要的并不重要,因为 ArticleBean 表中永远不会有任何内容。这一切都是为了在生成 Bean 时不让服务构建器抛出异常。
然后必须实现finder 方法。为此,请创建类com.myCompany.fooproject.service.persistence.impl.ArticleFinderImpl
。使用以下内容填充它:
public class ArticleFinderImpl extends BasePersistenceImpl<Article> {
}
使用正确的import
语句并运行服务构建器。让我们让该类实现服务构建器生成的接口:
public class ArticleFinderImpl extends BasePersistenceImpl<Article> implements ArticleFinder {
}
并用实际的 finder 实现填充它:
public class ArticleFinderImpl extends BasePersistenceImpl<Article> implements ArticleFinder {
// Query id according to liferay's query naming convention
public static final String FIND_BY_AUTHOR = ArticleFinder.class.getName() + ".findByAuthor";
public List<Article> findByAuthor(String author) {
Session session = null;
try {
session = openSession();
// Retrieve query
String sql = CustomSQLUtil.get(FIND_BY_AUTHOR);
SQLQuery q = session.createSQLQuery(sql);
q.setCacheable(false);
// Set the expected output type
q.addEntity("StaffBean", StaffBeanImpl.class);
// Binding arguments to query
QueryPos qpos = QueryPos.getInstance(q);
qpos.add(author);
// Fetching all elements and returning them as a list
return (List<StaffBean>) QueryUtil.list(q, getDialect(), QueryUtil.ALL_POS, QueryUtil.ALL_POS);
} catch(Exception e) {
e.printStackTrace();
} finally {
closeSession(session);
}
return null;
}
}
然后,您可以从 ArticleServiceImpl 调用此方法,无论是创建本地 API 还是远程 API。
注意:这是黑客。这不是一种完全干净的数据检索方式,但如果您想使用 Liferay 的服务构建器,这是您可以做的“不太糟糕”的事情。