/**
* Copyright 2014 Duan Bingnan
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.pinus4j.datalayer.update.jdbc;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import org.pinus4j.api.SQL;
import org.pinus4j.datalayer.AbstractDataLayer;
import org.pinus4j.datalayer.SQLBuilder;
import org.pinus4j.datalayer.update.IDataUpdate;
import org.pinus4j.entity.meta.DBTablePK;
import org.pinus4j.entity.meta.EntityPK;
import org.pinus4j.entity.meta.PKValue;
import org.pinus4j.utils.BeansUtil;
import org.pinus4j.utils.JdbcUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Lists;
/**
* 抽象的数据库更新操作组件.
*
* @author duanbn
* @since 0.7.1
*/
public abstract class AbstractJdbcUpdate extends AbstractDataLayer implements IDataUpdate {
public static final Logger LOG = LoggerFactory.getLogger(AbstractJdbcUpdate.class);
/**
* 执行保存数据操作.
*
* @param conn 数据库连接
* @param entities 需要被保存的数据
* @param tableIndex 分片表下标. 当-1时忽略下标
* @throws SQLException
*/
protected List<PKValue> _saveBatchWithAutoGeneratedKeys(Connection conn, List<? extends Object> entities,
int tableIndex) throws SQLException {
List<PKValue> pks = Lists.newArrayList();
PreparedStatement ps = null;
SQL sql = null;
Class<?> clazz = null;
try {
for (Object entity : entities) {
sql = SQLBuilder.getInsert(entity, tableIndex);
if (ps == null) {
ps = conn.prepareStatement(sql.getSql(), Statement.RETURN_GENERATED_KEYS);
}
fillParam(ps, sql);
ps.executeUpdate();
// 获取自增主键
clazz = entity.getClass();
if (!entityMetaManager.isUnionKey(clazz)) {
DBTablePK dbTablePK = entityMetaManager.getNotUnionPrimaryKey(clazz);
if (dbTablePK.isAutoIncrement()) {
ResultSet rs = ps.getGeneratedKeys();
Field f = BeansUtil.getField(clazz, dbTablePK.getField());
Object incrPK = null;
if (rs.next()) {
incrPK = rs.getObject(1);
if (f.getType() == Integer.TYPE || f.getType() == Integer.class) {
BeansUtil.setProperty(entity, dbTablePK.getField(), ((Long) incrPK).intValue());
pks.add(PKValue.valueOf(((Long) incrPK).intValue()));
} else {
BeansUtil.setProperty(entity, dbTablePK.getField(), incrPK);
pks.add(PKValue.valueOf(incrPK));
}
}
} else {
pks.add(PKValue.valueOf(BeansUtil.getProperty(entity, dbTablePK.getField())));
}
}
}
} finally {
JdbcUtil.close(ps);
}
return pks;
}
/**
* 批量保存数据,忽略自增主键.
*
* @param conn
* @param entities
* @param tableIndex
* @throws SQLException
*/
protected int _saveBatchWithoutAutoGeneratedKeys(Connection conn, List<? extends Object> entities, int tableIndex)
throws SQLException {
int insertCount = 0;
PreparedStatement ps = null;
try {
SQL sql = null;
for (Object entity : entities) {
sql = SQLBuilder.getInsert(entity, tableIndex);
if (ps == null) {
ps = conn.prepareStatement(sql.getSql());
}
fillParam(ps, sql);
ps.addBatch();
}
int[] insertCountArray = ps.executeBatch();
for (int i = 0; i < insertCountArray.length; i++) {
insertCount += insertCountArray[i];
}
} finally {
JdbcUtil.close(ps);
}
return insertCount;
}
/**
* @param tableIndex 等于-1时会被忽略.
* @throws SQLException
*/
protected int _removeByPks(Connection conn, List<EntityPK> pks, Class<?> clazz, int tableIndex) throws SQLException {
int removeCount = 0;
PreparedStatement ps = null;
try {
SQL sql = SQLBuilder.buildDeleteByPks(clazz, tableIndex, pks);
ps = conn.prepareStatement(sql.getSql());
fillParam(ps, sql);
removeCount = ps.executeUpdate();
} finally {
JdbcUtil.close(ps);
}
return removeCount;
}
/**
* @param tableIndex 等于-1时会被忽略.
* @throws SQLException
*/
protected int _updateBatch(Connection conn, List<? extends Object> entities, int tableIndex) throws SQLException {
int updateCount = 0;
PreparedStatement ps = null;
try {
SQL sql = null;
for (Object entity : entities) {
sql = SQLBuilder.getUpdate(entity, tableIndex);
if (ps == null) {
ps = conn.prepareStatement(sql.getSql());
}
fillParam(ps, sql);
ps.addBatch();
}
int[] updateCountArray = ps.executeBatch();
for (int i = 0; i < updateCountArray.length; i++) {
updateCount += updateCountArray[i];
}
} finally {
JdbcUtil.close(ps);
}
return updateCount;
}
}