添加join重载

This commit is contained in:
yulichang 2022-12-07 19:42:20 +08:00
parent 8254727e18
commit 4a1cd1f211
11 changed files with 135 additions and 49 deletions

View File

@ -173,9 +173,6 @@ public class MPJInterceptor implements Interceptor {
Map<String, Field> fieldMap = ReflectionKit.getFieldMap(resultType);
List<Select> columnList = wrapper.getSelectColumns();
//移除对多查询列为了可重复使用wrapper
for (Select s : columnList) {
System.out.println(s);
}
columnList.removeIf(Select::isLabel);
List<ResultMapping> resultMappings = new ArrayList<>();
for (Select i : columnList) {

View File

@ -160,7 +160,7 @@ public class MPJLambdaQueryWrapper<T> extends AbstractLambdaWrapper<T, MPJLambda
@Override
public MPJLambdaQueryWrapper<T> select(Class<T> entityClass, Predicate<TableFieldInfo> predicate) {
TableInfo info = TableInfoHelper.getTableInfo(entityClass);
Assert.notNull(info, "can not find table info");
Assert.notNull(info, "table not find by class <%s>", entityClass.getSimpleName());
selectColumns.addAll(info.getFieldList().stream().filter(predicate).map(c ->
Constant.TABLE_ALIAS + StringPool.DOT + c.getColumn()).collect(Collectors.toList()));
return typedThis;
@ -185,7 +185,7 @@ public class MPJLambdaQueryWrapper<T> extends AbstractLambdaWrapper<T, MPJLambda
@SuppressWarnings("DuplicatedCode")
public final MPJLambdaQueryWrapper<T> selectAll(Class<?> clazz, String as) {
TableInfo info = TableInfoHelper.getTableInfo(clazz);
Assert.notNull(info, "can not find table info");
Assert.notNull(info, "table not find by class <%s>", clazz.getSimpleName());
if (info.havePK()) {
selectColumns.add(as + StringPool.DOT + info.getKeyColumn());
}

View File

@ -135,7 +135,7 @@ public class MPJQueryWrapper<T> extends AbstractWrapper<T, String, MPJQueryWrapp
@Override
public MPJQueryWrapper<T> select(Class<T> entityClass, Predicate<TableFieldInfo> predicate) {
TableInfo info = TableInfoHelper.getTableInfo(entityClass);
Assert.notNull(info, "can not find table info");
Assert.notNull(info, "table not find by class <%s>", entityClass.getSimpleName());
selectColumns.addAll(info.getFieldList().stream().filter(predicate).map(c ->
alias + StringPool.DOT + c.getSqlSelect()).collect(Collectors.toList()));
return typedThis;
@ -160,7 +160,7 @@ public class MPJQueryWrapper<T> extends AbstractWrapper<T, String, MPJQueryWrapp
@SuppressWarnings({"DuplicatedCode", "UnusedReturnValue"})
public final MPJQueryWrapper<T> selectAll(Class<?> clazz, String as) {
TableInfo info = TableInfoHelper.getTableInfo(clazz);
Assert.notNull(info, "can not find table info");
Assert.notNull(info, "table not find by class <%s>", clazz);
if (info.havePK()) {
selectColumns.add(as + StringPool.DOT + info.getKeySqlSelect());
}

View File

@ -3,6 +3,7 @@ package com.github.yulichang.wrapper.interfaces;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.interfaces.MPJBaseJoin;
import com.github.yulichang.toolkit.Constant;
import com.github.yulichang.toolkit.LambdaUtils;
import com.github.yulichang.wrapper.interfaces.on.OnFunction;
/**
@ -22,6 +23,16 @@ public interface LambdaJoin<Children, Entity> extends MPJBaseJoin<Entity> {
return leftJoin(clazz, on -> on.eq(left, right));
}
/**
* left join
*
* @param left 条件
* @param right 条件
*/
default <T, X> Children leftJoin(SFunction<T, ?> left, SFunction<X, ?> right) {
return leftJoin(LambdaUtils.getEntityClass(left), on -> on.eq(left, right));
}
/**
* left join 多条件
* <p>
@ -41,6 +52,13 @@ public interface LambdaJoin<Children, Entity> extends MPJBaseJoin<Entity> {
return rightJoin(clazz, on -> on.eq(left, right));
}
/**
* ignore 参考 left join
*/
default <T, X> Children rightJoin(SFunction<T, ?> left, SFunction<X, ?> right) {
return rightJoin(LambdaUtils.getEntityClass(left), on -> on.eq(left, right));
}
/**
* ignore 参考 left join
*/
@ -55,6 +73,13 @@ public interface LambdaJoin<Children, Entity> extends MPJBaseJoin<Entity> {
return innerJoin(clazz, on -> on.eq(left, right));
}
/**
* ignore 参考 left join
*/
default <T, X> Children innerJoin(SFunction<T, ?> left, SFunction<X, ?> right) {
return innerJoin(LambdaUtils.getEntityClass(left), on -> on.eq(left, right));
}
/**
* ignore 参考 left join
*/
@ -70,6 +95,13 @@ public interface LambdaJoin<Children, Entity> extends MPJBaseJoin<Entity> {
return fullJoin(clazz, on -> on.eq(left, right));
}
/**
* ignore 参考 left join
*/
default <T, X> Children fullJoin(SFunction<T, ?> left, SFunction<X, ?> right) {
return fullJoin(LambdaUtils.getEntityClass(left), on -> on.eq(left, right));
}
/**
* ignore 参考 left join
*/

View File

@ -80,7 +80,7 @@
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>com.github.yulichang</groupId>

View File

@ -7,6 +7,7 @@ import com.github.yulichang.test.collection.dto.TableDDTO;
import com.github.yulichang.test.collection.entity.*;
import com.github.yulichang.test.collection.mapper.TableAMapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@ -26,10 +27,28 @@ import java.util.List;
class CollectionTest {
@Resource
private TableAMapper tableAMapper;
@Resource
private SqlSessionFactory sqlSessionFactory;
/**
* 覆盖测试
*/
@Test
void testJoinCollection() {
//4层嵌套 a对多b b对多c c对多d d对多e
MPJLambdaWrapper<TableA> wrapper1 = new MPJLambdaWrapper<TableA>()
.selectAll(TableA.class)
.selectCollection(TableB.class, TableADTO::getBList, b -> b
.collection(TableC.class, TableBDTO::getCcList, c -> c
.collection(TableD.class, TableCDTO::getDList, d -> d
.collection(TableE.class, TableDDTO::getEList, e -> e
.id(TableE::getId)))))
.leftJoin(TableB.class, TableB::getAid, TableA::getId)
.leftJoin(TableC.class, TableC::getBid, TableB::getId)
.leftJoin(TableD.class, TableD::getCid, TableC::getId)
.leftJoin(TableE.class, TableE::getDid, TableD::getId);
List<TableADTO> dtos1 = tableAMapper.selectJoinList(TableADTO.class, wrapper1);
MPJLambdaWrapper<TableA> wrapper = new MPJLambdaWrapper<TableA>()
.selectAll(TableA.class)
.selectCollection(TableB.class, TableADTO::getBList, b -> b
@ -40,8 +59,8 @@ class CollectionTest {
.leftJoin(TableC.class, TableC::getBid, TableB::getId)
.leftJoin(TableD.class, TableD::getCid, TableC::getId)
.leftJoin(TableE.class, TableE::getDid, TableD::getId);
List<TableADTO> dtos = tableAMapper.selectJoinList(TableADTO.class, wrapper);
System.out.println(dtos);
assert dtos.get(0).getBList().get(0).getCcList().get(0).getDList().get(0).getEList().get(0).getName() != null;
}
}

View File

@ -18,7 +18,9 @@ public class UserDTO {
/** user */
private Integer id;
/** user */
private Map<String,String> name;
private String name;
/** user */
private Map<String,String> json;
/** user */
private Sex sex;
/** user */

View File

@ -11,6 +11,7 @@ import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
@ -26,13 +27,18 @@ public class UserDO {
private Integer pid;
@TableField(value = "`name`", typeHandler = JacksonTypeHandler.class)
private Map<String, String> name;
@TableField("`name`")
private String name;
@TableField(value = "`json`", typeHandler = JacksonTypeHandler.class)
private Map<String, String> json;
private Sex sex;
private String headImg;
private LocalDateTime createTime;
private Integer addressId;
@TableLogic

View File

@ -29,28 +29,28 @@ INSERT INTO area (id, province, city, area, postcode, del) VALUES (10022, '北
DELETE FROM `user`;
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES ( 1, 1, '{"aa":"aaa","bb":"bbb"}', 1, 1, 'https://url-01', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES ( 2, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-02', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES ( 3, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-03', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES ( 4, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-04', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES ( 5, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-05', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES ( 6, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-06', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES ( 7, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-07', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES ( 8, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-08', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES ( 9, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-09', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES (10, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-10', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES (11, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-11', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES (12, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-12', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES (13, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-13', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES (14, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-14', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES (15, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-15', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES (16, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-16', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES (17, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-17', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES (18, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-18', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES (19, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-19', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES (20, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-20', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES (21, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-21', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES (22, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-22', false);
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES ( 1, 1, '张三 1', '{"id": 1,"name":"张三 1"}', 1, 1, 'https://url-01', '2022-01-01 12:00:00', false);
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES ( 2, 1, '张三 2', '{"id": 2,"name":"张三 2"}', 1, 0, 'https://url-02', '2022-01-01 12:00:00', false);
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES ( 3, 1, '张三 3', '{"id": 3,"name":"张三 3"}', 1, 0, 'https://url-03', '2022-01-01 12:00:00', false);
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES ( 4, 1, '张三 4', '{"id": 4,"name":"张三 4"}', 1, 0, 'https://url-04', '2022-01-01 12:00:00', false);
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES ( 5, 1, '张三 5', '{"id": 5,"name":"张三 5"}', 1, 0, 'https://url-05', '2022-01-01 12:00:00', false);
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES ( 6, 1, '张三 6', '{"id": 6,"name":"张三 6"}', 1, 0, 'https://url-06', '2022-01-01 12:00:00', false);
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES ( 7, 1, '张三 7', '{"id": 7,"name":"张三 7"}', 1, 0, 'https://url-07', '2022-01-01 12:00:00', false);
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES ( 8, 1, '张三 8', '{"id": 8,"name":"张三 8"}', 1, 0, 'https://url-08', '2022-01-01 12:00:00', false);
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES ( 9, 1, '张三 9', '{"id": 9,"name":"张三 9"}', 1, 0, 'https://url-09', '2022-01-01 12:00:00', false);
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES (10, 1, '张三10', '{"id":10,"name":"张三10"}', 1, 0, 'https://url-10', '2022-01-01 12:00:00', false);
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES (11, 1, '张三11', '{"id":11,"name":"张三11"}', 1, 0, 'https://url-11', '2022-01-01 12:00:00', false);
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES (12, 1, '张三12', '{"id":12,"name":"张三12"}', 1, 0, 'https://url-12', '2022-01-01 12:00:00', false);
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES (13, 1, '张三13', '{"id":13,"name":"张三13"}', 1, 0, 'https://url-13', '2022-01-01 12:00:00', false);
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES (14, 1, '张三14', '{"id":14,"name":"张三14"}', 1, 0, 'https://url-14', '2022-01-01 12:00:00', false);
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES (15, 1, '张三15', '{"id":15,"name":"张三15"}', 1, 0, 'https://url-15', '2022-01-01 12:00:00', false);
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES (16, 1, '张三16', '{"id":16,"name":"张三16"}', 1, 0, 'https://url-16', '2022-01-01 12:00:00', false);
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES (17, 1, '张三17', '{"id":17,"name":"张三17"}', 1, 0, 'https://url-17', '2022-01-01 12:00:00', false);
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES (18, 1, '张三18', '{"id":18,"name":"张三18"}', 1, 0, 'https://url-18', '2022-01-01 12:00:00', false);
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES (19, 1, '张三19', '{"id":19,"name":"张三19"}', 1, 0, 'https://url-19', '2022-01-01 12:00:00', false);
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES (20, 1, '张三20', '{"id":20,"name":"张三20"}', 1, 0, 'https://url-20', '2022-01-01 12:00:00', false);
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES (21, 1, '张三21', '{"id":21,"name":"张三21"}', 1, 0, 'https://url-21', '2022-01-01 12:00:00', false);
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES (22, 1, '张三22', '{"id":22,"name":"张三22"}', 1, 0, 'https://url-22', '2022-01-01 12:00:00', false);
DELETE FROM address;

View File

@ -23,9 +23,11 @@ create table `user`
primary key,
`pid` int not null,
`name` varchar(255) not null,
`json` varchar(255) not null,
`address_id` int not null,
sex tinyint not null,
head_img varchar(255) not null,
create_time datetime not null,
del bit
);

View File

@ -14,6 +14,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
import java.sql.Timestamp;
import java.util.List;
import java.util.Map;
@ -41,6 +42,23 @@ class LambdaWrapperTest {
.leftJoin(AreaDO.class, AreaDO::getId, AddressDO::getAreaId)
.orderByDesc(UserDO::getId);
List<UserDTO> list = userMapper.selectJoinList(UserDTO.class, wrapper);
assert list.get(0).getAddressList() != null && list.get(0).getAddressList().get(0).getId() != null;
list.forEach(System.out::println);
}
@Test
void testJoin1() {
MPJLambdaWrapper<UserDO> wrapper = new MPJLambdaWrapper<UserDO>()
.selectAll(UserDO.class)
.selectCollection(AddressDO.class, UserDTO::getAddressList, addr -> addr
.association(AreaDO.class, AddressDTO::getArea))
.leftJoin(AddressDO::getUserId, UserDO::getId)
.leftJoin(AreaDO::getId, AddressDO::getAreaId)
.orderByDesc(UserDO::getId);
List<UserDTO> list = userMapper.selectJoinList(UserDTO.class, wrapper);
assert list.get(0).getAddressList().get(0).getId() != null;
list.forEach(System.out::println);
}
@ -49,29 +67,39 @@ class LambdaWrapperTest {
*/
@Test
void testWrapper() {
//基本数据类型 String
MPJLambdaWrapper<UserDO> wrapper = new MPJLambdaWrapper<UserDO>()
.select(UserDO::getId)
.leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId)
.leftJoin(AreaDO.class, AreaDO::getId, AddressDO::getAreaId);
List<Integer> list = userMapper.selectJoinList(Integer.class, wrapper);
assert list.get(0) != null;
System.out.println(list);
//java.sql包下的类
MPJLambdaWrapper<UserDO> wrapper1 = new MPJLambdaWrapper<UserDO>()
.select(UserDO::getCreateTime)
.leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId)
.leftJoin(AreaDO.class, AreaDO::getId, AddressDO::getAreaId);
List<Timestamp> list1 = userMapper.selectJoinList(Timestamp.class, wrapper1);
assert list1.get(0) != null;
System.out.println(list);
}
/**
* ms缓存测试
*/
@Test
void testMSCache() {
MPJLambdaWrapper<UserDO> wrapper = new MPJLambdaWrapper<UserDO>()
.selectAll(UserDO.class)
.leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId)
.leftJoin(AreaDO.class, AreaDO::getId, AddressDO::getAreaId);
List<UserDTO> list = userMapper.selectJoinList(UserDTO.class, wrapper);
// MPJLambdaWrapper<UserDO> wrapper = new MPJLambdaWrapper<UserDO>()
// .selectAll(UserDO.class)
// .leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId)
// .leftJoin(AreaDO.class, AreaDO::getId, AddressDO::getAreaId);
// List<UserDTO> list = userMapper.selectJoinList(UserDTO.class, wrapper);
MPJLambdaWrapper<UserDO> wrapper1 = new MPJLambdaWrapper<UserDO>()
.select(UserDO::getId)
.selectAs(UserDO::getName, UserDTO::getArea)
.selectAs(UserDO::getJson, UserDTO::getArea)
.leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId)
.leftJoin(AreaDO.class, AreaDO::getId, AddressDO::getAreaId);
List<UserDTO> list1 = userMapper.selectJoinList(UserDTO.class, wrapper1);
@ -85,8 +113,8 @@ class LambdaWrapperTest {
@Test
void testInner() {
MPJLambdaWrapper<UserDO> wrapper = new MPJLambdaWrapper<UserDO>()
// .disableSubLogicDel()
// .disableLogicDel()
// .disableSubLogicDel()//关闭副表逻辑删除
// .disableLogicDel()//关闭主表逻辑删除
.selectAll(UserDO.class)
.selectCollection(UserDO.class, UserDO::getChildren)
.leftJoin(UserDO.class, UserDO::getPid, UserDO::getId);
@ -161,11 +189,10 @@ class LambdaWrapperTest {
MPJLambdaWrapper<UserDO> wrapper = new MPJLambdaWrapper<UserDO>()
.selectAll(UserDO.class)
.select(AddressDO.class, p -> true)
// .select(AddressDO::getAddress)
.leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId)
.eq(UserDO::getId, 1);
IPage<UserDTO> page = userMapper.selectJoinPage(new Page<>(1, 10), UserDTO.class,
wrapper);
IPage<UserDTO> page = userMapper.selectJoinPage(new Page<>(1, 10), UserDTO.class, wrapper);
assert page.getRecords().get(0).getAddress() != null;
page.getRecords().forEach(System.out::println);
}
@ -179,6 +206,7 @@ class LambdaWrapperTest {
.selectAll(UserDO.class)
.select(AddressDO::getAddress)
.leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId));
assert list.get(0).get("ADDRESS") != null;
list.forEach(System.out::println);
}
}