delphi枚举类型值的问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了delphi枚举类型值的问题相关的知识,希望对你有一定的参考价值。
代码如下type MyEnum=(meval1,meval2,meval3=0);vare:MyEnumbegine:=meval1;writeln(ord(e)); //显示0e:=meval3;writeln(ord(e)); //显示0writeln(ord(low(e))): //显示0writeln(ord(high(e))): //显示1readln;end在writeln(ord(low(e))): 的时候,输出的是0,但是在writeln(ord(high(e))): 的时候,显示的为什么是1?这个枚举类型的三种取值meval1,meval2,meval3,序号难道不都是0么?
参考技术A test.dpr.18: e:=meval1;0040A179 33DB xor ebx,ebx
test.dpr.20: writeln(ord(e)); //显示0
0040A17B 0FB6D3 movzx edx,bl
0040A17E A14CBC4000 mov eax,[$0040bc4c]
0040A183 E88098FFFF call @Write0Long
0040A188 E8A798FFFF call @WriteLn
0040A18D E8828FFFFF call @_IOTest
test.dpr.22: e:=meval3;
0040A192 33DB xor ebx,ebx
test.dpr.24: writeln(ord(e)); //显示0
0040A194 0FB6D3 movzx edx,bl
0040A197 A14CBC4000 mov eax,[$0040bc4c]
0040A19C E86798FFFF call @Write0Long
0040A1A1 E88E98FFFF call @WriteLn
0040A1A6 E8698FFFFF call @_IOTest
test.dpr.26: writeln(ord(low(e))); //显示0
0040A1AB A14CBC4000 mov eax,[$0040bc4c]
0040A1B0 33D2 xor edx,edx
0040A1B2 E85198FFFF call @Write0Long
0040A1B7 E87898FFFF call @WriteLn
0040A1BC E8538FFFFF call @_IOTest
test.dpr.28: writeln(ord(high(e))); //显示1
0040A1C1 A14CBC4000 mov eax,[$0040bc4c]
0040A1C6 BA01000000 mov edx,$00000001
0040A1CB E83898FFFF call @Write0Long
0040A1D0 E85F98FFFF call @WriteLn
这是对应的汇编代码, low(e), high(e)都是直接赋值0, 1的
用typehandler优雅的解决枚举类型的读写
问题
- 当数据库表字段是枚举类型的码值的时候,往往要根据字段注释找对应的业务值。随着业务的发展,产生了新的码值,而数据库表的注释往往不会跟着变。新的码值的业务含义就很难知道了。
- 对应的DO类的字段亦是如此。有了新的码值,字段的注释一般跟不上。
解决办法
表字段是码值的时候,一般会有一个枚举(enum)类对应。我们可以把DO类的对应字段定义为枚举类型,用mybatis的typehandler来处理读写。
这样做之后,就只需要维护枚举类型,数据库字段和DO类的注释都不需要了。最好的注释就是对应的枚举类。
通过枚举类强管控码值的变化,就不会随着时间的推移,代码的可读性和可维护性大大降低了。
具体做法
1 枚举字段类型定义, 我们的目标是直接把这个类型入库,并正确的读取出来。
public enum TerminalEnum
HTTP("http", "http接口"),
DUBBO("dubbo", "dubbo接口"),
WEB("web", "网页"),
;
TerminalEnum(String t, String n)
this.type = t;
this.name = n;
@Override
public String toString()
return this.name;
@Getter
private String type;
@Getter
private String name;
public static TerminalEnum getEnumByType(String type)
TerminalEnum[] values = TerminalEnum.values();
for (TerminalEnum terminalEnum : values)
if (StringUtils.equalsIgnoreCase(type, terminalEnum.type))
return terminalEnum;
return null;
2 typehandler定义, 需要继承 org.apache.ibatis.type.BaseTypeHandler
读写的逻辑
- 写的时候取枚举的type字段
- 读的时候根据type字段转成枚举类型
public class TerminalEnumHandler extends BaseTypeHandler<TerminalEnum>
@Override
public void setNonNullParameter(PreparedStatement ps, int i, TerminalEnum terminalEnum, JdbcType jdbcType) throws SQLException
if (terminalEnum == null)
return;
// 入库的时候取枚举的type字段
ps.setString(i, terminalEnum.getType());
@Override
public TerminalEnum getNullableResult(ResultSet rs, String columnName) throws SQLException
String type = rs.getString(columnName);
if (StringUtils.isBlank(type))
return null;
else
// 读的时候根据type字段转成枚举类型
return TerminalEnum.getEnumByType(type);
@Override
public TerminalEnum getNullableResult(ResultSet rs, int columnIndex) throws SQLException
String type = rs.getString(columnIndex);
if (StringUtils.isBlank(type))
return null;
else
return TerminalEnum.getEnumByType(type);
@Override
public TerminalEnum getNullableResult(CallableStatement cs, int columnIndex) throws SQLException
String type = cs.getString(columnIndex);
if (StringUtils.isBlank(type))
return null;
else
return TerminalEnum.getEnumByType(type);
3 我的应用不需要手动注册这个typehandler
4 resultMap对应的字段加上typehandler
<resultMap id="BaseResultMap" type="com.***.***DO" >
... ...
<result column="terminal" property="terminal" typeHandler="com.***.typehandler.TerminalEnumHandler"/>
</resultMap>
5 insert或者update的时候需要在字段后面带上typehandler
<update id="updateTerminal" >
UPDATE ***_token
SET
terminal=#terminal, typeHandler=com.***.typehandler.TerminalEnumHandler
WHERE id=#id
</update>
以上是关于delphi枚举类型值的问题的主要内容,如果未能解决你的问题,请参考以下文章