简体   繁体   中英

Query Object Pattern (Design Pattern)

I need to implement a Query Object Pattern in Java for my customizable search interface (of a webapp I'm writing).

Does anybody know where I can get an example/tutorial of Query Object Pattern (Martin Fowler's QoP)?

Thanks in Advance

ADDITION How to add a Query Pattern to an existing DAO pattern?

The word "pattern" in the "Query Object Pattern" is (IMHO) misplaced. It's not a real design pattern. The "Query Object" is just another example of the Interpreter Pattern . The legacy Hibernate Criteria API and the modern JPA2 Criteria API are an excellent examples which combines it with the Builder Pattern .

As to your question:

How to add a Query Pattern to an existing DAO pattern?

I would recommend to have a look at JPA2 .

Query Object

An object that represents a database query.

For a full description see here

SQL can be an involved language, and many developers aren't particularly familiar with it. Furthermore, you need to know what the database schema looks like to form queries. You can avoid this by creating specialized finder methods that hide the SQL inside parameterized methods, but that makes it difficult to form more ad-hoc queries. It also leads to duplication in the SQL statements should the database schema change.

A Query Object is an interpreter [Gang of Four], that is, a structure of objects that can form itself into a SQL query. You can create this query by referring to classes and fields rather than tables and columns. In this way those who write the queries can do so independently of the database schema and changes to the schema can be localized in a single place.

I wrote a C# implementation for NHibernate here: https://github.com/shaynevanasperen/NHibernate.Sessions.Operations .

It works by using an interface like this:

public interface IDatabases
{
    ISessionManager SessionManager { get; }

    T Query<T>(IDatabaseQuery<T> query);
    T Query<T>(ICachedDatabaseQuery<T> query);

    void Command(IDatabaseCommand command);
    T Command<T>(IDatabaseCommand<T> command);
}

Given a POCO entity class like this:

class Database1Poco
{
    public int Property1 { get; set; }
    public string Property2 { get; set; }
}

You can build query objects like this:

class Database1PocoByProperty1 : DatabaseQuery<Database1Poco>
{
    public override Database1Poco Execute(ISessionManager sessionManager)
    {
        return sessionManager.Session.Query<Database1Poco>().SingleOrDefault(x => x.Property1 == Property1);
    }

    public int Property1 { get; set; }
}

And then use them like this:

var database1Poco = _databases.Query(new Database1PocoByProperty1 { Property1 = 1 });

You could port that to Java if you like it.

Here are some other examples:

https://lostechies.com/jimmybogard/2012/10/08/favor-query-objects-over-repositories/ http://www.mrdustpan.com/command-query-objects-with-dapper#disqus_thread http://crosscuttingconcerns.com/CommandQuery-Object-pattern

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM