问题
In my old java code I could do this to "join" another table in a hibernate query and filter results based on it.
final Criteria brokerageCriteria = userCriteria.createCriteria("brokerage");
if (queryDto.getBrokerageID() != null) {
brokerageCriteria.add(Restrictions.eq("id", queryDto.getBrokerageID()));
}
In this example it would filter users who are a member of a specific brokerage only (each user has one brokerage).
As you can see I can easily join other tables that are associated in the hibernate mappings by calling criteria.createCriteria(String associationName). Is there anything similar to this in grails? I am trying to build a general purpose JSON-to-criteria web api for our internal developers to search various tables, page through data, etc.
回答1:
Considering the scenario, here is the domain classes and criteria query
//Domain User
class User{
//each user has one brokerage
static hasOne = [brokerage: Brokerage]
}
//Domain Brokerage
class Brokerage{
//Optional
//static belongsTo = [user: User]
}
//Criteria Query
def user = User.createCriteria().get{
brokerage{
idEq(queryDto.getBrokerageID())
}
}
or You can also use the non-DSL way
def user = User.createCriteria().get{
eq('brokerage.id', queryDto.getBrokerageID())
}
Joining associated tables in easier in case of criteria in grails because it uses DSLs(domain specific language). In the above example, only by providing the association in the criteria as brokerage{} an INNER JOIN is done on User and Brokerage based on brokerageId.
The beauty of Criteria in grails is that you can dynamically handle your query. For example, if a User has one Brokerage and one Mortgage and many Liens, and you want to get an User from the system if any of the brokerageId, mortgageId, lienId is provided in the JSON. The above criteria can be effectively enhanced as
def user = User.createCriteria().get{
if(queryDto.getBrokerageID() != null){
brokerage{
idEq(queryDto.getBrokerageID())
}
} else if(queryDto.getMortgageID() != null){
mortgage{
idEq(queryDto.getMortgageID())
}
} else if(queryDto.getLienID() != null){
liens{
idEq(queryDto.getLienID())
}
}
}
User domain would look like
class User{
//each user has one brokerage and one mortgage
static hasOne = [brokerage: Brokerage, mortgage: Mortgage]
static hasMany = [liens: Lien] //many Liens
}
来源:https://stackoverflow.com/questions/16452345/how-can-i-add-a-criteria-to-a-grails-criteria-to-limit-results-based-on-a-filter