下面列出了怎么用org.hibernate.sql.JoinFragment的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Generate a sequence of <tt>LEFT OUTER JOIN</tt> clauses for the given associations.
*/
protected final JoinFragment mergeOuterJoins(List associations)
throws MappingException {
JoinFragment outerjoin = getDialect().createOuterJoinFragment();
Iterator iter = associations.iterator();
OuterJoinableAssociation last = null;
while ( iter.hasNext() ) {
final OuterJoinableAssociation oj = (OuterJoinableAssociation) iter.next();
if ( last != null && last.isManyToManyWith( oj ) ) {
oj.addManyToManyJoin( outerjoin, (QueryableCollection) last.getJoinable() );
}
else {
oj.addJoins( outerjoin );
}
last = oj;
}
last = null;
return outerjoin;
}
public void addManyToManyJoin(JoinFragment outerjoin, QueryableCollection collection) throws MappingException {
String manyToManyFilter = collection.getManyToManyFilterFragment( rhsAlias, enabledFilters );
String condition = "".equals( manyToManyFilter )
? on
: "".equals( on )
? manyToManyFilter
: on + " and " + manyToManyFilter;
outerjoin.addJoin(
joinable.getTableName(),
rhsAlias,
lhsColumns,
rhsColumns,
joinType,
condition
);
outerjoin.addJoins(
joinable.fromJoinFragment( rhsAlias, false, true ),
joinable.whereJoinFragment( rhsAlias, false, true )
);
}
private void renderJoin(Join join, JoinFragment joinFragment) {
if ( CompositeQuerySpace.class.isInstance( join.getRightHandSide() ) ) {
handleCompositeJoin( join, joinFragment );
}
else if ( EntityQuerySpace.class.isInstance( join.getRightHandSide() ) ) {
// do not render the entity join for a one-to-many association, since the collection join
// already joins to the associated entity table (see doc in renderCollectionJoin()).
if ( join.getLeftHandSide().getDisposition() == QuerySpace.Disposition.COLLECTION ) {
if ( CollectionQuerySpace.class.cast( join.getLeftHandSide() ).getCollectionPersister().isManyToMany() ) {
renderManyToManyJoin( join, joinFragment );
}
else if ( JoinDefinedByMetadata.class.isInstance( join ) &&
CollectionPropertyNames.COLLECTION_INDICES.equals( JoinDefinedByMetadata.class.cast( join ).getJoinedPropertyName() ) ) {
renderManyToManyJoin( join, joinFragment );
}
}
else {
renderEntityJoin( join, joinFragment );
}
}
else if ( CollectionQuerySpace.class.isInstance( join.getRightHandSide() ) ) {
renderCollectionJoin( join, joinFragment );
}
}
public void addManyToManyJoin(JoinFragment outerjoin, QueryableCollection collection) throws MappingException {
String manyToManyFilter = collection.getManyToManyFilterFragment( rhsAlias, enabledFilters );
String condition = "".equals( manyToManyFilter )
? on
: "".equals( on )
? manyToManyFilter
: on + " and " + manyToManyFilter;
outerjoin.addJoin(
joinable.getTableName(),
rhsAlias,
lhsColumns,
rhsColumns,
joinType,
condition
);
outerjoin.addJoins(
joinable.fromJoinFragment(rhsAlias, false, true),
joinable.whereJoinFragment(rhsAlias, false, true)
);
}
private void renderEntityJoin(Join join, JoinFragment joinFragment) {
final EntityQuerySpace rightHandSide = (EntityQuerySpace) join.getRightHandSide();
// see if there is already aliases registered for this entity query space (collection joins)
EntityReferenceAliases aliases = aliasResolutionContext.resolveEntityReferenceAliases( rightHandSide.getUid() );
if ( aliases == null && mutableAliasResolutionContext != null ) {
mutableAliasResolutionContext.generateEntityReferenceAliases(
rightHandSide.getUid(),
rightHandSide.getEntityPersister()
);
}
final Joinable joinable = (Joinable) rightHandSide.getEntityPersister();
addJoins(
join,
joinFragment,
joinable,
null
);
}
/**
* Should we join this association?
*/
protected boolean isJoinable(
final int joinType,
final Set visitedAssociationKeys,
final String lhsTable,
final String[] lhsColumnNames,
final AssociationType type,
final int depth
) {
if (joinType<0) return false;
if (joinType==JoinFragment.INNER_JOIN) return true;
Integer maxFetchDepth = getFactory().getSettings().getMaximumFetchDepth();
final boolean tooDeep = maxFetchDepth!=null &&
depth >= maxFetchDepth.intValue();
return !tooDeep && !isDuplicateAssociation(lhsTable, lhsColumnNames, type);
}
@Override
public List<TargetValue> listKpiWithTarget(final Integer targetId) {
List<SbiKpiTargetValue> lst = list(new ICriterion<SbiKpiTargetValue>() {
@Override
public Criteria evaluate(Session session) {
return session.createCriteria(SbiKpiTargetValue.class).createAlias("sbiKpiKpi", "sbiKpiKpi", JoinFragment.RIGHT_OUTER_JOIN)
.createAlias("sbiKpiTarget", "sbiKpiTarget").add(Restrictions.eq("sbiKpiKpi.active", 'T'))
.add(Restrictions.eq("sbiKpiTarget.targetId", targetId));
/*
* return session .createCriteria(SbiKpiKpi.class) .createAlias("sbiKpiTargetValues", "sbiKpiTargetValues", JoinFragment.LEFT_OUTER_JOIN)
* .createAlias("sbiKpiTargetValues.sbiKpiKpi", "sbiKpiKpi") .add(Restrictions.eq("active", 'T')) .setProjection(
* Projections.projectionList().add(Property.forName("sbiKpiKpiId.id").as("kpiId"))
* .add(Property.forName("sbiKpiKpiId.version").as("kpiVersion")) .add(Property.forName("sbiKpiTargetValues.value").as("value")))
* .setResultTransformer(Transformers.aliasToBean(SbiKpiTargetValue.class));
*/
}
});
List<TargetValue> ret = new ArrayList<>();
for (SbiKpiTargetValue sbiTarget : lst) {
ret.add(from(sbiTarget));
}
return ret;
}
protected JoinFragment createJoin(String name, boolean innerJoin, boolean includeSubclasses) {
final String[] idCols = StringHelper.qualify( name, getIdentifierColumnNames() ); //all joins join to the pk of the driving table
final JoinFragment join = getFactory().getDialect().createOuterJoinFragment();
final int tableSpan = getSubclassTableSpan();
for ( int j = 1; j < tableSpan; j++ ) { //notice that we skip the first table; it is the driving table!
final boolean joinIsIncluded = isClassOrSuperclassTable( j ) ||
( includeSubclasses && !isSubclassTableSequentialSelect( j ) && !isSubclassTableLazy( j ) );
if ( joinIsIncluded ) {
join.addJoin( getSubclassTableName( j ),
generateTableAlias( name, j ),
idCols,
getSubclassTableKeyColumns( j ),
innerJoin && isClassOrSuperclassTable( j ) && !isInverseTable( j ) && !isNullableTable( j ) ?
JoinFragment.INNER_JOIN : //we can inner join to superclass tables (the row MUST be there)
JoinFragment.LEFT_OUTER_JOIN //we can never inner join to subclass tables
);
}
}
return join;
}
protected AST createFromFilterElement(AST filterEntity, AST alias) throws SemanticException {
FromElement fromElement = currentFromClause.addFromElement( filterEntity.getText(), alias );
FromClause fromClause = fromElement.getFromClause();
QueryableCollection persister = sessionFactoryHelper.getCollectionPersister( collectionFilterRole );
// Get the names of the columns used to link between the collection
// owner and the collection elements.
String[] keyColumnNames = persister.getKeyColumnNames();
String fkTableAlias = persister.isOneToMany()
? fromElement.getTableAlias()
: fromClause.getAliasGenerator().createName( collectionFilterRole );
JoinSequence join = sessionFactoryHelper.createJoinSequence();
join.setRoot( persister, fkTableAlias );
if ( !persister.isOneToMany() ) {
join.addJoin( ( AssociationType ) persister.getElementType(),
fromElement.getTableAlias(),
JoinFragment.INNER_JOIN,
persister.getElementColumnNames( fkTableAlias ) );
}
join.addCondition( fkTableAlias, keyColumnNames, " = ?" );
fromElement.setJoinSequence( join );
fromElement.setFilter( true );
if ( log.isDebugEnabled() ) {
log.debug( "createFromFilterElement() : processed filter FROM element." );
}
return fromElement;
}
public void addJoins(JoinFragment outerjoin) throws MappingException {
outerjoin.addJoin(
joinable.getTableName(),
rhsAlias,
lhsColumns,
rhsColumns,
joinType,
on
);
outerjoin.addJoins(
joinable.fromJoinFragment( rhsAlias, false, true ),
joinable.whereJoinFragment( rhsAlias, false, true )
);
}
public void processQuerySpaceJoins(QuerySpace querySpace, SelectStatementBuilder selectStatementBuilder) {
LOG.debug( "processing queryspace " + querySpace.getUid() );
final JoinFragment joinFragment = factory.getDialect().createOuterJoinFragment();
processQuerySpaceJoins( querySpace, joinFragment );
selectStatementBuilder.setOuterJoins(
joinFragment.toFromFragmentString(),
joinFragment.toWhereFragmentString()
);
}
private void processQuerySpaceJoins(QuerySpace querySpace, JoinFragment joinFragment) {
// IMPL NOTES:
//
// 1) The querySpace and the left-hand-side of each of the querySpace's joins should really be the same.
// validate that? any cases where they wont be the same?
//
// 2) Assume that the table fragments for the left-hand-side have already been rendered. We just need to
// figure out the proper lhs table alias to use and the column/formula from the lhs to define the join
// condition, which can be different per Join
for ( Join join : querySpace.getJoins() ) {
processQuerySpaceJoin( join, joinFragment );
}
}
private void renderCollectionJoin(Join join, JoinFragment joinFragment) {
final CollectionQuerySpace rightHandSide = (CollectionQuerySpace) join.getRightHandSide();
if ( mutableAliasResolutionContext != null ) {
registerCollectionJoinAliases( mutableAliasResolutionContext, rightHandSide );
}
addJoins(
join,
joinFragment,
(Joinable) rightHandSide.getCollectionPersister(),
null
);
}
protected JoinFragment createJoin(
String name,
boolean innerJoin,
boolean includeSubclasses,
Set<String> treatAsDeclarations) {
// IMPL NOTE : all joins join to the pk of the driving table
final String[] idCols = StringHelper.qualify( name, getIdentifierColumnNames() );
final JoinFragment join = getFactory().getDialect().createOuterJoinFragment();
final int tableSpan = getSubclassTableSpan();
// IMPL NOTE : notice that we skip the first table; it is the driving table!
for ( int j = 1; j < tableSpan; j++ ) {
final JoinType joinType = determineSubclassTableJoinType(
j,
innerJoin,
includeSubclasses,
treatAsDeclarations
);
if ( joinType != null && joinType != JoinType.NONE ) {
join.addJoin(
getSubclassTableName( j ),
generateTableAlias( name, j ),
idCols,
getSubclassTableKeyColumns( j ),
joinType
);
}
}
return join;
}
protected String renderSelect(
final int[] tableNumbers,
final int[] columnNumbers,
final int[] formulaNumbers) {
Arrays.sort( tableNumbers ); //get 'em in the right order (not that it really matters)
//render the where and from parts
int drivingTable = tableNumbers[0];
final String drivingAlias = generateTableAlias(
getRootAlias(),
drivingTable
); //we *could* regerate this inside each called method!
final String where = createWhereByKey( drivingTable, drivingAlias );
final String from = createFrom( drivingTable, drivingAlias );
//now render the joins
JoinFragment jf = createJoin( tableNumbers, drivingAlias );
//now render the select clause
SelectFragment selectFragment = createSelect( columnNumbers, formulaNumbers );
//now tie it all together
Select select = new Select( getFactory().getDialect() );
select.setSelectClause( selectFragment.toFragmentString().substring( 2 ) );
select.setFromClause( from );
select.setWhereClause( where );
select.setOuterJoins( jf.toFromFragmentString(), jf.toWhereFragmentString() );
if ( getFactory().getSessionFactoryOptions().isCommentsEnabled() ) {
select.setComment( "sequential select " + getEntityName() );
}
return select.toStatementString();
}
public static String createCollectionSubquery(
JoinSequence joinSequence,
Map enabledFilters,
String[] columns) {
try {
JoinFragment join = joinSequence.toJoinFragment( enabledFilters, true );
return "select " + String.join( ", ", columns )
+ " from " + join.toFromFragmentString().substring( 2 )
+ " where " + join.toWhereFragmentString().substring( 5 );
}
catch (MappingException me) {
throw new QueryException( me );
}
}
/**
* Translates an AST join type (i.e., the token type) into a JoinFragment.XXX join type.
*
* @param astJoinType The AST join type (from HqlSqlTokenTypes or SqlTokenTypes)
* @return a JoinFragment.XXX join type.
* @see JoinFragment
* @see SqlTokenTypes
*/
public static int toHibernateJoinType(int astJoinType) {
switch ( astJoinType ) {
case LEFT_OUTER:
return JoinFragment.LEFT_OUTER_JOIN;
case INNER:
return JoinFragment.INNER_JOIN;
case RIGHT_OUTER:
return JoinFragment.RIGHT_OUTER_JOIN;
default:
throw new AssertionFailure( "undefined join type " + astJoinType );
}
}
/**
* Translates an AST join type (i.e., the token type) into a JoinFragment.XXX join type.
*
* @param astJoinType The AST join type (from HqlSqlTokenTypes or SqlTokenTypes)
* @return a JoinFragment.XXX join type.
* @see JoinFragment
* @see SqlTokenTypes
*/
public static int toHibernateJoinType(int astJoinType) {
switch ( astJoinType ) {
case LEFT_OUTER:
return JoinFragment.LEFT_OUTER_JOIN;
case INNER:
return JoinFragment.INNER_JOIN;
case RIGHT_OUTER:
return JoinFragment.RIGHT_OUTER_JOIN;
default:
throw new AssertionFailure( "undefined join type " + astJoinType );
}
}
/**
* Translates an AST join type (i.e., the token type) into a JoinFragment.XXX join type.
*
* @param astJoinType The AST join type (from HqlSqlTokenTypes or SqlTokenTypes)
* @return a JoinFragment.XXX join type.
* @see JoinFragment
* @see SqlTokenTypes
*/
public static int toHibernateJoinType(int astJoinType) {
switch ( astJoinType ) {
case LEFT_OUTER:
return JoinFragment.LEFT_OUTER_JOIN;
case INNER:
return JoinFragment.INNER_JOIN;
case RIGHT_OUTER:
return JoinFragment.RIGHT_OUTER_JOIN;
default:
throw new AssertionFailure( "undefined join type " + astJoinType );
}
}
/**
* Translates an AST join type (i.e., the token type) into a JoinFragment.XXX join type.
*
* @param astJoinType The AST join type (from HqlSqlTokenTypes or SqlTokenTypes)
* @return a JoinFragment.XXX join type.
* @see JoinFragment
* @see SqlTokenTypes
*/
public static int toHibernateJoinType(int astJoinType) {
switch ( astJoinType ) {
case LEFT_OUTER:
return JoinFragment.LEFT_OUTER_JOIN;
case INNER:
return JoinFragment.INNER_JOIN;
case RIGHT_OUTER:
return JoinFragment.RIGHT_OUTER_JOIN;
default:
throw new AssertionFailure( "undefined join type " + astJoinType );
}
}
/**
* Translates an AST join type (i.e., the token type) into a JoinFragment.XXX join type.
*
* @param astJoinType The AST join type (from HqlSqlTokenTypes or SqlTokenTypes)
* @return a JoinFragment.XXX join type.
* @see JoinFragment
* @see SqlTokenTypes
*/
public static int toHibernateJoinType(int astJoinType) {
switch ( astJoinType ) {
case LEFT_OUTER:
return JoinFragment.LEFT_OUTER_JOIN;
case INNER:
return JoinFragment.INNER_JOIN;
case RIGHT_OUTER:
return JoinFragment.RIGHT_OUTER_JOIN;
default:
throw new AssertionFailure( "undefined join type " + astJoinType );
}
}
/**
* Used for collection filters
*/
private void addFromAssociation(final String elementName, final String collectionRole)
throws QueryException {
//q.addCollection(collectionName, collectionRole);
QueryableCollection persister = getCollectionPersister( collectionRole );
Type collectionElementType = persister.getElementType();
if ( !collectionElementType.isEntityType() ) {
throw new QueryException( "collection of values in filter: " + elementName );
}
String[] keyColumnNames = persister.getKeyColumnNames();
//if (keyColumnNames.length!=1) throw new QueryException("composite-key collection in filter: " + collectionRole);
String collectionName;
JoinSequence join = new JoinSequence( getFactory() );
collectionName = persister.isOneToMany() ?
elementName :
createNameForCollection( collectionRole );
join.setRoot( persister, collectionName );
if ( !persister.isOneToMany() ) {
//many-to-many
addCollection( collectionName, collectionRole );
try {
join.addJoin( ( AssociationType ) persister.getElementType(),
elementName,
JoinFragment.INNER_JOIN,
persister.getElementColumnNames(collectionName) );
}
catch ( MappingException me ) {
throw new QueryException( me );
}
}
join.addCondition( collectionName, keyColumnNames, " = ?" );
//if ( persister.hasWhere() ) join.addCondition( persister.getSQLWhereString(collectionName) );
EntityType elemType = ( EntityType ) collectionElementType;
addFrom( elementName, elemType.getAssociatedEntityName(), join );
}
/**
* Translates an AST join type (i.e., the token type) into a JoinFragment.XXX join type.
*
* @param astJoinType The AST join type (from HqlSqlTokenTypes or SqlTokenTypes)
* @return a JoinFragment.XXX join type.
* @see JoinFragment
* @see SqlTokenTypes
*/
public static int toHibernateJoinType(int astJoinType) {
switch ( astJoinType ) {
case LEFT_OUTER:
return JoinFragment.LEFT_OUTER_JOIN;
case INNER:
return JoinFragment.INNER_JOIN;
case RIGHT_OUTER:
return JoinFragment.RIGHT_OUTER_JOIN;
default:
throw new AssertionFailure( "undefined join type " + astJoinType );
}
}
/**
* Translates an AST join type (i.e., the token type) into a JoinFragment.XXX join type.
*
* @param astJoinType The AST join type (from HqlSqlTokenTypes or SqlTokenTypes)
* @return a JoinFragment.XXX join type.
* @see JoinFragment
* @see SqlTokenTypes
*/
public static int toHibernateJoinType(int astJoinType) {
switch ( astJoinType ) {
case LEFT_OUTER:
return JoinFragment.LEFT_OUTER_JOIN;
case INNER:
return JoinFragment.INNER_JOIN;
case RIGHT_OUTER:
return JoinFragment.RIGHT_OUTER_JOIN;
default:
throw new AssertionFailure( "undefined join type " + astJoinType );
}
}
/**
* Translates an AST join type (i.e., the token type) into a JoinFragment.XXX join type.
*
* @param astJoinType The AST join type (from HqlSqlTokenTypes or SqlTokenTypes)
* @return a JoinFragment.XXX join type.
* @see JoinFragment
* @see SqlTokenTypes
*/
public static int toHibernateJoinType(int astJoinType) {
switch ( astJoinType ) {
case LEFT_OUTER:
return JoinFragment.LEFT_OUTER_JOIN;
case INNER:
return JoinFragment.INNER_JOIN;
case RIGHT_OUTER:
return JoinFragment.RIGHT_OUTER_JOIN;
default:
throw new AssertionFailure( "undefined join type " + astJoinType );
}
}
private void initStatementString(
final String projection,
final String condition,
final String orderBy,
final String groupBy,
final LockMode lockMode) throws MappingException {
final int joins = countEntityPersisters( associations );
suffixes = BasicLoader.generateSuffixes( joins + 1 );
JoinFragment ojf = mergeOuterJoins( associations );
Select select = new Select( getDialect() )
.setLockMode( lockMode )
.setSelectClause(
projection == null ?
persister.selectFragment( alias, suffixes[joins] ) + selectString( associations ) :
projection
)
.setFromClause(
getDialect().appendLockHint( lockMode, persister.fromTableFragment( alias ) ) +
persister.fromJoinFragment( alias, true, true )
)
.setWhereClause( condition )
.setOuterJoins(
ojf.toFromFragmentString(),
ojf.toWhereFragmentString() + getWhereFragment()
)
.setOrderByClause( orderBy( associations, orderBy ) )
.setGroupByClause( groupBy );
if ( getFactory().getSettings().isCommentsEnabled() ) {
select.setComment( getComment() );
}
sql = select.toStatementString();
}
/**
* Count the number of instances of Joinable which are actually
* also instances of PersistentCollection which are being fetched
* by outer join
*/
protected static final int countCollectionPersisters(List associations)
throws MappingException {
int result = 0;
Iterator iter = associations.iterator();
while ( iter.hasNext() ) {
OuterJoinableAssociation oj = (OuterJoinableAssociation) iter.next();
if ( oj.getJoinType()==JoinFragment.LEFT_OUTER_JOIN && oj.getJoinable().isCollection() ) {
result++;
}
}
return result;
}
public OneToManyJoinWalker(
QueryableCollection oneToManyPersister,
int batchSize,
String subquery,
SessionFactoryImplementor factory,
Map enabledFilters)
throws MappingException {
super(factory, enabledFilters);
this.oneToManyPersister = oneToManyPersister;
final OuterJoinLoadable elementPersister = (OuterJoinLoadable) oneToManyPersister.getElementPersister();
final String alias = generateRootAlias( oneToManyPersister.getRole() );
walkEntityTree(elementPersister, alias);
List allAssociations = new ArrayList();
allAssociations.addAll(associations);
allAssociations.add( new OuterJoinableAssociation(
oneToManyPersister.getCollectionType(),
null,
null,
alias,
JoinFragment.LEFT_OUTER_JOIN,
getFactory(),
CollectionHelper.EMPTY_MAP
) );
initPersisters(allAssociations, LockMode.NONE);
initStatementString(elementPersister, alias, batchSize, subquery);
}
/**
* Translates an AST join type (i.e., the token type) into a JoinFragment.XXX join type.
*
* @param astJoinType The AST join type (from HqlSqlTokenTypes or SqlTokenTypes)
* @return a JoinFragment.XXX join type.
* @see JoinFragment
* @see SqlTokenTypes
*/
public static int toHibernateJoinType(int astJoinType) {
switch ( astJoinType ) {
case LEFT_OUTER:
return JoinFragment.LEFT_OUTER_JOIN;
case INNER:
return JoinFragment.INNER_JOIN;
case RIGHT_OUTER:
return JoinFragment.RIGHT_OUTER_JOIN;
default:
throw new AssertionFailure( "undefined join type " + astJoinType );
}
}
public JoinFragment toJoinFragment() throws MappingException {
return toJoinFragment( CollectionHelper.EMPTY_MAP, true );
}