0

我正在尝试使用自定义 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中的一个错误

4

1 回答 1

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>

此时运行服务构建器以生成持久层和服务层。

您必须使用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 的服务构建器,这是您可以做的“不太糟糕”的事情。

于 2014-04-09T12:58:35.730 回答