Skip to content
This repository has been archived by the owner on Nov 7, 2023. It is now read-only.

Commit

Permalink
在model对象和json字符串之间相互转换时可以设置model属性名的格式,支持驼峰、大小写下划线三种格式
Browse files Browse the repository at this point in the history
  • Loading branch information
codefollower committed Oct 25, 2022
1 parent dfd2bd9 commit 073c656
Show file tree
Hide file tree
Showing 14 changed files with 220 additions and 30 deletions.
38 changes: 35 additions & 3 deletions orm/src/main/java/org/lealone/plugins/orm/Model.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ public abstract class Model<T extends Model<T>> {
public static final short ROOT_DAO = 1;
public static final short CHILD_DAO = 2;

public enum CaseFormat {
CAMEL,
LOWER_UNDERSCORE,
UPPER_UNDERSCORE
}

private static final Logger logger = LoggerFactory.getLogger(Model.class);

private static final ConcurrentSkipListMap<Long, ServerSession> currentSessions = new ConcurrentSkipListMap<>();
Expand Down Expand Up @@ -591,10 +597,26 @@ protected static boolean areEqual(PBase<?, ?> p1, PBase<?, ?> p2) {
return ModelProperty.areEqual(p1.get(), p2.get());
}

private CaseFormat getCaseFormat() {
String cf = modelTable.getTable().getParameter("caseFormat");
CaseFormat format;
if (cf == null)
format = CaseFormat.UPPER_UNDERSCORE;
else
format = CaseFormat.valueOf(cf.toUpperCase());
return format;
}

public Map<String, Object> toMap() {
return toMap(null);
}

public Map<String, Object> toMap(CaseFormat format) {
if (format == null)
format = getCaseFormat();
Map<String, Object> map = new LinkedHashMap<>();
for (ModelProperty<?> p : modelProperties) {
p.serialize(map);
p.serialize(map, format);
}
if (modelMap != null) {
for (Entry<Class, ArrayList<Model<?>>> e : modelMap.entrySet()) {
Expand All @@ -606,13 +628,23 @@ public Map<String, Object> toMap() {
}

public String encode() {
return new JsonObject(toMap()).encode();
return encode(null);
}

public String encode(CaseFormat format) {
return new JsonObject(toMap(format)).encode();
}

protected T decode0(String str) {
return decode0(str, null);
}

protected T decode0(String str, CaseFormat format) {
if (format == null)
format = getCaseFormat();
Map<String, Object> map = new JsonObject(str).getMap();
for (ModelProperty<?> p : modelProperties) {
Object v = map.get(p.getName());
Object v = map.get(p.getName(format));
if (v != null) {
// 先反序列化再set,这样Model的子类对象就可以在后续调用insert之类的方法
p.deserializeAndSet(v);
Expand Down
19 changes: 19 additions & 0 deletions orm/src/main/java/org/lealone/plugins/orm/ModelProperty.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
import java.util.HashMap;
import java.util.Map;

import org.lealone.common.util.CamelCaseHelper;
import org.lealone.db.value.Value;
import org.lealone.plugins.orm.Model.CaseFormat;

/**
* A property used in type query.
Expand Down Expand Up @@ -43,6 +45,19 @@ public String getName() {
return name;
}

public String getName(CaseFormat format) {
String n = name;
switch (format) {
case CAMEL:
n = CamelCaseHelper.toCamelFromUnderscore(n);
break;
case LOWER_UNDERSCORE:
n = n.toLowerCase();
break;
}
return n;
}

protected String getFullName() {
if (fullName == null) {
fullName = getSchemaName() + "." + getTableName() + "." + name;
Expand Down Expand Up @@ -119,6 +134,10 @@ public final M eq(ModelProperty<?> p) {
}

protected void serialize(Map<String, Object> map) {
this.serialize(map, CaseFormat.UPPER_UNDERSCORE);
}

protected void serialize(Map<String, Object> map, CaseFormat format) {
}

protected void deserialize(Object v) {
Expand Down
8 changes: 5 additions & 3 deletions orm/src/main/java/org/lealone/plugins/orm/property/PBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import org.lealone.db.value.Value;
import org.lealone.plugins.orm.Model;
import org.lealone.plugins.orm.Model.CaseFormat;
import org.lealone.plugins.orm.ModelProperty;

public abstract class PBase<M extends Model<M>, T> extends ModelProperty<M> {
Expand Down Expand Up @@ -51,9 +52,10 @@ protected Object encodeValue() {
}

@Override
protected final void serialize(Map<String, Object> map) {
if (value != null)
map.put(getName(), encodeValue());
protected final void serialize(Map<String, Object> map, CaseFormat format) {
if (value != null) {
map.put(getName(format), encodeValue());
}
}

@Override
Expand Down
17 changes: 0 additions & 17 deletions test/src/test/java/org/lealone/plugins/test/orm/DaoTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import java.util.concurrent.CountDownLatch;

import org.junit.Test;
import org.lealone.plugins.orm.json.JsonObject;
import org.lealone.plugins.test.orm.generated.User;;

public class DaoTest extends OrmTestBase {
Expand All @@ -18,22 +17,6 @@ public void run() {
// SqlScript.createUserTable(this);
testMultiThreads();
crud();
json();
}

void json() {
// dao对象序列化后包含modelType字段,并且是ROOT_DAO
JsonObject json = new JsonObject(User.dao.encode());
assertTrue(json.getInteger("modelType") == User.ROOT_DAO);

// 反序列化
String str = json.encode();
User u = User.decode(str);
assertTrue(u.isDao());

// 普通User对象序列化后也包含modelType字段,但为REGULAR_MODEL
json = new JsonObject(new User().encode());
assertTrue(json.getInteger("modelType") == User.REGULAR_MODEL);
}

// 测试多个线程同时使用User.dao是否产生混乱
Expand Down
71 changes: 71 additions & 0 deletions test/src/test/java/org/lealone/plugins/test/orm/OrmJsonTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright Lealone Database Group.
* Licensed under the Server Side Public License, v 1.
* Initial Developer: zhh
*/
package org.lealone.plugins.test.orm;

import org.junit.Before;
import org.junit.Test;
import org.lealone.plugins.orm.Model.CaseFormat;
import org.lealone.plugins.orm.json.JsonObject;
import org.lealone.plugins.test.orm.generated.JsonTestTable;
import org.lealone.plugins.test.orm.generated.User;

public class OrmJsonTest extends OrmTestBase {

@Before
@Override
public void setUpBefore() {
setEmbedded(true);
setInMemory(true);
SqlScript.createUserTable(this);
SqlScript.createJsonTestTable(this);
}

@Test
public void run() {
testModelType();
testCaseFormat();
}

void testModelType() {
// dao对象序列化后包含modelType字段,并且是ROOT_DAO
JsonObject json = new JsonObject(User.dao.encode());
assertTrue(json.getInteger("modelType") == User.ROOT_DAO);

// 反序列化
String str = json.encode();
User u = User.decode(str);
assertTrue(u.isDao());

// 普通User对象序列化后也包含modelType字段,但为REGULAR_MODEL
json = new JsonObject(new User().encode());
assertTrue(json.getInteger("modelType") == User.REGULAR_MODEL);
}

void testCaseFormat() {
User user = new User().id.set(1006).name.set("rob6").phones.set(new Object[] { 1, 2, 3 });
String json = user.encode();
JsonObject jsonObject = new JsonObject(json);
assertEquals(jsonObject.getString(User.dao.name.getName()), user.name.get());
User u = User.decode(json);
assertEquals(u.name.get(), user.name.get());

json = user.encode(CaseFormat.CAMEL);
jsonObject = new JsonObject(json);
assertEquals(jsonObject.getString(User.dao.name.getName(CaseFormat.CAMEL)), user.name.get());

JsonTestTable t1 = new JsonTestTable().propertyName1.set(1).propertyName2.set(3);
json = t1.encode();
jsonObject = new JsonObject(json);
assertEquals(jsonObject.getInteger(JsonTestTable.dao.propertyName1.getName(CaseFormat.CAMEL)),
t1.propertyName1.get());
JsonTestTable t2 = JsonTestTable.decode(json);
assertEquals(t1.propertyName2.get(), t2.propertyName2.get());

json = t1.encode(CaseFormat.LOWER_UNDERSCORE);
t2 = JsonTestTable.decode(json, CaseFormat.LOWER_UNDERSCORE);
assertEquals(t1.propertyName2.get(), t2.propertyName2.get());
}
}
11 changes: 11 additions & 0 deletions test/src/test/java/org/lealone/plugins/test/orm/SqlScript.java
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,17 @@ public static void createOrderItemTable(SqlExecutor executor) {
);
}

public static void createJsonTestTable(SqlExecutor executor) {
System.out.println("create table: json_test_table");

executor.execute("drop table if exists json_test_table");
executor.execute(
"create table if not exists json_test_table(property_name1 int, property_name2 long)" //
+ " parameters(caseFormat='CAMEL')" //
+ " package '" + MODEL_PACKAGE_NAME + "'" //
+ " generate code '" + GENERATED_CODE_PATH + "'");
}

// 21种模型属性类型,目前不支持GEOMETRY类型
// INT
// BOOLEAN
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ protected AllModelProperty newInstance(ModelTable t, short modelType) {
}

public static AllModelProperty decode(String str) {
return new AllModelProperty().decode0(str);
return decode(str, null);
}

public static AllModelProperty decode(String str, CaseFormat format) {
return new AllModelProperty().decode0(str, format);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ public void add(Order m) {
}

public static Customer decode(String str) {
return new Customer().decode0(str);
return decode(str, null);
}

public static Customer decode(String str, CaseFormat format) {
return new Customer().decode0(str, format);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ public boolean set(Customer m) {
}

public static CustomerAddress decode(String str) {
return new CustomerAddress().decode0(str);
return decode(str, null);
}

public static CustomerAddress decode(String str, CaseFormat format) {
return new CustomerAddress().decode0(str, format);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package org.lealone.plugins.test.orm.generated;

import org.lealone.plugins.orm.Model;
import org.lealone.plugins.orm.ModelProperty;
import org.lealone.plugins.orm.ModelTable;
import org.lealone.plugins.orm.property.PInteger;
import org.lealone.plugins.orm.property.PLong;

/**
* Model for table 'JSON_TEST_TABLE'.
*
* THIS IS A GENERATED OBJECT, DO NOT MODIFY THIS CLASS.
*/
public class JsonTestTable extends Model<JsonTestTable> {

public static final JsonTestTable dao = new JsonTestTable(null, ROOT_DAO);

public final PInteger<JsonTestTable> propertyName1;
public final PLong<JsonTestTable> propertyName2;

public JsonTestTable() {
this(null, REGULAR_MODEL);
}

private JsonTestTable(ModelTable t, short modelType) {
super(t == null ? new ModelTable("TEST", "PUBLIC", "JSON_TEST_TABLE") : t, modelType);
propertyName1 = new PInteger<>("PROPERTY_NAME1", this);
propertyName2 = new PLong<>("PROPERTY_NAME2", this);
super.setModelProperties(new ModelProperty[] { propertyName1, propertyName2 });
}

@Override
protected JsonTestTable newInstance(ModelTable t, short modelType) {
return new JsonTestTable(t, modelType);
}

public static JsonTestTable decode(String str) {
return decode(str, null);
}

public static JsonTestTable decode(String str, CaseFormat format) {
return new JsonTestTable().decode0(str, format);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ public void add(OrderItem m) {
}

public static Order decode(String str) {
return new Order().decode0(str);
return decode(str, null);
}

public static Order decode(String str, CaseFormat format) {
return new Order().decode0(str, format);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ public boolean set(Product m) {
}

public static OrderItem decode(String str) {
return new OrderItem().decode0(str);
return decode(str, null);
}

public static OrderItem decode(String str, CaseFormat format) {
return new OrderItem().decode0(str, format);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ protected Product newInstance(ModelTable t, short modelType) {
}

public static Product decode(String str) {
return new Product().decode0(str);
return decode(str, null);
}

public static Product decode(String str, CaseFormat format) {
return new Product().decode0(str, format);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ protected User newInstance(ModelTable t, short modelType) {
}

public static User decode(String str) {
return new User().decode0(str);
return decode(str, null);
}

public static User decode(String str, CaseFormat format) {
return new User().decode0(str, format);
}
}

0 comments on commit 073c656

Please sign in to comment.