online.sanen.unabo.sql.Behavior Maven / Gradle / Ivy
Show all versions of unabo Show documentation
package online.sanen.unabo.sql;
import static online.sanen.unabo.api.condition.C.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Consumer;
import com.mhdt.degist.Validate;
import com.mhdt.toolkit.Assert;
import com.mhdt.toolkit.Reflect;
import online.sanen.unabo.api.Bootstrap;
import online.sanen.unabo.api.condition.C;
import online.sanen.unabo.api.condition.CompositeCondition;
import online.sanen.unabo.api.condition.Condition;
import online.sanen.unabo.api.condition.SimpleCondition;
import online.sanen.unabo.api.exception.QueryException;
import online.sanen.unabo.api.structure.Column;
import online.sanen.unabo.api.structure.enums.Sorts;
import online.sanen.unabo.sql.factory.Unabo;
import online.sanen.unabo.sql.pipe.SimplePileline;
import online.sanen.unabo.template.jpa.Id;
import online.sanen.unabo.template.jpa.JPA;
import online.sanen.unabo.template.jpa.NoDB;
import online.sanen.unabo.template.jpa.Table;
import online.sanen.unabo.template.jpa.JPA.PrimaryKey;
/**
*
* User behavior interface.
*
* By default, it provides users with the basic function of insert,
* delete, update and select singlecases.
*
* To keep coding styles consistent, static methods implement common set
* operations (although {@link Bootstrap} instances can still be used, we
* recommend this approach).
*
* All result sets correspond to subclass class name fields, class names
* correspond to table names, object fields correspond to table fields, and
* object field types correspond to table field types.
*
* By default, the query is associated with the class name field name, or
* aliased using the {@link Table} {@link Column} annotation.
*
* Note that this interface cannot execute SQL statements.
*
* @see Bootstrap
*
* @author LazyToShow
* Date: Dec 7, 2018
* Time: 10:28:34 AM
*/
public interface Behavior extends SimplePileline {
/**
*
* @param fields
* @return
*/
default Perfect fields(String... fields) {
Perfect perfect = perfect(bootstrap(), this, fields, null);
return perfect;
}
/**
*
* @param fields
* @return
*/
default Perfect exceptFields(String... fields) {
Perfect perfect = perfect(bootstrap(), this, null, fields);
return perfect;
}
/**
* Inserts the current instance to the database
*
* @return
*/
default int insert() {
return perfect(bootstrap(), this, null, null).insert();
}
/**
* Delete in the database according to the {@link Id}
*
* @return
*/
default int delete() throws QueryException {
checkPrimary();
return bootstrap().query(this).delete();
}
default void checkPrimary() {
PrimaryKey primaryKey = this.getPrimaryKey(this.getClass());
Object primary = primaryKey.getValue(this);
Assert.notNull(primary, "The primary key is null:" + primaryKey + " " + this.getClass());
}
/**
* Specify field modification
*
* @param fields - Only the specified fields in the entity class are modified
* @see #fields(String...)
* @see #update(String...)
* @return
*/
default int update(String... fields) {
checkPrimary();
return fields(fields).update();
}
default int updateBy(String column) {
return perfect(bootstrap(), this, null, null).updateBy(column);
}
/**
* Gets an instance from the database through the primary key
*
* @return
*/
default Optional findByPk() {
return perfect(bootstrap(), this, null, null).findByPk();
}
/**
*
* @param fields
* @return
*/
default Optional findByFields(String... fields) throws QueryException {
return perfect(bootstrap(), this, null, null).findByFields(fields);
}
/**
* Create tables based on data structures
*
* @return
*/
default int createTable() {
return perfect(bootstrap(), this, null, null).createTable();
}
/**
* Delete table
*
* @return
*/
default int dropTable() {
String tableName = Unabo.tableNameByClass(this.getClass());
if (bootstrap().queryTable(tableName).isExsites())
return bootstrap().queryTable(tableName).drop();
return -1;
}
/**
* Get the {@link Bootstrap} instance corresponding to the current model. Note
* that new {@link Bootstrap} should not be constructed here, but should be
* obtained from the created object pool or cache container.
*
* @return
*/
@SuppressWarnings("static-access")
default Bootstrap bootstrap() {
String bootstrapId = JPA.getBootStrapId(this.getClass());
if (Validate.isNullOrEmpty(bootstrapId) && Unabo.sql.isUniqueness())
return Unabo.sql.getFirst();
Assert.notNull(bootstrapId, "The bootstrap instance is not specified id " + this.getClass());
if (Unabo.sql.contains(bootstrapId))
return Unabo.sql.get(bootstrapId);
else
throw new NullPointerException(String.format("The entity(%s) bootstrapId:%s not instance found in %s", this.getClass().getName(),bootstrapId.toString(),Unabo.sql.keys().toString()));
}
/**
* Tell {@link Behavior} the type of instance the interface is about to operate
* on, which is a constructed start function
*
* @param cls
* @return
*/
public static PerfectList specify(Class cls) {
return perfectList(staticBootstrap(cls), cls);
}
/**
*
* @param cls
* @return
*/
static Bootstrap staticBootstrap(Class> cls) {
String bootStrapId = JPA.getBootStrapId(cls);
if (!Validate.isNullOrEmpty(bootStrapId)) {
Bootstrap bootstrap = Unabo.sql.get(JPA.getBootStrapId(cls));
if (bootstrap == null)
throw new BootstrapObtainException("Invalid bootstrap id '" + bootStrapId + "' for class " + cls);
return bootstrap;
} else if (Validate.isNullOrEmpty(bootStrapId) && Unabo.sql.isUniqueness()) {
return Unabo.sql.getFirst();
} else {
throw new BootstrapObtainException("There is no available bootstrap instance");
}
}
/**
*
* @param $bootstrap
* @param $class
* @return
*/
static PerfectList perfectList(Bootstrap $bootstrap, Class $class) {
return new PerfectList() {
List conditions = new ArrayList<>();
Integer[] limit;
private String[] fields;
private String[] excepts;
Sorts sorts;
private String[] sortFields;
@Override
public PerfectList addCondition(Condition cond) {
if (cond != null)
this.conditions.add(cond);
return this;
}
@Override
public PerfectList addCondition(Consumer> conds) {
if (conds != null)
conds.accept(conditions);
return this;
}
@Override
public PerfectList sort(Sorts sorts, String... fields) {
this.sorts = sorts;
this.sortFields = fields;
return this;
}
@Override
public PerfectList limit(Integer... limit) {
this.limit = limit;
return this;
}
@Override
public PerfectList setFields(String... fields) {
this.fields = fields;
return this;
}
@Override
public PerfectList setExcepts(String... excepts) {
this.excepts = excepts;
return this;
}
@Override
public void batchInsert(List list) {
Assert.notNull(list, "List is null");
$bootstrap.query(list).setFields(fields).setExceptFields(excepts).insert();
}
@Override
public void batchUpdate(List list) {
Assert.notNull(list, "List is null");
$bootstrap.query(list).setFields(fields).setExceptFields(excepts).update();
}
@Override
public List list() {
return $bootstrap.queryTable(Unabo.tableNameByClass($class)).setFields(fields).setExceptFields(excepts)
.limit(limit).sort(sorts, sortFields).addCondition(conds -> conds.addAll(conditions))
.entities($class);
}
@Override
public int delete() {
return $bootstrap.queryTable(Unabo.tableNameByClass($class))
.addCondition(conds -> conds.addAll(conditions)).delete();
}
@Override
public List