运行时机制重写descrption实现实体模型数据打印查看

本文介绍了一种在Objective-C中自定义打印实体模型的方法,通过扩展NSObject类来实现对实体模型属性的详细打印,便于开发者在调试过程中查看实体的具体状态。

使用前打印实体模型时,结果是这样的

(lldb) po self.userModel
<SXLoginModel: 0x7fb08bc36aa0>

使用后打印实体模型时,结果是这样的

(lldb) po [self.userModel descriptionShow]

deptName : 南京校区;
lastSigninTime : 2018-07-13 16:16:56;
roleList : (
    "<SXRoleModel: 0x600000284060>"
);
sex : 2;
source : 1;
state : 1;
xiaoNengId : liuluqing;
zuoXiId : ;
(lldb) po [self.userModel.roleList.firstObject descriptionShow]

descn : (null);
roleId : 2e34ff21224541d;
roleName : 中端军团长;
state : 1;

代码实现

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface NSObject (SYCategory)

/// 实体模型属性打印
- (NSString *)descriptionShow;

@end

#import "NSObject+SYCategory.h"
#import <objc/runtime.h>

@implementation NSObject (SYCategory)

/// 实体模型属性打印
- (NSString *)descriptionShow
{
    NSString *message = @"\n";
    unsigned int outCount;
    objc_property_t *properties = class_copyPropertyList([self class], &outCount);
    for (int i = 0; i < outCount; i ++)
    {
        objc_property_t property = properties[i];
        const char *propName = property_getName(property);
        if (propName)
        {
            NSString *key = [NSString stringWithCString:propName encoding:[NSString defaultCStringEncoding]];
            id value = [self valueForKey:key];
            message = [message stringByAppendingFormat:@"%@ : %@;\n", key, value];
        }
    }
    free(properties);
    return message;
}

@end
### MyBatis 插入 Enum 数据的方法 在 MyBatis 中插入 `Enum` 类型的数据可以通过多种方式进行处理,其中最常用的是使用默认的 `EnumTypeHandler` 或者自定义 `TypeHandler`。 #### 使用默认的 `EnumTypeHandler` 当数据库字段为字符串类型,MyBatis 默认会自动将 Java 的 `Enum` 转换为其名称(即调用 `name()` 方法),并将其存储到数据库中。如果数据库字段是整数类型,则会转换成枚举类型的序号(即调用 `ordinal()` 方法)。这种方式适用于简单的场景[^1]。 ```java public enum Gender { MALE, FEMALE; } ``` 对于上述枚举类,假设有一个名为 `User` 的实体对象: ```java public class User { private Integer id; private String name; private Gender gender; // getters and setters... } ``` 以及相应的表结构如下所示: | Column Name | Type | |-------------|-------------| | id | INT | | name | VARCHAR(50) | | gender | VARCHAR(20) | 此可以编写如下的 Mapper XML 文件来实现插入操作而无需额外配置处理器: ```xml <insert id="insertUser" parameterType="com.example.User"> INSERT INTO users (id, name, gender) VALUES (#{id}, #{name}, #{gender}) </insert> ``` 这里的关键在于 `#{gender}` 这个占位符可以直接接受来自 Java 层面传递过来的 `Gender` 枚举实例,并由 MyBatis 自动完成必要的类型转换工作。 #### 定制化解决方案——创建自定义 `TypeHandler` 然而,在某些情况下,默认行为可能不符合需求;比如想要保存枚举成员的具体描述而非其名字或索引值的候就需要构建一个专门针对特定业务逻辑设计过的 `TypeHandler` 来满足这些特殊的要求了。 下面是一个例子展示了怎样制作这样一个定制化的处理器以便于把性别信息存入数据库的同也能够读取出来: 首先定义一个新的枚举类型带有更详细的说明属性: ```java public enum DetailedGender { MALE("Male"), FEMALE("Female"); private final String description; DetailedGender(String desc){ this.description = desc; } public String getDescription(){ return description; } } ``` 接着我们需要开发一个继承自 `BaseTypeHandler<DetailedGender>` 的新类用于控制如何序列化/反序列化此枚举至数据库列: ```java import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class DetailedGenderTypeHandler extends BaseTypeHandler<DetailedGender> { @Override public void setNonNullParameter(PreparedStatement ps, int i, DetailedGender parameter, JdbcType jdbcType) throws SQLException { ps.setString(i, parameter.getDescription()); } @Override public DetailedGender getNullableResult(ResultSet rs, String columnName) throws SQLException { String descrption = rs.getString(columnName); if (rs.wasNull()) { return null; } else { for(DetailedGender g : DetailedGender.values()){ if(g.getDescription().equals(descrption)){ return g; } } throw new IllegalArgumentException("Unknown detailed gender " + descrption); } } @Override public DetailedGender getNullableResult(ResultSet rs, int columnIndex) throws SQLException { String descrption = rs.getString(columnIndex); if (rs.wasNull()) { return null; } else { for(DetailedGender g : DetailedGender.values()){ if(g.getDescription().equals(descrption)){ return g; } } throw new IllegalArgumentException("Unknown detailed gender " + descrption); } } @Override public DetailedGender getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { String descrption = cs.getString(columnIndex); if (cs.wasNull()) { return null; } else { for(DetailedGender g : DetailedGender.values()){ if(g.getDescription().equals(descrption)){ return g; } } throw new IllegalArgumentException("Unknown detailed gender " + descrption); } } } ``` 最后一步是在 MyBatis 配置文件里注册这个新的 `TypeHandler` 并指定给哪个 SQL 列应用它: ```xml <mappers> <!-- Other mappers --> <typeHandlers> <typeHandler handler="com.yourpackage.DetailedGenderTypeHandler"/> </typeHandlers> ... </mappers> ``` 现在每当涉及到 `DetailedGender` 类型的操作都会按照所设定的方式来进行处理了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

番薯大佬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值