Mybatis Plus 如何通过lambda获取属性名的

沁海棠 2019-05-23 05:53:18
        
QueryWrapper<Goods> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(Goods::getGoodsId,"123");

QueryWrapper<Goods> wrapper1 = new QueryWrapper<>();
wrapper1.eq("goods_id","123");


看不明白, 怎么实现这样拿到属性名的.

不要沉
...全文
509 点赞 收藏 12
写回复
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
正好这两天在研究这个问题 顺便写了个总结: https://blog.csdn.net/li281037846/article/details/116401948
回复
沁海棠 2019-06-05
引用 9 楼 PtCJIT 的回复:
直接上Demo
//这就是MybatisPlus底层的实现,我只是把它单独拿出来了
public class MybatisPlusApplicationTests {

    @Test
    public void test() {
        //SerializedLambda对象为MybatisPlus中的一个类可以自行查看
        SerializedLambda serializedLambda = getSerializedLambda(Banner::getBannerName);
        System.out.println(serializedLambda.getImplMethodName());  //输出结果为:getBannerName,再做的个简单的字符串截取即可获得bannerName属性名
    }

    public static SerializedLambda getSerializedLambda(SFunction<Banner, ?> lambda) {
        SerializedLambda serializedLambda = null;
        try {
            ObjectInputStream objIn = new ObjectInputStream(new ByteArrayInputStream(serialize(lambda))) {
                protected Class<?> resolveClass(ObjectStreamClass objectStreamClass) throws IOException, ClassNotFoundException {
                    Class<?> clazz = super.resolveClass(objectStreamClass);
                    return clazz == java.lang.invoke.SerializedLambda.class ? SerializedLambda.class : clazz;
                }
            };
            serializedLambda  = (SerializedLambda) objIn.readObject();
        } catch (Exception x) {
        }
        return serializedLambda;
    }

    public static byte[] serialize(Object object) {
        if (object == null) {
            return null;
        } else {
            ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
            try {
                ObjectOutputStream oos = new ObjectOutputStream(baos);
                oos.writeObject(object);
                oos.flush();
            } catch (IOException var3) {
                throw new IllegalArgumentException("Failed to serialize object of type: " + object.getClass(), var3);
            }

            return baos.toByteArray();
        }
    }
}
尴尬贴已经结了。。。。
回复
沁海棠 2019-06-05
引用 9 楼 PtCJIT 的回复:
直接上Demo
//这就是MybatisPlus底层的实现,我只是把它单独拿出来了
public class MybatisPlusApplicationTests {

    @Test
    public void test() {
        //SerializedLambda对象为MybatisPlus中的一个类可以自行查看
        SerializedLambda serializedLambda = getSerializedLambda(Banner::getBannerName);
        System.out.println(serializedLambda.getImplMethodName());  //输出结果为:getBannerName,再做的个简单的字符串截取即可获得bannerName属性名
    }

    public static SerializedLambda getSerializedLambda(SFunction<Banner, ?> lambda) {
        SerializedLambda serializedLambda = null;
        try {
            ObjectInputStream objIn = new ObjectInputStream(new ByteArrayInputStream(serialize(lambda))) {
                protected Class<?> resolveClass(ObjectStreamClass objectStreamClass) throws IOException, ClassNotFoundException {
                    Class<?> clazz = super.resolveClass(objectStreamClass);
                    return clazz == java.lang.invoke.SerializedLambda.class ? SerializedLambda.class : clazz;
                }
            };
            serializedLambda  = (SerializedLambda) objIn.readObject();
        } catch (Exception x) {
        }
        return serializedLambda;
    }

    public static byte[] serialize(Object object) {
        if (object == null) {
            return null;
        } else {
            ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
            try {
                ObjectOutputStream oos = new ObjectOutputStream(baos);
                oos.writeObject(object);
                oos.flush();
            } catch (IOException var3) {
                throw new IllegalArgumentException("Failed to serialize object of type: " + object.getClass(), var3);
            }

            return baos.toByteArray();
        }
    }
}
七楼评论以后,我也翻到了他的源码忘结贴了,谢了一人给你们100分吧。
回复
PtCJIT 2019-06-05
直接上Demo
//这就是MybatisPlus底层的实现,我只是把它单独拿出来了
public class MybatisPlusApplicationTests {

    @Test
    public void test() {
        //SerializedLambda对象为MybatisPlus中的一个类可以自行查看
        SerializedLambda serializedLambda = getSerializedLambda(Banner::getBannerName);
        System.out.println(serializedLambda.getImplMethodName());  //输出结果为:getBannerName,再做的个简单的字符串截取即可获得bannerName属性名
    }

    public static SerializedLambda getSerializedLambda(SFunction<Banner, ?> lambda) {
        SerializedLambda serializedLambda = null;
        try {
            ObjectInputStream objIn = new ObjectInputStream(new ByteArrayInputStream(serialize(lambda))) {
                protected Class<?> resolveClass(ObjectStreamClass objectStreamClass) throws IOException, ClassNotFoundException {
                    Class<?> clazz = super.resolveClass(objectStreamClass);
                    return clazz == java.lang.invoke.SerializedLambda.class ? SerializedLambda.class : clazz;
                }
            };
            serializedLambda  = (SerializedLambda) objIn.readObject();
        } catch (Exception x) {
        }
        return serializedLambda;
    }

    public static byte[] serialize(Object object) {
        if (object == null) {
            return null;
        } else {
            ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
            try {
                ObjectOutputStream oos = new ObjectOutputStream(baos);
                oos.writeObject(object);
                oos.flush();
            } catch (IOException var3) {
                throw new IllegalArgumentException("Failed to serialize object of type: " + object.getClass(), var3);
            }

            return baos.toByteArray();
        }
    }
}
回复
PtCJIT 2019-06-05
//这就是MybatisPlus底层的实现,我只是把它单独拿出来了 public class MybatisPlusApplicationTests { @Test public void test() { //SerializedLambda对象为MybatisPlus中的一个类可以自行查看 SerializedLambda serializedLambda = getSerializedLambda(Banner::getBannerName); //Banner为任意对象,getBannerName为
对象方法 System.out.println(serializedLambda.getImplMethodName()); //输出结果为:getBannerName,再做的个简单的字符串截取即可获得bannerName属性名 } public static SerializedLambda getSerializedLambda(SFunction<Banner, ?> lambda) { SerializedLambda serializedLambda = null; try { ObjectInputStream objIn = new ObjectInputStream(new ByteArrayInputStream(serialize(lambda))) { protected Class<?> resolveClass(ObjectStreamClass objectStreamClass) throws IOException, ClassNotFoundException { Class<?> clazz = super.resolveClass(objectStreamClass); return clazz == java.lang.invoke.SerializedLambda.class ? SerializedLambda.class : clazz; } }; serializedLambda = (SerializedLambda) objIn.readObject(); } catch (Exception x) { } return serializedLambda; } public static byte[] serialize(Object object) { if (object == null) { return null; } else { ByteArrayOutputStream baos = new ByteArrayOutputStream(1024); try { ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(object); oos.flush(); } catch (IOException var3) { throw new IllegalArgumentException("Failed to serialize object of type: " + object.getClass(), var3); } return baos.toByteArray(); } } }
[code=java]
[/code]
回复
我写个demo有难度啊。。 下面是它的源码,QueryWrapper使用Lambda表达式主要引用的类是LambdaQueryWrapper,它继承的AbstractLambdaWrapper类有个方法是getColumn:

    private String getColumn(SerializedLambda lambda) {
        String fieldName = StringUtils.resolveFieldName(lambda.getImplMethodName());
        if (!this.initColumnMap || this.columnMap.get(fieldName) == null) {
            String entityClassName = lambda.getImplClass().replace("/", ".");
            this.columnMap = LambdaUtils.getColumnMap(entityClassName);
            Assert.notEmpty(this.columnMap, "该模式不能应用于非 baseMapper 的泛型 entity 之外的 entity!");
            this.initColumnMap = true;
        }

        return (String)Optional.ofNullable(this.columnMap.get(fieldName)).orElseThrow(() -> {
            return ExceptionUtils.mpe("该模式不能应用于非数据库字段!");
        });
    }
// StringUtils的resolveFieldName方法实现
    public static String resolveFieldName(String getMethodName) {
        if (getMethodName.startsWith("get")) {
            getMethodName = getMethodName.substring(3);// 把get截取掉
        } else if (getMethodName.startsWith("is")) {
            getMethodName = getMethodName.substring(2);
        }

        return firstToLowerCase(getMethodName);// 首字母转为小写 GoodsId ->goodsId
    }
最后得到的fieldName 就是属性名
回复
沁海棠 2019-05-28
引用 5 楼 对梦想的牵挂 的回复:
[quote=引用 4 楼 青海棠 的回复:] [quote=引用 3 楼 对梦想的牵挂 的回复:] 双冒号运算符就是java中的方法引用,方法引用的格式是类名::方法名。Lambda有所谓的懒加载 例如: 表达式: Goods->Goods.getGoodsId (); 可以替换为 Goods::getGoodsId
如果我想通过传入一个方法引用 (get方法)得到属性名 怎么实现?[/quote] 这个直接截取方法引用的字符串不就得到属性名了么[/quote] 能写个demo么? 方法接收 类::方法引用 拿到名字
回复
引用 4 楼 青海棠 的回复:
[quote=引用 3 楼 对梦想的牵挂 的回复:] 双冒号运算符就是java中的方法引用,方法引用的格式是类名::方法名。Lambda有所谓的懒加载 例如: 表达式: Goods->Goods.getGoodsId (); 可以替换为 Goods::getGoodsId
如果我想通过传入一个方法引用 (get方法)得到属性名 怎么实现?[/quote] 这个直接截取方法引用的字符串不就得到属性名了么
回复
沁海棠 2019-05-25
引用 3 楼 对梦想的牵挂 的回复:
双冒号运算符就是java中的方法引用,方法引用的格式是类名::方法名。Lambda有所谓的懒加载 例如: 表达式: Goods->Goods.getGoodsId (); 可以替换为 Goods::getGoodsId
如果我想通过传入一个方法引用 (get方法)得到属性名 怎么实现?
回复
双冒号运算符就是java中的方法引用,方法引用的格式是类名::方法名。Lambda有所谓的懒加载 例如: 表达式: Goods->Goods.getGoodsId (); 可以替换为 Goods::getGoodsId
回复
沁海棠 2019-05-23
引用 楼主 青海棠 的回复:
        
QueryWrapper<Goods> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(Goods::getGoodsId,"123");

QueryWrapper<Goods> wrapper1 = new QueryWrapper<>();
wrapper1.eq("goods_id","123");
看不明白, 怎么实现这样拿到属性名的. 不要沉
这我知道 我想知道的是 通过Goods::getGoodsId 怎么拿到属性名的
回复
萧~X 2019-05-23
首先第一个lambda().eq是一个查询语句,再是看eq的内容 Goods::getGoodsId,“123”Goods代表的商品类,::后面的是属性goodId,“”里的是查询条件,也就是在商品表中查询goodId为123的商品信息 ,下面的那个eq应该和第一个是一样的结果
回复
发动态
发帖子
Java EE
创建于2007-09-28

6.6w+

社区成员

J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
申请成为版主
社区公告
暂无公告