Some refactoring of query generation; addition of "for update" support. From
Zell.
This commit is contained in:
@@ -472,7 +472,7 @@ public class DepotMarshaller<T>
|
|||||||
}
|
}
|
||||||
update.append(field).append(" = ?");
|
update.append(field).append(" = ?");
|
||||||
}
|
}
|
||||||
update.append(" where "); key.appendClause(null, update);
|
key.appendClause(null, update);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
PreparedStatement pstmt = conn.prepareStatement(update.toString());
|
PreparedStatement pstmt = conn.prepareStatement(update.toString());
|
||||||
@@ -513,7 +513,7 @@ public class DepotMarshaller<T>
|
|||||||
}
|
}
|
||||||
update.append(field).append(" = ?");
|
update.append(field).append(" = ?");
|
||||||
}
|
}
|
||||||
update.append(" where "); key.appendClause(null, update);
|
key.appendClause(null, update);
|
||||||
|
|
||||||
PreparedStatement pstmt = conn.prepareStatement(update.toString());
|
PreparedStatement pstmt = conn.prepareStatement(update.toString());
|
||||||
idx = 0;
|
idx = 0;
|
||||||
@@ -533,7 +533,7 @@ public class DepotMarshaller<T>
|
|||||||
public PreparedStatement createDelete (Connection conn, Key key)
|
public PreparedStatement createDelete (Connection conn, Key key)
|
||||||
throws SQLException
|
throws SQLException
|
||||||
{
|
{
|
||||||
StringBuilder query = new StringBuilder("delete from " + getTableName() + " where ");
|
StringBuilder query = new StringBuilder("delete from " + getTableName());
|
||||||
key.appendClause(null, query);
|
key.appendClause(null, query);
|
||||||
PreparedStatement pstmt = conn.prepareStatement(query.toString());
|
PreparedStatement pstmt = conn.prepareStatement(query.toString());
|
||||||
key.bindArguments(pstmt, 1);
|
key.bindArguments(pstmt, 1);
|
||||||
@@ -557,7 +557,7 @@ public class DepotMarshaller<T>
|
|||||||
update.append(modifiedFields[ii]).append(" = ");
|
update.append(modifiedFields[ii]).append(" = ");
|
||||||
update.append(modifiedValues[ii]);
|
update.append(modifiedValues[ii]);
|
||||||
}
|
}
|
||||||
update.append(" where "); key.appendClause(null, update);
|
key.appendClause(null, update);
|
||||||
|
|
||||||
PreparedStatement pstmt = conn.prepareStatement(update.toString());
|
PreparedStatement pstmt = conn.prepareStatement(update.toString());
|
||||||
key.bindArguments(pstmt, 1);
|
key.bindArguments(pstmt, 1);
|
||||||
|
|||||||
@@ -58,20 +58,20 @@ public class DepotRepository
|
|||||||
/**
|
/**
|
||||||
* Loads the persistent object that matches the specified primary key.
|
* Loads the persistent object that matches the specified primary key.
|
||||||
*/
|
*/
|
||||||
protected <T> T load (Class<T> type, Comparable primaryKey)
|
protected <T> T load (Class<T> type, Comparable primaryKey, QueryClause... clauses)
|
||||||
throws PersistenceException
|
throws PersistenceException
|
||||||
{
|
{
|
||||||
return load(type, _ctx.getMarshaller(type).makePrimaryKey(primaryKey));
|
return load(type, _ctx.getMarshaller(type).makePrimaryKey(primaryKey), clauses);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the first persistent object that matches the supplied key.
|
* Loads the first persistent object that matches the supplied key.
|
||||||
*/
|
*/
|
||||||
protected <T> T load (Class<T> type, Key key)
|
protected <T> T load (Class<T> type, Key key, QueryClause... clauses)
|
||||||
throws PersistenceException
|
throws PersistenceException
|
||||||
{
|
{
|
||||||
final DepotMarshaller<T> marsh = _ctx.getMarshaller(type);
|
final DepotMarshaller<T> marsh = _ctx.getMarshaller(type);
|
||||||
return _ctx.invoke(new Query<T>(_ctx, type, key) {
|
return _ctx.invoke(new Query<T>(_ctx, type, key, clauses) {
|
||||||
public T invoke (Connection conn) throws SQLException {
|
public T invoke (Connection conn) throws SQLException {
|
||||||
PreparedStatement stmt = createQuery(conn);
|
PreparedStatement stmt = createQuery(conn);
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ public class Key
|
|||||||
|
|
||||||
public void appendClause (Query query, StringBuilder builder)
|
public void appendClause (Query query, StringBuilder builder)
|
||||||
{
|
{
|
||||||
|
builder.append(" where ");
|
||||||
for (int ii = 0; ii < columns.length; ii++) {
|
for (int ii = 0; ii < columns.length; ii++) {
|
||||||
if (ii > 0) {
|
if (ii > 0) {
|
||||||
builder.append(" and ");
|
builder.append(" and ");
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import java.util.Set;
|
|||||||
|
|
||||||
import com.samskivert.io.PersistenceException;
|
import com.samskivert.io.PersistenceException;
|
||||||
import com.samskivert.jdbc.depot.clause.FieldOverrideClause;
|
import com.samskivert.jdbc.depot.clause.FieldOverrideClause;
|
||||||
|
import com.samskivert.jdbc.depot.clause.ForUpdateClause;
|
||||||
import com.samskivert.jdbc.depot.clause.GroupByClause;
|
import com.samskivert.jdbc.depot.clause.GroupByClause;
|
||||||
import com.samskivert.jdbc.depot.clause.JoinClause;
|
import com.samskivert.jdbc.depot.clause.JoinClause;
|
||||||
import com.samskivert.jdbc.depot.clause.LimitClause;
|
import com.samskivert.jdbc.depot.clause.LimitClause;
|
||||||
@@ -130,25 +131,23 @@ public abstract class Query<T>
|
|||||||
query.append(" from " + mainMarshaller.getTableName() + " as T ");
|
query.append(" from " + mainMarshaller.getTableName() + " as T ");
|
||||||
|
|
||||||
for (JoinClause clause : _joinClauses) {
|
for (JoinClause clause : _joinClauses) {
|
||||||
query.append(" inner join " );
|
|
||||||
clause.appendClause(this, query);
|
clause.appendClause(this, query);
|
||||||
}
|
}
|
||||||
if (_key != null) {
|
if (_key != null) {
|
||||||
query.append(" where ");
|
|
||||||
_key.appendClause(this, query);
|
_key.appendClause(this, query);
|
||||||
}
|
}
|
||||||
if (_groupBy != null) {
|
if (_groupBy != null) {
|
||||||
query.append(" group by ");
|
|
||||||
_groupBy.appendClause(this, query);
|
_groupBy.appendClause(this, query);
|
||||||
}
|
}
|
||||||
if (_orderBy != null) {
|
if (_orderBy != null) {
|
||||||
query.append(" order by ");
|
|
||||||
_orderBy.appendClause(this, query);
|
_orderBy.appendClause(this, query);
|
||||||
}
|
}
|
||||||
if (_limit != null) {
|
if (_limit != null) {
|
||||||
query.append(" limit ");
|
|
||||||
_limit.appendClause(this, query);
|
_limit.appendClause(this, query);
|
||||||
}
|
}
|
||||||
|
if (_forUpdate != null) {
|
||||||
|
_forUpdate.appendClause(this, query);
|
||||||
|
}
|
||||||
|
|
||||||
PreparedStatement pstmt = conn.prepareStatement(query.toString());
|
PreparedStatement pstmt = conn.prepareStatement(query.toString());
|
||||||
int argIdx = 1;
|
int argIdx = 1;
|
||||||
@@ -164,6 +163,9 @@ public abstract class Query<T>
|
|||||||
if (_limit != null) {
|
if (_limit != null) {
|
||||||
argIdx = _limit.bindArguments(pstmt, argIdx);
|
argIdx = _limit.bindArguments(pstmt, argIdx);
|
||||||
}
|
}
|
||||||
|
if (_forUpdate != null) {
|
||||||
|
argIdx = _forUpdate.bindArguments(pstmt, argIdx);
|
||||||
|
}
|
||||||
|
|
||||||
return pstmt;
|
return pstmt;
|
||||||
}
|
}
|
||||||
@@ -215,6 +217,13 @@ public abstract class Query<T>
|
|||||||
"Query can't contain multiple Limit clauses.");
|
"Query can't contain multiple Limit clauses.");
|
||||||
}
|
}
|
||||||
_limit = (LimitClause) clause;
|
_limit = (LimitClause) clause;
|
||||||
|
|
||||||
|
} else if (clause instanceof ForUpdateClause) {
|
||||||
|
if (_forUpdate != null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Query can't contain multiple For Update clauses.");
|
||||||
|
}
|
||||||
|
_forUpdate = (ForUpdateClause) clause;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_classMap = new HashMap<Class, DepotMarshaller>();
|
_classMap = new HashMap<Class, DepotMarshaller>();
|
||||||
@@ -251,4 +260,7 @@ public abstract class Query<T>
|
|||||||
|
|
||||||
/** The limit clause, if any. */
|
/** The limit clause, if any. */
|
||||||
protected LimitClause _limit;
|
protected LimitClause _limit;
|
||||||
|
|
||||||
|
/** The For Update clause, if any. */
|
||||||
|
protected ForUpdateClause _forUpdate;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
//
|
||||||
|
// $Id$
|
||||||
|
//
|
||||||
|
// samskivert library - useful routines for java programs
|
||||||
|
// Copyright (C) 2006 Michael Bayne, Pär Winzell
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify it
|
||||||
|
// under the terms of the GNU Lesser General Public License as published
|
||||||
|
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
package com.samskivert.jdbc.depot.clause;
|
||||||
|
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import com.samskivert.jdbc.depot.Query;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a FOR UPDATE clause.
|
||||||
|
*/
|
||||||
|
public class ForUpdateClause
|
||||||
|
implements QueryClause
|
||||||
|
{
|
||||||
|
// from QueryClause
|
||||||
|
public Collection<Class> getClassSet ()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// from QueryClause
|
||||||
|
public void appendClause (Query query, StringBuilder builder)
|
||||||
|
{
|
||||||
|
builder.append(" for update ");
|
||||||
|
}
|
||||||
|
|
||||||
|
// from QueryClause
|
||||||
|
public int bindArguments (PreparedStatement pstmt, int argIdx)
|
||||||
|
throws SQLException
|
||||||
|
{
|
||||||
|
return argIdx;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -48,6 +48,7 @@ public class GroupByClause
|
|||||||
// from QueryClause
|
// from QueryClause
|
||||||
public void appendClause (Query query, StringBuilder builder)
|
public void appendClause (Query query, StringBuilder builder)
|
||||||
{
|
{
|
||||||
|
builder.append(" group by ");
|
||||||
for (int ii = 0; ii < _values.length; ii++) {
|
for (int ii = 0; ii < _values.length; ii++) {
|
||||||
if (ii > 0) {
|
if (ii > 0) {
|
||||||
builder.append(", ");
|
builder.append(", ");
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ public class JoinClause
|
|||||||
// from QueryClause
|
// from QueryClause
|
||||||
public void appendClause (Query query, StringBuilder builder)
|
public void appendClause (Query query, StringBuilder builder)
|
||||||
{
|
{
|
||||||
|
builder.append(" inner join " );
|
||||||
String jAbbrev = query.getTableAbbreviation(_joinClass);
|
String jAbbrev = query.getTableAbbreviation(_joinClass);
|
||||||
builder.append(query.getTableName(_joinClass) + " as " + jAbbrev + " on T." +
|
builder.append(query.getTableName(_joinClass) + " as " + jAbbrev + " on T." +
|
||||||
_primaryColumn + " = " + jAbbrev + "." + _joinColumn);
|
_primaryColumn + " = " + jAbbrev + "." + _joinColumn);
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public class LimitClause
|
|||||||
// from QueryClause
|
// from QueryClause
|
||||||
public void appendClause (Query query, StringBuilder builder)
|
public void appendClause (Query query, StringBuilder builder)
|
||||||
{
|
{
|
||||||
builder.append("? offset ?");
|
builder.append(" limit ? offset ? ");
|
||||||
}
|
}
|
||||||
|
|
||||||
// from QueryClause
|
// from QueryClause
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ public class OrderByClause
|
|||||||
// from QueryClause
|
// from QueryClause
|
||||||
public void appendClause (Query query, StringBuilder builder)
|
public void appendClause (Query query, StringBuilder builder)
|
||||||
{
|
{
|
||||||
|
builder.append(" order by ");
|
||||||
for (int ii = 0; ii < _values.length; ii++) {
|
for (int ii = 0; ii < _values.length; ii++) {
|
||||||
if (ii > 0) {
|
if (ii > 0) {
|
||||||
builder.append(", ");
|
builder.append(", ");
|
||||||
|
|||||||
Reference in New Issue
Block a user