mysql模拟oracle的序列生成器
主要思路:
将表名和表中主键字段组成枚举作为数据源,每次获取该字段在表中的最大数值,加1即是下个主键值.
枚举类
public enum SeqTable {
SYS_ROLE_ID("SYS_ROLE_ID", "system_roles"),
STAFF_ID("STAFF_ID", "staff"),
STAFF_ATTR_ID("STAFF_ATTR_ID", "staff_attr"),
SYS_USER_ID("SYS_USER_ID", "system_user"),
SYS_USER_ATTR_ID("SYS_USER_ATTR_ID", "system_user_attr"),
SYS_USER_ROLE_ID("SYS_USER_ROLE_ID", "system_user_role"),
MSG_ID("MSG_ID", "msg"),
LOGIN_LIMIT_ID("LOGIN_LIMIT_ID", "sysuser_login_limit"),
MENU_ID("MENU_ID","func_menu"),
MENU_ATTR_ID("MENU_ATTR_ID","func_menu_attr"),
ORG_ID("ORG_ID","organization");
private String tableName ;
private String tableId ;
// getter and setter
}
获取序列的方法
@Override
public Long getNextMysql(String seqName) throws Exception {
//获取到table
Map<String, String> map = new HashMap<String, String>();
map.put("tableId", seqName);
map.put("tableName", getTableNameById(seqName));
//查询该table中该主键的最大值
Long a = systemRolesMapper.selectMaxId(map);
return a+1;
}
sql语句
<select id="selectMaxId" parameterType="java.util.Map" resultType="java.lang.Long">
select ifnull(max(${tableId}),0) FROM ${tableName}
</select>
消息报文的生成和记录
当执行DML语句时,需要在数据库中记录下当前消费报文的内容(json),该方法必须要满足各种实体类,以及集合对象.还要根据不同的操作类型记录.一开始采用Object作为实体类的父类,但是后来加入循环节点,所以只能用List<Object>类型.
操作组件
@Component
public class CommonOperate {
@Autowired
private IMessageProductService messageProduct;
public void BeanToJsonConvertAndSendMsg(Map<String, List<Object>> transMap, String flag) {
StringBuilder json = new StringBuilder();
json.append("{");
json.append("\"ROOT\": {");
json.append("\"HEADER\": \"\",");
json.append("\"BODY\": {");
Iterator<Map.Entry<String, List<Object>>> it = transMap.entrySet().iterator();
JsonConfig config = new JsonConfig();
DateToJsonTransfer jsonValueProcessor = new DateToJsonTransfer();
config.registerJsonValueProcessor(Date.class, jsonValueProcessor);
while (it.hasNext()) {
Map.Entry<String, List<Object>> entry = it.next();
List<Object> array = entry.getValue();
// 组成数组[{},{}]
if(array.size() > 1){
for (int i = 0; i < array.size(); i++) {
String paramData = transToJson(JSONObject.fromObject(array.get(i), config).toString());
if(i == 0){
json.append("\"" + entry.getKey() + "\":[" + paramData + "");
}else if(i == array.size() - 1){
json.append("," + paramData + "]");
}else{
json.append("," + paramData);
}
}
}
// 组成单个元素{}
if(array.size() == 1){
String paramData = transToJson(JSONObject.fromObject(array.get(0), config).toString());
json.append("\"" + entry.getKey() + "\":" + paramData + "");
}
// 如果不是最后一个元素字符串末尾添加逗号
if(it.hasNext() && array.size() != 0){
json.append(",");
}
}
json.append("}");
json.append("}}");
// 记录到数据库
messageProduct.sendMsg(json.toString(), flag);
}
/**
* json中字符串进行驼峰字段替换为数据库字段类型
*/
private String transToJson(String json) {
JSONObject object = JSONObject.fromObject(json);
Iterator<String> iterator = object.keys();
while (iterator.hasNext()) {
String a = (String) iterator.next();
String key = propertyToField(a);
json = json.replaceAll(a, key);
}
return json;
}
/**
* 驼峰类型字段转为数据库字段(如:myName 转为MY_NAME)
*/
public static String propertyToField(String property) {
if (null == property) {
return "";
}
char[] chars = property.toCharArray();
StringBuffer sb = new StringBuffer();
for (char c : chars) {
if (CharUtils.isAsciiAlphaUpper(c)) {
sb.append("_" + CharUtils.toString(c).toLowerCase());
} else {
sb.append(c);
}
}
return sb.toString().toUpperCase();
}
}
添加消息对象
List<Object> object = new ArrayList<Object>();
Map<String, List<Object>> map = new HashMap<String, List<Object>>();
....
object.add(sysUser);
map.put("LOGIN_BASE_INFO", object);
// 清空集合
object = new ArrayList<Object>();
for(** * :###){
object.add(*);
}
map.put("LOGIN_ROLE_INFO", object);
HiJson
介绍一个好用的json转换工具:HiJson,可以格式化长且不好看的json串,还可以轻松找到节点,非常好用.
- 转换前:
{"ROOT": {"HEADER": "","BODY": {"LOGIN_ROLE_INFO":[{"OP_TYPE":"D","SYSTEM_INFO_ID":"8140000","SYS_ROLE_CODE":"0102"},{"OP_TYPE":"D","SYSTEM_INFO_ID":"8140000","SYS_ROLE_CODE":"010101"}],"LOGIN_BASE_INFO":{"STATUS_DATE":"","UPDATE_DATE":"2017-10-18 13:25:59","SYS_USER_TYPE_VALUE":"","OP_TYPE":"M","SYS_USER_DESC":"工号描述","MULT_LOGIN_FLAG":"","EXP_DATE":"2017-10-31 16:43:20","ORG_ID":1,"SYS_USER_ALIAS":"","EFF_DATE":"2017-10-01 16:43:17","PASSWORD":"123qwe111","STAFF_NAME":"和东方红的","PWD_NEWTIME":"","SYS_USER_ID":1,"SYSTEM_INFO_ID_VALUE":"","CREATE_DATE":"","PWD_ERR_CNT":10,"SYS_USER_CODE":"sitech-0921","LIMIT_COUNT":10,"PWD_EFFECT_DAYS":100,"STATUS_CD":"1000","SYSTEM_INFO_ID":1000,"CREATE_STAFF":0,"PWD_STATUS":"1000","REGION_ID":8140000,"STATUS_CDValue":"","PWD_STATUSValue":"","SYS_USER_TYPE":"","LOGINED_NUM":0,"PWD_SMS_TEL":13145678432,"STAFF_ID":1,"UPDATE_STAFF":0}}}}
- 转换后:
{
"ROOT": {
"BODY": {
"LOGIN_BASE_INFO": {
"CREATE_DATE": "",
"CREATE_STAFF": 0,
"EFF_DATE": "2017-10-01 16:43:17",
"EXP_DATE": "2017-10-31 16:43:20",
"LIMIT_COUNT": 10,
"LOGINED_NUM": 0,
"MULT_LOGIN_FLAG": "",
"OP_TYPE": "M",
"ORG_ID": 1,
"PASSWORD": "123qwe111",
"PWD_EFFECT_DAYS": 100,
"PWD_ERR_CNT": 10,
"PWD_NEWTIME": "",
"PWD_SMS_TEL": 13145678432,
"PWD_STATUS": "1000",
"PWD_STATUSValue": "",
"REGION_ID": 8140000,
"STAFF_ID": 1,
"STAFF_NAME": "dddd",
"STATUS_CD": "1000",
"STATUS_CDValue": "",
"STATUS_DATE": "",
"SYSTEM_INFO_ID": 1000,
"SYSTEM_INFO_ID_VALUE": "",
"SYS_USER_ALIAS": "",
"SYS_USER_CODE": "kkk-0921",
"SYS_USER_DESC": "工号描述",
"SYS_USER_ID": 1,
"SYS_USER_TYPE": "",
"SYS_USER_TYPE_VALUE": "",
"UPDATE_DATE": "2017-10-18 13:25:59",
"UPDATE_STAFF": 0
},
"LOGIN_ROLE_INFO": [
{
"OP_TYPE": "D",
"SYSTEM_INFO_ID": "8140000",
"SYS_ROLE_CODE": "0102"
},
{
"OP_TYPE": "D",
"SYSTEM_INFO_ID": "8140000",
"SYS_ROLE_CODE": "010101"
}
]
},
"HEADER": ""
}
}
是不是清晰了很多,也便于调试.