drcmg28484 2011-06-15 17:51
浏览 37
已采纳

帮助处理复杂的依赖关系,排序,过滤和访问控制

I've been wrestling with this code for a while, trying to clean it up but it just doesn't feel right. I have a Model, called Library. Libraries can own books, and the Library Model class has a public books property which is simply an array of Books. The model might look something like this:

Application_Model_Library {
    public $books = null;

    protected $_id;
    protected $_name;

    /* Getters, setters, etc. */
}

I also have a Book model. Users can have access to Books which is defined by a many-to-many table, users_books_permissions.

The library model stores the number of books the current user has access to, which is found using a JOIN on the books table and COUNT(*). Obviously, the library table itself doesn't store this information, so it is a calculated field.

protected $_accessibleBookCount;

All of my models are contained in one file, with (static) mappers built it. For example:

// In the Application_Model_Library class
public static function fetchAll(){
    $db = Zend_Registry::get("db");
    /* etc */
}

However, my pagination plugin needs access to the raw select statement so it can add the LIMIT clause. This is also useful for sorting and filtering. To handle this, fetching a list of books actually requires two calls. The first one creates and returns a select object. This is modified in my controller based on the parameters to add sorting, filtering, and paginating. Then, another method in my Model takes the select object and performs the actual fetching and initialing of objects.

The first method is also responsible for injecting the JOIN that populates the $_accessibleBookCount field.

Fetching a single Library involves getting the select statement from the aforementioned function, adding a WHERE clause so only the library I want is selected, and then feeding this into the method to actually instantiate the Library model object.

Once I have a library object, fetching its books is handled by a method in the Library model called getBooks. If $books is null, then the method populates it. Then, the array is returned. Access to individual books can be achieved because the $books property is public. Upon fetching, the method also uses a JOIN to determine whether the user has access to the book.

However, what if I need to fetch a list of all libraries AND list each library's books at the same time? It's two method calls to get the list of libraries, but then getBooks must be called on each Library. This results in A LOT of repeated queries.

Whew. I want to thank anyone who was able to hold on long enough to get to the end of my post. I'd also like to thank anyone ahead of time for their help.

  • 写回答

1条回答 默认 最新

  • duangan6797 2011-06-15 18:38
    关注

    The only solution I see to fetch all books and libraries in one query is to actually fetch for all books and join with the libraries table. This might or might not be a better solution depending on what you are doing with libraries and books in your program.

    Something like this (in Books model):

    $select = $this->select();
    $select->setIntegrityCheck(false)
           ->from(array("b" => "books"))
           ->join(array("l" => "libraries"),"b.lid = l.id",array("libraryName" => "l.name")) // lid = Library ID in Books table
           ->order("l.name ASC"); // Order by Library Name
    

    You could then do some PHP magic to sort out Libraries and Books (create new objects,arrays, or whatever you want), for instance:

    $libraries = array(); 
    foreach($books as $book) {
      $libraries[$book->libraryName]["books"][] = $book; 
    }
    

    You have to see if it's worth the trouble and is faster/more efficient than SQL queries.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 远程桌面文档内容复制粘贴,格式会变化
  • ¥15 关于#java#的问题:找一份能快速看完mooc视频的代码
  • ¥15 这种微信登录授权 谁可以做啊
  • ¥15 请问我该如何添加自己的数据去运行蚁群算法代码
  • ¥20 用HslCommunication 连接欧姆龙 plc有时会连接失败。报异常为“未知错误”
  • ¥15 网络设备配置与管理这个该怎么弄
  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题