org.sakaiproject.genericdao.util.JDBCUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of generic-dao Show documentation
Show all versions of generic-dao Show documentation
Generic Dao is a Java package which allows a developer to skip writing
DAOs for their persistence objects when they are using Spring and/or Hibernate.
The package was originally created by Aaron Zeckoski for the Evaluation System
project but was repackaged to make it distributable by request. It is used in the
RSF framework (http://www2.caret.cam.ac.uk/rsfwiki/). Note about the BeanUtils
provided dependency: BeanUtils is not required if you are not using it in your
project. Note about the Hibernate provided dependency: Hibernate is not required
if you are not using it in your project.
The newest version!
/**
* $Id$
* $URL$
* JDBCUtils.java - genericdao - Aug 4, 2008 6:12:37 PM - azeckoski
**************************************************************************
* Copyright (c) 2008 Aaron Zeckoski
* Licensed under the Apache License, Version 2.0
*
* A copy of the Apache License has been included in this
* distribution and is available at: http://www.apache.org/licenses/LICENSE-2.0.txt
*
* Aaron Zeckoski (azeckoski @ gmail.com) (aaronz @ vt.edu) (aaron @ caret.cam.ac.uk)
*/
package org.sakaiproject.genericdao.util;
import java.util.ArrayList;
import java.util.List;
import org.azeckoski.reflectutils.ConversionUtils;
import org.sakaiproject.genericdao.api.mappers.NamesRecord;
import org.sakaiproject.genericdao.api.search.Restriction;
import org.sakaiproject.genericdao.api.search.Search;
/**
* A set of utilities to help working with JDBC
*
* @author Aaron Zeckoski (azeckoski @ gmail.com)
*/
public class JDBCUtils {
/**
* Make a partial SQL string for a specific entity type using the associated {@link NamesRecord}
* and a {@link Search} object
* @param namesRecord a record of the mapping of property to columns for an entity type
* @param search a search object
* @return an object with the partial where SQL query and the params (args)
*/
public static QueryData makeSQLfromSearch(NamesRecord namesRecord, Search search) {
// Checks to see if the required params are set and throws exception if not
if (search == null) {
throw new IllegalArgumentException("search cannot be null");
}
QueryData sd = new QueryData();
//NamesRecord nr = getNamesRecord(type);
StringBuilder sql = new StringBuilder();
// Only add in restrictions if there are some to add
if (search.getRestrictions() != null && search.getRestrictions().length > 0) {
// set up the conjunction
String junction = " and ";
if (! search.conjunction) {
// set to use disjunction
junction = " or ";
}
// put in the restrictions
for (int i = 0; i < search.getRestrictions().length; i++) {
if (i > 0) {
sql.append(junction);
}
String property = search.getRestrictions()[i].property;
Object value = search.getRestrictions()[i].value;
if (property == null || value == null) {
throw new IllegalArgumentException("restrictions property and value cannot be null or empty");
}
String column = namesRecord.getColumnForProperty(property);
// we cannot recover from the case where the property is invalid
if (column == null) {
throw new IllegalArgumentException("Cannot find a column which matches the property ("+property+") for search: " + search);
}
if (value.getClass().isArray()) {
// special handling for "in" type comparisons
Object[] objectArray = (Object[]) value;
if (objectArray.length == 1) {
value = objectArray[0];
} else if (objectArray.length > 1) {
sql.append(column);
if (Restriction.NOT_EQUALS == search.getRestrictions()[i].comparison) {
sql.append(" not in ");
} else {
sql.append(" in ");
}
// need to create this kind of thing: (?,?,?) where there are 3 things in the array
sql.append("(");
for (int j = 0; j < objectArray.length; j++) {
if (j > 0) { sql.append(','); }
sql.append('?');
}
sql.append(") ");
// now we need to add the array of values (and convert possibly all of them)
for (int j = 0; j < objectArray.length; j++) {
sd.addArg( convertColumn(namesRecord, column, objectArray[j]) );
}
//sd.addArrayArg(objectArray);
} else {
// do nothing for now, this is slightly invalid but not worth dying over
}
}
if (! value.getClass().isArray()) {
int comparisonConstant = search.getRestrictions()[i].comparison;
// convert if needed
value = convertColumn(namesRecord, column, value);
sql.append( makeComparisonSQL(sd.args, namesRecord.getColumnForProperty(property), comparisonConstant, value) );
}
}
}
// handle the sorting (sort param can be null for no sort)
if (search.getOrders() != null) {
StringBuilder orderSQL = new StringBuilder();
if (search.getOrders().length > 0) {
orderSQL.append(" order by ");
for (int i = 0; i < search.getOrders().length; i++) {
if (i > 0) {
orderSQL.append(", ");
}
String property = search.getOrders()[i].property;
orderSQL.append(namesRecord.getColumnForProperty(property));
if (search.getOrders()[i].ascending) {
orderSQL.append(" asc ");
} else {
orderSQL.append(" desc ");
}
}
}
sd.orderSQL = orderSQL.toString();
}
sd.whereSQL = sql.toString();
return sd;
}
/**
* Create comparison SQL but converts the value object to a string
*
* @param column the name of a database column
* @param comparisonConstant the comparison constant (e.g. EQUALS)
* @param value the value to compare the property to
* @return a string representing the SQL snippet (e.g. propA = ?)
*/
public static String makeComparisonSQL(String column, int comparisonConstant, Object value) {
String sval = null;
if (comparisonConstant != Restriction.NOT_NULL
&& comparisonConstant != Restriction.NULL) {
if (value.getClass().isAssignableFrom(Boolean.class)
|| value.getClass().isAssignableFrom(Number.class)) {
// special handling for boolean and numbers
sval = value.toString();
} else {
sval = "'" + value.toString() + "'";
}
}
return buildComparisonSQL(column, comparisonConstant, sval);
}
/**
* Create comparison SQL but places the values into the params list
*
* @param params a set of params to add this value to
* @param column the name of a database column
* @param comparisonConstant the comparison constant (e.g. EQUALS)
* @param value the value to compare the property to
* @return a string representing the SQL snippet (e.g. propA = ?)
*/
public static String makeComparisonSQL(List