Skip to content

Commit 124b8f2

Browse files
authored
Merge pull request #1615 from ywjno/jsonAdaptor
给Mysql跟Postgresql添加保存JSON内容时的设置格式的ValueAdaptor
2 parents 6b2ede7 + be0c559 commit 124b8f2

16 files changed

+374
-14
lines changed

pom.xml

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,19 @@
8888
<dependency>
8989
<groupId>org.postgresql</groupId>
9090
<artifactId>postgresql</artifactId>
91-
<version>9.4-1206-jdbc41</version>
91+
<version>42.7.4</version>
9292
<scope>test</scope>
9393
</dependency>
9494
<dependency>
95-
<groupId>mysql</groupId>
96-
<artifactId>mysql-connector-java</artifactId>
97-
<version>8.0.21</version>
95+
<groupId>com.mysql</groupId>
96+
<artifactId>mysql-connector-j</artifactId>
97+
<version>8.2.0</version>
98+
<scope>test</scope>
99+
</dependency>
100+
<dependency>
101+
<groupId>org.mariadb.jdbc</groupId>
102+
<artifactId>mariadb-java-client</artifactId>
103+
<version>3.4.1</version>
98104
<scope>test</scope>
99105
</dependency>
100106
<dependency>

src/org/nutz/dao/impl/jdbc/mysql/MysqlJdbcExpert.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,12 @@ public Pojo fetchPojoId(Entity<?> en, MappingField idField) {
196196
@Override
197197
public ValueAdaptor getAdaptor(MappingField ef) {
198198
if (ColType.MYSQL_JSON == ef.getColumnType()) {
199-
return new MysqlJsonAdaptor();
199+
ValueAdaptor adaptor = ef.getAdaptor();
200+
if (adaptor instanceof MysqlJsonAdaptor) {
201+
return adaptor;
202+
} else {
203+
return new MysqlJsonAdaptor();
204+
}
200205
} else {
201206
return super.getAdaptor(ef);
202207
}

src/org/nutz/dao/impl/jdbc/mysql/MysqlJsonAdaptor.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
* 注意,必要的时候需要给 POJO 添加<b>带一个参数的静态工厂方法</b>或者<b>带一个参数的构造函数</b>,<br>
1818
* 显示的使用 java.sql.ResultSet 来创建该 POJO,不然会出现无法映射的错误。
1919
* <p/>
20+
* 数据库中默认使用 {@code JsonFormat.tidy()} 格式来保存JSON类型字段的值。
21+
* <p/>
2022
*
2123
* <pre>
2224
* public class Pet {
@@ -59,6 +61,16 @@
5961
*/
6062
public class MysqlJsonAdaptor implements ValueAdaptor {
6163

64+
private JsonFormat jsonFormat;
65+
66+
public MysqlJsonAdaptor() {
67+
this.jsonFormat = JsonFormat.tidy();
68+
}
69+
70+
public void setJsonFormat(JsonFormat jsonFormat) {
71+
this.jsonFormat = jsonFormat;
72+
}
73+
6274
public Object get(ResultSet rs, String colName) throws SQLException {
6375
return rs.getObject(colName);
6476
}
@@ -67,7 +79,7 @@ public void set(PreparedStatement stat, Object obj, int index) throws SQLExcepti
6779
if (null == obj) {
6880
stat.setNull(index, Types.NULL);
6981
} else {
70-
stat.setObject(index, Json.toJson(obj, JsonFormat.tidy()), Types.VARCHAR);
82+
stat.setObject(index, Json.toJson(obj, jsonFormat), Types.VARCHAR);
7183
}
7284
}
7385
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.nutz.dao.impl.jdbc.mysql;
2+
3+
import org.nutz.json.JsonFormat;
4+
5+
/**
6+
* 数据库中使用 {@code JsonFormat.compact()} 格式来保存JSON类型字段的值。
7+
* <p />
8+
* 使用时 {@code ColDefine} 注解的 {@code adaptor} 属性显示声明为 {@code MysqlJsonCompactAdaptor.class}
9+
* <p />
10+
* <pre>
11+
* {@code
12+
* @ColDefine(customType = "json", type = ColType.MYSQL_JSON, adaptor = MysqlJsonCompactAdaptor.class)
13+
* private Information info;
14+
* }
15+
* </pre>
16+
*/
17+
public class MysqlJsonCompactAdaptor extends MysqlJsonAdaptor {
18+
19+
public MysqlJsonCompactAdaptor() {
20+
setJsonFormat(JsonFormat.compact());
21+
}
22+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.nutz.dao.impl.jdbc.mysql;
2+
3+
import org.nutz.json.JsonFormat;
4+
5+
/**
6+
* 数据库中使用 {@code JsonFormat.tidy()} 格式来保存JSON类型字段的值。
7+
* <p />
8+
* 使用时 {@code ColDefine} 注解的 {@code adaptor} 属性显示声明为 {@code MysqlJsonTidyAdaptor.class}
9+
* <p />
10+
* <pre>
11+
* {@code
12+
* @ColDefine(customType = "json", type = ColType.MYSQL_JSON, adaptor = MysqlJsonTidyAdaptor.class)
13+
* private Information info;
14+
* }
15+
* </pre>
16+
*/
17+
public class MysqlJsonTidyAdaptor extends MysqlJsonAdaptor {
18+
19+
public MysqlJsonTidyAdaptor() {
20+
setJsonFormat(JsonFormat.tidy());
21+
}
22+
}

src/org/nutz/dao/impl/jdbc/psql/PsqlJdbcExpert.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,12 @@ public ValueAdaptor getAdaptor(MappingField ef) {
169169
if (ef.getMirror().isOf(Blob.class)) {
170170
return new BlobValueAdaptor3(Jdbcs.getFilePool());
171171
} else if (ColType.PSQL_JSON == ef.getColumnType()) {
172-
return new PsqlJsonAdaptor();
172+
ValueAdaptor adaptor = ef.getAdaptor();
173+
if (adaptor instanceof PsqlJsonAdaptor) {
174+
return adaptor;
175+
} else {
176+
return new PsqlJsonAdaptor();
177+
}
173178
} else if (ColType.PSQL_ARRAY == ef.getColumnType()) {
174179
return new PsqlArrayAdaptor(ef.getCustomDbType());
175180
} else {

src/org/nutz/dao/impl/jdbc/psql/PsqlJsonAdaptor.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
* 注意,必要的时候需要给 POJO 添加<b>带一个参数的静态工厂方法</b>或者<b>带一个参数的构造函数</b>,<br>
1818
* 显示的使用 java.sql.ResultSet 来创建该 POJO,不然会出现无法映射的错误。
1919
* <p/>
20+
* 数据库中默认使用 {@code JsonFormat.tidy()} 格式来保存JSON类型字段的值。
21+
* <p/>
22+
*
2023
* <pre>
2124
* public class Pet {
2225
*
@@ -58,6 +61,16 @@
5861
*/
5962
public class PsqlJsonAdaptor implements ValueAdaptor {
6063

64+
private JsonFormat jsonFormat;
65+
66+
public PsqlJsonAdaptor() {
67+
this.jsonFormat = JsonFormat.tidy();
68+
}
69+
70+
public void setJsonFormat(JsonFormat jsonFormat) {
71+
this.jsonFormat = jsonFormat;
72+
}
73+
6174
public Object get(ResultSet rs, String colName) throws SQLException {
6275
return rs.getObject(colName);
6376
}
@@ -66,7 +79,7 @@ public void set(PreparedStatement stat, Object obj, int index) throws SQLExcepti
6679
if (null == obj) {
6780
stat.setNull(index, Types.NULL);
6881
} else {
69-
stat.setObject(index, Json.toJson(obj, JsonFormat.tidy()), Types.OTHER);
82+
stat.setObject(index, Json.toJson(obj, jsonFormat), Types.OTHER);
7083
}
7184
}
7285
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.nutz.dao.impl.jdbc.psql;
2+
3+
import org.nutz.json.JsonFormat;
4+
5+
/**
6+
* 数据库中使用 {@code JsonFormat.compact()} 格式来保存JSON类型字段的值。
7+
* <p />
8+
* 使用时 {@code ColDefine} 注解的 {@code adaptor} 属性显示声明为 {@code PsqlJsonCompactAdaptor.class}
9+
* <p />
10+
* <pre>
11+
* {@code
12+
* @ColDefine(customType = "json", type = ColType.PSQL_JSON, adaptor = PsqlJsonCompactAdaptor.class)
13+
* private Information info;
14+
* }
15+
* </pre>
16+
*/
17+
public class PsqlJsonCompactAdaptor extends PsqlJsonAdaptor {
18+
19+
public PsqlJsonCompactAdaptor() {
20+
setJsonFormat(JsonFormat.compact());
21+
}
22+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.nutz.dao.impl.jdbc.psql;
2+
3+
import org.nutz.json.JsonFormat;
4+
5+
/**
6+
* 数据库中使用 {@code JsonFormat.tidy()} 格式来保存JSON类型字段的值。
7+
* <p />
8+
* 使用时 {@code ColDefine} 注解的 {@code adaptor} 属性显示声明为 {@code PsqlJsonTidyAdaptor.class}
9+
* <p />
10+
* <pre>
11+
* {@code
12+
* @ColDefine(customType = "json", type = ColType.PSQL_JSON, adaptor = PsqlJsonTidyAdaptor.class)
13+
* private Information info;
14+
* }
15+
* </pre>
16+
*/
17+
public class PsqlJsonTidyAdaptor extends PsqlJsonAdaptor {
18+
19+
public PsqlJsonTidyAdaptor() {
20+
setJsonFormat(JsonFormat.tidy());
21+
}
22+
}

test/org/nutz/dao/test/normal/mysql/AllMysqlTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44
import org.junit.runners.Suite;
55

66
@RunWith(Suite.class)
7-
@Suite.SuiteClasses({MysqlJsonTest.class})
7+
@Suite.SuiteClasses({MysqlJsonTest.class, MysqlJsonAdaptorTest.class})
88
public class AllMysqlTest {}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package org.nutz.dao.test.normal.mysql;
2+
3+
import static org.junit.Assert.assertEquals;
4+
5+
import java.math.BigDecimal;
6+
7+
import org.junit.Test;
8+
import org.nutz.dao.Cnd;
9+
import org.nutz.dao.test.DaoCase;
10+
import org.nutz.json.Json;
11+
import org.nutz.json.JsonFormat;
12+
13+
public class MysqlJsonAdaptorTest extends DaoCase {
14+
15+
@Override
16+
protected void before() {
17+
if (!dao.meta().isMySql()) {
18+
return;
19+
}
20+
dao.create(MysqlJsonAdaptorTestBean.class, true);
21+
}
22+
23+
@Test
24+
public void adapotor() {
25+
if (!dao.meta().isMySql()) {
26+
return;
27+
}
28+
29+
MysqlJsonAdaptorTestBean testBean = new MysqlJsonAdaptorTestBean();
30+
StudentResult result = new StudentResult();
31+
result.setPhysics(new BigDecimal("100"));
32+
testBean.setNoneAdaptor(result);
33+
testBean.setJsonAdaptor(result);
34+
testBean.setJsonCompactAdaptor(result);
35+
testBean.setJsonTidyAdaptor(result);
36+
37+
int insertId = dao.insert(testBean).getId();
38+
39+
org.nutz.dao.entity.Record record = dao.fetch("t_mysql_json_adaptor_test_bean", Cnd.where("id","=",insertId));
40+
// mysql 在保存 json 格式字段的时候会自动格式化该字段的值
41+
// mariadb 的话就没问题
42+
assertEquals(Json.toJson(result, JsonFormat.tidy()), record.getString("noneAdaptor"));
43+
assertEquals(Json.toJson(result, JsonFormat.tidy()), record.getString("noneAdaptor"));
44+
assertEquals(Json.toJson(result, JsonFormat.tidy()), record.getString("jsonAdaptor"));
45+
assertEquals(Json.toJson(result, JsonFormat.compact()), record.getString("jsonCompactAdaptor"));
46+
assertEquals(Json.toJson(result, JsonFormat.tidy()), record.getString("jsonTidyAdaptor"));
47+
}
48+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package org.nutz.dao.test.normal.mysql;
2+
3+
import org.nutz.dao.entity.annotation.ColDefine;
4+
import org.nutz.dao.entity.annotation.ColType;
5+
import org.nutz.dao.entity.annotation.Id;
6+
import org.nutz.dao.entity.annotation.Table;
7+
import org.nutz.dao.impl.jdbc.mysql.MysqlJsonAdaptor;
8+
import org.nutz.dao.impl.jdbc.mysql.MysqlJsonCompactAdaptor;
9+
import org.nutz.dao.impl.jdbc.mysql.MysqlJsonTidyAdaptor;
10+
11+
@Table("t_mysql_json_adaptor_test_bean")
12+
public class MysqlJsonAdaptorTestBean {
13+
14+
@Id
15+
private int id;
16+
17+
@ColDefine(customType = "json", type = ColType.MYSQL_JSON)
18+
private StudentResult noneAdaptor;
19+
20+
@ColDefine(customType = "json", type = ColType.MYSQL_JSON, adaptor = MysqlJsonAdaptor.class)
21+
private StudentResult jsonAdaptor;
22+
23+
@ColDefine(customType = "json", type = ColType.MYSQL_JSON, adaptor = MysqlJsonCompactAdaptor.class)
24+
private StudentResult jsonCompactAdaptor;
25+
26+
@ColDefine(customType = "json", type = ColType.MYSQL_JSON, adaptor = MysqlJsonTidyAdaptor.class)
27+
private StudentResult jsonTidyAdaptor;
28+
29+
public int getId() {
30+
return id;
31+
}
32+
33+
public void setId(int id) {
34+
this.id = id;
35+
}
36+
37+
public StudentResult getNoneAdaptor() {
38+
return noneAdaptor;
39+
}
40+
41+
public void setNoneAdaptor(StudentResult noneAdaptor) {
42+
this.noneAdaptor = noneAdaptor;
43+
}
44+
45+
public StudentResult getJsonAdaptor() {
46+
return jsonAdaptor;
47+
}
48+
49+
public void setJsonAdaptor(StudentResult jsonAdaptor) {
50+
this.jsonAdaptor = jsonAdaptor;
51+
}
52+
53+
public StudentResult getJsonCompactAdaptor() {
54+
return jsonCompactAdaptor;
55+
}
56+
57+
public void setJsonCompactAdaptor(StudentResult jsonCompactAdaptor) {
58+
this.jsonCompactAdaptor = jsonCompactAdaptor;
59+
}
60+
61+
public StudentResult getJsonTidyAdaptor() {
62+
return jsonTidyAdaptor;
63+
}
64+
65+
public void setJsonTidyAdaptor(StudentResult jsonTidyAdaptor) {
66+
this.jsonTidyAdaptor = jsonTidyAdaptor;
67+
}
68+
}

test/org/nutz/dao/test/normal/psql/AllPsqlTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44
import org.junit.runners.Suite;
55

66
@RunWith(Suite.class)
7-
@Suite.SuiteClasses({PsqlJsonTest.class, PsqlArrayTest.class})
7+
@Suite.SuiteClasses({PsqlJsonTest.class, PsqlArrayTest.class, PsqlJsonAdaptorTest.class})
88
public class AllPsqlTest {}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package org.nutz.dao.test.normal.psql;
2+
3+
import static org.junit.Assert.assertEquals;
4+
5+
import java.math.BigDecimal;
6+
7+
import org.junit.Test;
8+
import org.nutz.dao.Cnd;
9+
import org.nutz.dao.test.DaoCase;
10+
import org.nutz.json.Json;
11+
import org.nutz.json.JsonFormat;
12+
13+
public class PsqlJsonAdaptorTest extends DaoCase {
14+
15+
@Override
16+
protected void before() {
17+
if (!dao.meta().isPostgresql()) {
18+
return;
19+
}
20+
dao.create(PsqlJsonAdaptorTestBean.class, true);
21+
}
22+
23+
@Test
24+
public void adapotor() {
25+
if (!dao.meta().isPostgresql()) {
26+
return;
27+
}
28+
29+
PsqlJsonAdaptorTestBean testBean = new PsqlJsonAdaptorTestBean();
30+
org.nutz.dao.test.normal.psql.StudentResult result = new StudentResult();
31+
result.setPhysics(new BigDecimal("100"));
32+
testBean.setNoneAdaptor(result);
33+
testBean.setJsonAdaptor(result);
34+
testBean.setJsonCompactAdaptor(result);
35+
testBean.setJsonTidyAdaptor(result);
36+
37+
int insertId = dao.insert(testBean).getId();
38+
39+
org.nutz.dao.entity.Record record = dao.fetch("t_psql_json_adaptor_test_bean", Cnd.where("id","=",insertId));
40+
// 设置成 jsonb 格式的时候会自动格式化该字段的值
41+
assertEquals(Json.toJson(result, JsonFormat.tidy()), record.getString("noneAdaptor"));
42+
assertEquals(Json.toJson(result, JsonFormat.tidy()), record.getString("noneAdaptor"));
43+
assertEquals(Json.toJson(result, JsonFormat.tidy()), record.getString("jsonAdaptor"));
44+
assertEquals(Json.toJson(result, JsonFormat.compact()), record.getString("jsonCompactAdaptor"));
45+
assertEquals(Json.toJson(result, JsonFormat.tidy()), record.getString("jsonTidyAdaptor"));
46+
}
47+
}

0 commit comments

Comments
 (0)