me.zzp.ar.Table Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jactiverecord Show documentation
Show all versions of jactiverecord Show documentation
ActiveRecord of Ruby on Rails in Java
package me.zzp.ar;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import me.zzp.ar.ex.IllegalFieldNameException;
import me.zzp.ar.ex.SqlExecuteException;
import me.zzp.ar.sql.SqlBuilder;
import me.zzp.ar.sql.TSqlBuilder;
import me.zzp.util.Seq;
/**
* 表对象。
*
* @since 1.0
* @author redraiment
*/
public final class Table {
final DB dbo;
final String name;
final Map columns;
final Map relations;
final String primaryKey;
private String foreignTable;
private final Map foreignKeys = new HashMap<>();
Table(DB dbo, String name, Map columns, Map relations) {
this.dbo = dbo;
this.name = name;
this.columns = columns;
this.relations = relations;
this.primaryKey = name.concat(".id");
}
public Map getColumns() {
return Collections.unmodifiableMap(columns);
}
/* Association */
private Association assoc(String name, boolean onlyOne, boolean ancestor) {
name = DB.parseKeyParameter(name);
Association assoc = new Association(relations, name, onlyOne, ancestor);
relations.put(name, assoc);
return assoc;
}
public Association belongsTo(String name) {
return assoc(name, true, false);
}
public Association hasOne(String name) {
return assoc(name, true, true);
}
public Association hasMany(String name) {
return assoc(name, false, true);
}
public Association hasAndBelongsToMany(String name) {
return assoc(name, false, false);
}
private String[] getForeignKeys() {
List conditions = new ArrayList<>();
for (Map.Entry e : foreignKeys.entrySet()) {
conditions.add(String.format("%s.%s = %d", name, e.getKey(), e.getValue()));
}
return conditions.toArray(new String[0]);
}
public Table constrain(String key, int id) {
foreignKeys.put(DB.parseKeyParameter(key), id);
return this;
}
public Table join(String table) {
this.foreignTable = table;
return this;
}
/* CRUD */
public Record create(Object... args) {
Map data = new HashMap<>();
data.putAll(foreignKeys);
for (int i = 0; i < args.length; i += 2) {
String key = DB.parseKeyParameter(args[i].toString());
if (!columns.containsKey(key)) {
throw new IllegalFieldNameException(key);
}
Object value = args[i + 1];
data.put(key, value);
}
String[] fields = new String[data.size() + 2];
int[] types = new int[data.size() + 2];
Object[] values = new Object[data.size() + 2];
int index = 0;
for (Map.Entry e : data.entrySet()) {
fields[index] = e.getKey();
types[index] = columns.get(e.getKey());
values[index] = e.getValue();
index++;
}
Seq.assignAt(fields, Seq.array(-2, -1), "created_at", "updated_at");
Seq.assignAt(types, Seq.array(-2, -1), Types.TIMESTAMP, Types.TIMESTAMP);
Seq.assignAt(values, Seq.array(-2, -1), DB.now(), DB.now());
SqlBuilder sql = new TSqlBuilder();
sql.insert().into(name).values(fields);
PreparedStatement call = dbo.prepare(sql.toString(), values, types);
try {
int id = 0;
if (call.executeUpdate() > 0) {
ResultSet rs = call.getGeneratedKeys();
if (rs != null && rs.next()) {
id = rs.getInt(1);
rs.close();
}
}
return id > 0 ? find(id) : null;
} catch (SQLException e) {
throw new SqlExecuteException(sql.toString(), e);
} finally {
dbo.close(call);
}
}
/**
* 根据现有的Record创建新的Record.
* 为跨数据库之间导数据提供便捷接口;同时也方便根据模板创建多条相似的纪录。
* @param o Record对象
* @return 根据参数创建的新的Record对象
*/
public Record create(Record o) {
List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy