为何不把POJO字段类型定义成String

最近项目后台整体使用ICE提供服务,返回JSON数据给前台

整体架构大致如下:

1.Controller 接受客户端请求

2.使用IceClient调用iceservice

3.iceservice调用数据库层


有趣的是,在controller和dao层定义了两个业务对象,一个是ice数据对象,另一个是dao层众所周知的java pojo对象,ice service层使用cglib来回拷贝,请注意注释部分

            session = SqlSessionFactoryUtil.getSqlSessionFactory().openSession();
            BaseDataDAO dao = session.getMapper(BaseDataDAO.class);
            ProvincePOJO provincePOJO = new ProvincePOJO();
            BeanCopierUtil.copy(province, provincePOJO);//拷贝参数
            List<ProvincePOJO> provinces = dao.getProvince(provincePOJO);
            List<Province> _provinces = new ArrayList<Province>(provinces.size());
            for (int i = 0; i < provinces.size(); i++) {
                ProvincePOJO _provincePOJO = provinces.get(i);
                Province _province = new Province();
                BeanCopierUtil.copy(_provincePOJO, _province);//拷贝返回值
                _provinces.add(i, _province);
            }
            return _provinces;


cglib拷贝工具

public class BeanCopierUtil {

    public static void copy(Object source, Object target) {
        BeanCopier bc = BeanCopier.create(source.getClass(), target.getClass(), false);
        bc.copy(source, target, null);
    }

    public static void copy(Object source, Object target, Converter converter) {
        BeanCopier bc = BeanCopier.create(source.getClass(), target.getClass(), true);
        bc.copy(source, target, converter);
    }
}
数据对象如下

public class ProvincePOJO {

    private Integer provinceID;

    private String provinceName;

    private Integer areaId;

    private Integer countryId;

    private Date dateCreate;
}
["java:getset"]
    struct Province{
       int provinceID;
       string provinceName;
       int areaId;
       int countryId;
       string dateCreate;
    };
    

ice为支持多语言,只提供基本数据类型,而Interger,Date是Java类型的!问题来了,我们知道,大名鼎鼎的cglib拷贝工具BeanCopier只会对同类型的的数据做拷贝,int->int  ok!   int->Ingeter  no!    这种情况迫使我们不得不加上一个转换器

public static Converter getDefaultConverter() {
        return converter = new Converter() {
            @SuppressWarnings("rawtypes")
            @Override
            public Object convert(Object arg0, Class arg1, Object arg2) {
                return arg0;//直接返回
            }
        };
}
//加上转换器
BeanCopierUtil.copy(province, provincePOJO,BeanCopierUtil.getDefaultConverter());//拷贝参数
BeanCopierUtil.copy(_provincePOJO, _province,BeanCopierUtil.getDefaultConverter());//拷贝返回值

至此,我以为万事大吉了 int ->integer no problem!,我只想说,呵呵! tooyoung, too simple, sometimes naïve!

Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Date
	at org.springframework.cglib.empty.Object$$BeanCopierByCGLIB$$a26519e4.copy(
	at com.huilian.hlej.loan.utils.BeanCopierUtil.copy(BeanCopierUtil.java:23)
	at com.huilian.hlej.loan.utils.BeanCopierUtil.main(BeanCopierUtil.java:64)
字符串转日期失败!!好吧

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                if ("setDateCreate".equals(arg2)) {// date<->string
                    if ("java.util.Date".equals(typeName)) {
                        try {
                            return sdf.parse((String) arg0);
                        }
                        catch (ParseException e) {
                        }
                        return null;
                    }
                    
                }
日期转字符串失败!!

Exception in thread "main" java.lang.ClassCastException: java.util.Date cannot be cast to java.lang.String
	at org.springframework.cglib.empty.Object$$BeanCopierByCGLIB$$e3dd8d28.copy
	at com.huilian.hlej.loan.utils.BeanCopierUtil.copy(BeanCopierUtil.java:23)
	at com.huilian.hlej.loan.utils.BeanCopierUtil.main(BeanCopierUtil.java:77)

                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                if ("setDateCreate".equals(arg2)) {// date<->string
                    if ("java.util.Date".equals(typeName)) {
                        try {
                            return sdf.parse((String) arg0);
                        }
                        catch (ParseException e) {
                        }
                        return null;
                    }
                    return sdf.format(arg0);//加上日期转字符串代码
                }


后来业务需求不断调整,加入了多个日期字段,大字段java.math.BigDecimal,不断地修改转换器代码,另外接受前台的非法参数,如何不经过严格判断,直接系统错误,这简直就是噩梦!!


JAVA POJO类字段类型为何一定要定义数据表字段相应的类型?

接口本身的功能是从数据库查询到前台JSON,反过来从前台JSON保存到数据库

JS和SQL语言本身是弱类型,为何在中间强制加上强类型?

架构师给出的答案:性能问题,我大概只能呵呵了


实际上,mybatis已经很好完成类型转换的工作,不管数据库定义什么类型,都能映射到JAVA String字段

反过来,即使将一个非法的int类型传递到数据库(where t.loan_status > '123d'),数据库也能正常的工作,而不是直接崩溃 

自己写的转换器,性能就一定好吗,不尽然吧!不管怎样,我还是推荐POJO全部定义成String类型



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值