Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.enterprisemath.dao.big.MyBatisBigEntityDao Maven / Gradle / Ivy
package com.enterprisemath.dao.big;
import com.enterprisemath.dao.filter.Criterium;
import com.enterprisemath.dao.filter.Filter;
import com.enterprisemath.utils.DomainUtils;
import com.enterprisemath.utils.ValidationUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
/**
* Implementation of big entity dao through MyBatis.
*
* @author radek.hecl
*/
public class MyBatisBigEntityDao implements BigEntityDao {
/**
* Builder object.
*/
public static class Builder {
/**
* Factory for sql sessions.
*/
private SqlSessionFactory sqlSessionFactory;
/**
* Mapper from entity type to the collection.
*/
private TypeCollectionMapper typeCollectionMapper;
/**
* Sets factory for sql sessions.
*
* @param sqlSessionFactory factory for sql sessions
* @return this instance
*/
public Builder setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
return this;
}
/**
* Sets mapper from entity type to the collection.
*
* @param typeCollectionMapper mapper from entity type to the collection
* @return this instance
*/
public Builder setTypeCollectionMapper(TypeCollectionMapper typeCollectionMapper) {
this.typeCollectionMapper = typeCollectionMapper;
return this;
}
/**
* Builds the result object.
*
* @return created object
*/
public MyBatisBigEntityDao build() {
return new MyBatisBigEntityDao(this);
}
}
/**
* Factory for sql sessions.
*/
private SqlSessionFactory sqlSessionFactory;
/**
* Mapper from entity type to the collection.
*/
private TypeCollectionMapper typeCollectionMapper;
/**
* Creates new instance.
*
* @param builder builder object
*/
public MyBatisBigEntityDao(Builder builder) {
sqlSessionFactory = builder.sqlSessionFactory;
typeCollectionMapper = builder.typeCollectionMapper;
guardInvariants();
}
/**
* Guards this object to be consistent. Throws exception if this is not the case.
*/
private void guardInvariants() {
ValidationUtils.guardNotNull(sqlSessionFactory, "sqlSessionFactory cannot be null");
ValidationUtils.guardNotNull(typeCollectionMapper, "typeCollectionMapper cannot be null");
}
@Override
public void insertBigEntity(String type, BigEntity entity, InsertOptions options) {
String table = typeCollectionMapper.getCollectionName(type);
List fields = new ArrayList();
List values = new ArrayList();
fields.add("code");
values.add(entity.getCode());
for (String fld : entity.getFields().keySet()) {
fields.add(fld);
values.add(entity.getFields().get(fld));
}
SqlSession session = sqlSessionFactory.openSession();
try {
MyBatisBigEntityMapper mapper = session.getMapper(MyBatisBigEntityMapper.class);
mapper.insertBigEntity(table, fields, values);
} finally {
session.close();
}
}
@Override
public void insertBigEntities(String type, List entities, InsertOptions options) {
if (entities.isEmpty()) {
return;
}
String table = typeCollectionMapper.getCollectionName(type);
List fields = new ArrayList();
fields.add("code");
for (String fld : entities.get(0).getFields().keySet()) {
fields.add(fld);
}
List pureFields = fields.subList(1, fields.size());
Set pureFieldsSet = DomainUtils.softCopySet(pureFields);
List> rawData = new ArrayList>();
SqlSession session = sqlSessionFactory.openSession();
try {
MyBatisBigEntityMapper mapper = session.getMapper(MyBatisBigEntityMapper.class);
for (BigEntity ent : entities) {
ValidationUtils.guardEquals(pureFieldsSet, ent.getFields().keySet(), "all entities must have same fields");
List rawRow = new ArrayList();
rawRow.add(ent.getCode());
for (String field : pureFields) {
rawRow.add(ent.getFields().get(field));
}
rawData.add(rawRow);
if (rawData.size() >= 100) {
mapper.insertBigEntities(table, fields, rawData);
rawData.clear();
}
}
if (!rawData.isEmpty()) {
mapper.insertBigEntities(table, fields, rawData);
rawData.clear();
}
} finally {
session.close();
}
}
@Override
public BigEntityIterator selectBigEntities(String type, Filter filter, Set fields, SelectOptions options) {
String table = typeCollectionMapper.getCollectionName(type);
SqlSession session = sqlSessionFactory.openSession();
try {
MyBatisBigEntityMapper mapper = session.getMapper(MyBatisBigEntityMapper.class);
// fetch data
Set queryFields = DomainUtils.softCopySet(fields);
queryFields.add("code");
List> recs = mapper.selectBigEntities(table, filter, queryFields);
if (recs == null || recs.isEmpty()) {
return new EntIterator(Collections.emptyList());
}
// map data
List res = new ArrayList();
for (Map rec : recs) {
rec = convertKeysToLowerKeys(rec);
BigEntity.Builder builder = new BigEntity.Builder().
setCode((String) rec.get("code"));
for (String field : fields) {
Object obj = rec.get(field.toLowerCase());
if (obj != null && obj instanceof java.sql.Timestamp) {
obj = DomainUtils.copyDate((Date) obj);
}
builder.addField(field, obj);
}
res.add(builder.build());
}
return new EntIterator(res);
} finally {
session.close();
}
}
@Override
public long countBigEntities(String type, List> criteria, CountOptions options) {
String table = typeCollectionMapper.getCollectionName(type);
SqlSession session = sqlSessionFactory.openSession();
try {
MyBatisBigEntityMapper mapper = session.getMapper(MyBatisBigEntityMapper.class);
return mapper.countBigEntities(table, criteria);
} finally {
session.close();
}
}
@Override
public void updateBigEntity(String type, String code, BigEntityUpdate update, UpdateOptions options) {
String table = typeCollectionMapper.getCollectionName(type);
SqlSession session = sqlSessionFactory.openSession();
try {
MyBatisBigEntityMapper mapper = session.getMapper(MyBatisBigEntityMapper.class);
for (String key : update.getUpdateFields().keySet()) {
mapper.updateBigEntityField(table, code, key, update.getUpdateFields().get(key));
}
for (String key : update.getDropFields()) {
mapper.updateBigEntityField(table, code, key, null);
}
} finally {
session.close();
}
}
@Override
public void deleteBigEntity(String type, String code, DeleteOptions options) {
String table = typeCollectionMapper.getCollectionName(type);
SqlSession session = sqlSessionFactory.openSession();
try {
MyBatisBigEntityMapper mapper = session.getMapper(MyBatisBigEntityMapper.class);
mapper.deleteBigEntity(table, code);
} finally {
session.close();
}
}
/**
* Converts keys in the one map to the lower case.
*
* @param source source map
* @return map with lower case keys
*/
private Map convertKeysToLowerKeys(Map source) {
Map res = new HashMap(source.size());
for (String key : source.keySet()) {
res.put(key.toLowerCase(), source.get(key));
}
return res;
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
/**
* Implementation of iterator for entities.
*/
private static class EntIterator implements BigEntityIterator {
/**
* Entities.
*/
private List entities;
/**
* Index.
*/
private int index = 0;
/**
* Lock object.
*/
private final Object lock = new Object();
/**
* Creates new instance.
*
* @param entities list of entities
*/
public EntIterator(List entities) {
this.entities = DomainUtils.softCopyList(entities);
guardInvariants();
}
/**
* Guards this object to be consistent. Throws exception if this is not the case.
*/
private void guardInvariants() {
ValidationUtils.guardNotNullCollection(entities, "entities cannot have null element");
}
@Override
public boolean isNextAvailable() {
synchronized (lock) {
return index < entities.size();
}
}
@Override
public BigEntity getNext() throws NoSuchElementException {
synchronized (lock) {
if (index >= entities.size()) {
throw new NoSuchElementException("iterator is consumed");
}
BigEntity res = entities.get(index);
index = index + 1;
return res;
}
}
}
}