自认为
优点:数据库存储为单纯的数据,不需要额外存储类型
缺点:不够通用 对于Map、Object、List能用,但是对于List>不太行
需要写两个Typehander不够优雅
接下来,简单过一下流程(只有插入和查找)
notice: 使用的转换JSON工具是hutool中的,如果自己有别的转换可以使用别的json转换工具
hutool工具包
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.11</version>
</dependency>
JsonTypeHandler 这个负责非List,一般存储的都是Map,Object,和List
public class JsonTypeHandler<T> extends BaseTypeHandler<T>{
private Class<T> clazz;
//在Mybatis中将类型注入进来
public JsonTypeHandler(Class<T> clazz) {
this.clazz = clazz;
}
//写入数据
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, JSONUtil.toJsonStr(parameter));
}
/**
* 一般是根据列名字获取下方就不再详述“(因为我也不知道,还没用到)
* @param rs 结果
* @param colName 列名
*/
@SneakyThrows
@Override
public T getNullableResult(ResultSet rs, String colName) {
String data = rs.getString(colName);
return StrUtil.isBlank(data) ? null : JSONUtil.toBean(data, clazz);
}
@SneakyThrows
@Override
public T getNullableResult(ResultSet rs, int colIndex) {
String data = rs.getString(colIndex);
return StrUtil.isBlank(data) ? null : JSONUtil.toBean(data, clazz);
}
@SneakyThrows
@Override
public T getNullableResult(CallableStatement cs, int i) {
String data = cs.getString(i);
return StrUtil.isBlank(data) ? null : JSONUtil.toBean(data, clazz);
}
}
public class ListJsonTypeHandler<T> extends BaseTypeHandler<List<T>> implements InitializingBean {
private Class<T> clazz;
public ListJsonTypeHandler(Class<T> clazz) {
this.clazz = clazz;
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, List<T> parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, JSONUtil.toJsonStr(parameter));
}
@Override
public List<T> getNullableResult(ResultSet rs, String columnName) throws SQLException {
String data = rs.getString(columnName);
return StrUtil.isBlank(data) ? null : JSONUtil.parseArray(data).toList(clazz);
}
@SneakyThrows
@Override
public List<T> getNullableResult(ResultSet rs, int colIndex) {
String data = rs.getString(colIndex);
return StrUtil.isBlank(data) ? null : JSONUtil.parseArray(data).toList(clazz);
}
@SneakyThrows
@Override
public List<T> getNullableResult(CallableStatement cs, int i) {
String data = cs.getString(i);
return StrUtil.isBlank(data) ? null : JSONUtil.parseArray(data).toList(clazz);
}
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Json {
/**
* 唯一标识
*/
private Integer id;
/**
* map
*/
private Map<String,Object> mapJson;
/**
* 对象
* 这个对象自定义的放在下面
*/
private Object objJson;
/**
* list集合
* extends Object>这个我也不知道怎么设置 但是用这个没错
*/
private List<? extends Object> listJson;
}
//测试的对象
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class JsonObj {
/**
* 唯一id
*/
private Integer id;
/**
* 测试所用
*/
private String str;
}
//查找 不建议用 * 代替 我是为啦偷工减料
@Select(" SELECT * from json ")
@Results(value = {
@Result(property = "id", column = "id"),
@Result(property = "mapJson", column = "mapJson", typeHandler = JsonTypeHandler.class,javaType = HashMap.class),
@Result(property = "objJson", column = "objJson", typeHandler = JsonTypeHandler.class,javaType = JsonObj.class),
@Result(property = "listJson", column = "listJson", typeHandler = ListJsonTypeHandler.class,javaType = JsonObj.class)
})
List<Json> select1();
// 增加
@Insert("insert into json( mapJson, objJson, listJson) values (#{mapJson,typeHandler=com.hb.springredis.typeHandler.JsonTypeHandler}," +
"#{objJson,typeHandler=com.hb.springredis.typeHandler.JsonTypeHandler}," +
"#{listJson,typeHandler=com.hb.springredis.typeHandler.JsonTypeHandler})")
int insert1(Json vo);
@SpringBootTest
public class ProductTest {
//这个就是刚才放sql的mapper
@Autowired
JsonMapper jsonMapper;
@Test
void test11() throws JsonProcessingException {
JsonObj js = JsonObj.builder().str("这真的是一个简单的测试对象").build();
Map<String,Object> map = new HashMap<>();
map.put("gaga","乱杀");
List<JsonObj> jsonObjs = new ArrayList<>();
for (int i = 0; i < 10; i++) {
JsonObj js0 = JsonObj.builder().id(i).str("这真的是一个简单的测试对象").build();
jsonObjs.add(js0);
}
Json build = Json.builder().mapJson(map).listJson(jsonObjs).objJson(js).build();
jsonMapper.insert1(build);
}
@Test
void test12(){
List<Json> select = jsonMapper.select1();
System.out.println(select);
}
}
因为在java在编译的时候是泛型擦除的,所以对于,List里面的类型无法确定,于是便可以把数据类型存入数据库之中,并且不需要再指出java类型
实体类还和上面一样,只需调整mapper中,对应的typeHandler即可
@Select(" SELECT * from json ")
@Results(value = {
@Result(property = "id", column = "id"),
@Result(property = "mapJson", column = "mapJson", typeHandler = JsonTypeHandler2.class),
@Result(property = "objJson", column = "objJson", typeHandler = JsonTypeHandler2.class),
@Result(property = "listJson", column = "listJson", typeHandler = JsonTypeHandler2.class)
})
List<Json> select();
@Insert("insert into json( mapJson, objJson, listJson) values (#{mapJson,typeHandler=com.hb.springredis.typeHandler.JsonTypeHandler2}," +
"#{objJson,typeHandler=com.hb.springredis.typeHandler.JsonTypeHandler2}," +
"#{listJson,typeHandler=com.hb.springredis.typeHandler.JsonTypeHandler2})")
int insert(Json vo);
public class ListJsonTypeHandler<T> extends BaseTypeHandler<List<T>>{
private Class<T> clazz;
public ListJsonTypeHandler(Class<T> clazz) {
this.clazz = clazz;
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, List<T> parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, JSONUtil.toJsonStr(parameter));
}
@Override
public List<T> getNullableResult(ResultSet rs, String columnName) throws SQLException {
String data = rs.getString(columnName);
return StrUtil.isBlank(data) ? null : JSONUtil.parseArray(data).toList(clazz);
}
@SneakyThrows
@Override
public List<T> getNullableResult(ResultSet rs, int colIndex) {
String data = rs.getString(colIndex);
return StrUtil.isBlank(data) ? null : JSONUtil.parseArray(data).toList(clazz);
}
@SneakyThrows
@Override
public List<T> getNullableResult(CallableStatement cs, int i) {
String data = cs.getString(i);
return StrUtil.isBlank(data) ? null : JSONUtil.parseArray(data).toList(clazz);
}
}
测试类,和上面基本类似
@Test
void test() throws JsonProcessingException {
JsonObj js = JsonObj.builder().str("这真的是一个简单的测试对象").build();
Map<String,Object> map = new HashMap<>();
map.put("gaga","乱杀");
List<JsonObj> jsonObjs = new ArrayList<>();
for (int i = 0; i < 10; i++) {
JsonObj js0 = JsonObj.builder().id(i).str("这真的是一个简单的测试对象").build();
jsonObjs.add(js0);
}
Json build = Json.builder().mapJson(map).listJson(jsonObjs).objJson(js).build();
jsonMapper.insert(build);
}
@Test
void test1(){
List<Json> select = jsonMapper.select();
System.out.println(select);
}