我正在尝试使用自定义sql从liferay 6.0.6中的多个表中获取数据,但是现在我只能从一个表中显示数据。任何人都知道该怎么做。谢谢
更新: 我确实找到了这个链接http://www.liferaysavvy.com/2013/02/getting-data-from-multiple-tables-in.html,但对我来说它没有用,因为它给出了一个错误BeanLocator为null,而且似乎它是liferay 6.0.6中的一个错误
答案 0 :(得分:3)
以下技术也适用于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>
此时运行服务构建器以生成持久性和服务层。
您必须使用自定义SQL查询as described by Liferay's Documentation从多个数据库中获取信息。
以下是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
!小心:豆子和田地的领域&#39;查询返回的名称必须匹配。
<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。
注意:这是黑客攻击。这不是一种检索数据的完全干净的方法,但它是“不那么糟糕”的#34;如果您想使用Liferay的服务构建器,您可以这样做。