package com.ycsoft.daos.core.generator;
import static com.ycsoft.daos.helper.StringHelper.format;
import static com.ycsoft.daos.helper.StringHelper.formatIgnoreType;
import java.io.Serializable;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import com.ycsoft.commons.helper.StringHelper;
import com.ycsoft.daos.config.Table;
import com.ycsoft.daos.helper.DateHelper;
import com.ycsoft.daos.helper.ListHelper;
/**
* <p>生成Oracle数据库执行的相关sql类</p>
*/
@SuppressWarnings("unchecked")
public class OracleGenerator implements SQLGenerator{
/**
* <p> 生成产生所有数据的SQL </P>
* @param tname 表名
*/
public String getEntityAll(String tname) {
return formatIgnoreType("SELECT t.* FROM {0} t ",tname);
}
/**
* <p> 通过主键获得逐渐对象 </p>
* @return
*/
public String getEntityByKey(Table tb) {
return formatIgnoreType("SELECT t.* FROM {0} t WHERE t.{1} = ?",tb.getTableName(),tb.getPrimaryKey());
}
/**
* <p> 分页命令 </p>
*/
public String getPage(String sql, int start, int limit) {
StringBuffer sb = new StringBuffer(100);
sb.append("SELECT * FROM (");
sb.append("SELECT row_.*, ROWNUM rownum_");
sb.append(" FROM ( {0} ) row_ ");
sb.append(" WHERE rownum <= {1})");
sb.append("WHERE rownum_ > {2} ");
return formatIgnoreType(sb.toString(), sql,start+limit,start);
}
/**
* <p> oracle 采用count函数获取sql结果集的行数 </p>
*/
public String getPageCount(String sql) {
return formatIgnoreType("SELECT count(*) FROM ( {0} )" , sql );
}
/**
* <p> 获得总记录数的sql </p>
* @param tname 表名
*/
public String getRows(String tname ){
return formatIgnoreType("SELECT COUNT(*) FROM {0} t",tname);
}
/**
* <p> 获得oracle下的序列nextVal值 </p>
*/
public String getSeqNextVal(String sequenceName) {
return formatIgnoreType("SELECT {0}.NEXTVAL FROM dual ",sequenceName);
}
/**
* <p> 获得删除的Sql语句 </p>
*/
public String getDelete(Table tb) {
return formatIgnoreType("DELETE FROM {0} t WHERE t.{1} = ?",tb.getTableName(),tb.getPrimaryKey());
}
/**
* <p> 获得保存的SQL语句 </p>
*/
public String getSave(String tableName,Map<String , Object > maps){
String sql = "INSERT INTO {0}({1}) values({2})" ;
StringBuffer columns = new StringBuffer();
StringBuffer values = new StringBuffer();
Iterator<String> ite = maps.keySet().iterator();
while(ite.hasNext()){
String key = ite.next() ;
columns.append(key + ",");
if (maps.get(key) instanceof Date) {
values.append("to_date("+format("{0}",DateHelper.format((Date)maps.get(key))) + ",'yyyy-mm-dd hh24:mi:ss'),");
}
else
values.append(format("{0}",maps.get(key)) + ",");
}
if(values.length()>0){
values.deleteCharAt(values.length() - 1);
columns.deleteCharAt(columns.length() - 1);
}
return formatIgnoreType(sql,tableName,columns,values);
}
/**
* <p> 获取更新的SQL </p>
*/
public String getUpdate(Table tb , List<String> columns) {
String sql = "UPDATE {0} t SET {1} WHERE t.{2} = ?";
String cols = ListHelper.parseListToStr(""," = ? ", columns );
return formatIgnoreType(sql,tb.getTableName(),cols,tb.getPrimaryKey());
}
/**
* 获取更新SQL命令,包含参数的值
*/
public String getUpdate(Table tb, Map<String, Object> maps, Object key) {
String sql = "UPDATE {0} t SET {1} WHERE t.{2} = " + format("{0}",key);
StringBuffer where = new StringBuffer();
Iterator ite = maps.keySet().iterator();
Object [] objs = new Object[maps.keySet().toArray().length];
int i = 0 ;
while(ite.hasNext()){
Object str = ite.next();
where.append( str +" = {"+ i +"} ,");
if (maps.get(str) instanceof Date)
objs[i] = "to_date('" + DateHelper.format((Date)maps.get(str)) + "','yyyy-mm-dd hh24:mi:ss')";
else
objs[i] = format("{0}",maps.get(str)) + "";
i ++ ;
}
if (where.length() > 0) {
where.deleteCharAt(where.length() - 1);
}
return formatIgnoreType(
sql,
tb.getTableName(),
formatIgnoreType(where.toString(),objs),
tb.getPrimaryKey());
}
/**
* <p> 获得表名,根据Oracle的特性,表名大写
* 因此强行调用<code> java.lang.String.toUpperCase() </code>大写表名 </p>
* <p> 这里也使用了oracle的函数<code>lower</code>小写列名 </p>
*/
public String getTableColums(String tname) {
return format("SELECT lower(t.COLUMN_NAME) FROM user_tab_columns t WHERE t.TABLE_NAME = {0}",tname.toUpperCase());
}
/**
* <p> 根据Map获得查询实体类的SQL </p>
*/
public String getFindByMap(String tableName,
Map<String, Serializable> params) {
StringBuffer sql = new StringBuffer("SELECT * FROM {0} WHERE 1 = 1 ") ;
Object [] os = params.keySet().toArray();
for (Object _o : os)
sql.append(" AND " + _o + " = ? ");
return formatIgnoreType(sql.toString(), tableName);
}
public String and(Map params){
String target = StringUtils.EMPTY;
if(params == null) return target;
Iterator<String> ite = params.keySet().iterator();
String key = null ;
while(ite.hasNext()){
key = ite.next();
if( params.get(key) != null ){
target += format( key + "={0}", params.get(key)) + " and ";
}
}
return StringHelper.delEndChar( target , 4 ) ;
}
public String in(Object[] value) {
String target = StringUtils.EMPTY;
if(value == null ) return target;
boolean flag = false;
for (Object o : value) {
if (o != null){
target += format("{0},", o);
flag = true;
}
}
if (flag)
return StringHelper.delEndChar( target , 1 );
else
return "-111";
}
/**
* 处理where in 里面的数据。当where in 里面的参数值超过一定数量时,把它分开来处理。如oracle in
* 里面的参数超出1000条数据将报错,此方法可以处理之. 形式如:select * from table1 where 1=1 and (ID in
* (1,2,3,4,...,1000) or ID in (1001,1002,...))
* 格式如:"select * from r_card r where 1=1 and ("+getSqlGenerator().setWhereInArray("r.card_id",values)+")";
* @param name
* 参数类型 如 r.card_id 会组装成 r.card_id in ('1','2',....'1000') or r.card_id in ('1001',...'2000')
* @param value
* 参数值
* @return 返回 分割后的sql
*/
public String setWhereInArray(String name, Object[] value) {
int inArrayNum = value.length % 1000 == 0 ? value.length
/ 1000 : value.length / 1000 + 1;// 参数值一共能分割成多少组,记录总组数
int m = 0;// 用来记录参数值数字的下标值
int b = 0;// 用来记录参数值数组和sql片段,能分出多少个参数值片段就能分割成多少个sql片段
int n = 1000;// 用来记录参数值数字下标值的步长,步长的长度等于需要分割的数量,如要1000
String p[] = new String[inArrayNum];// 分割的参数值片段数组
String arrySql[] = new String[inArrayNum];// 分割的sql片段数组
for (int k = 0; k < value.length; k++) {
if (b < inArrayNum) {
p[b] = "";
for (; m < n; m++) {
if (m >= value.length) {
break;
}
p[b] += "'" + value[m].toString().trim() + "',";
}
p[b] = p[b].substring(0, p[b].lastIndexOf(","));
arrySql[b] = " or " + name + " in ("+p[b]+")";
b++;
n += 1000;
}
}
String sql ="";
if(arrySql.length>0){
arrySql[0] = StringHelper.delStartChar( arrySql[0] , 3 );
for (int q = 0; q < arrySql.length; q++) {
sql += arrySql[q];
}
}
return sql;
}
public String or(Map<String, Object> params) {
String target = StringUtils.EMPTY;
if(params == null ) return target;
Iterator<String> ite = params.keySet().iterator();
String key = null ;
while(ite.hasNext()){
key = ite.next();
if( params.get(key) != null ){
target += format( key + "={0}", params.get(key)) + " or ";
}
}
return StringHelper.delEndChar( target , 3);
}
}