Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow referencing result map from @One and @Many #1771

Merged
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/main/java/org/apache/ibatis/annotations/Many.java
Expand Up @@ -33,6 +33,12 @@
@Retention(RetentionPolicy.RUNTIME)
@Target({})
public @interface Many {
/**
* Returns the id that retrieves result map.
*
* @return the id that retrieves result map.
*/
String resultMapId() default "";
moonService marked this conversation as resolved.
Show resolved Hide resolved
/**
* Returns the statement id that retrieves collection.
*
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/org/apache/ibatis/annotations/One.java
Expand Up @@ -33,6 +33,12 @@
@Retention(RetentionPolicy.RUNTIME)
@Target({})
public @interface One {
/**
* Returns the id that retrieves result map.
*
* @return the id that retrieves result map.
*/
String resultMapId() default "";
moonService marked this conversation as resolved.
Show resolved Hide resolved
/**
* Returns the statement id that retrieves single object.
*
Expand Down
Expand Up @@ -552,7 +552,7 @@ private void applyResults(Result[] results, Class<?> resultType, List<ResultMapp
result.javaType() == void.class ? null : result.javaType(),
result.jdbcType() == JdbcType.UNDEFINED ? null : result.jdbcType(),
hasNestedSelect(result) ? nestedSelectId(result) : null,
null,
hasNestedResultMap(result) ? nestedResultMapId(result) : null,
null,
null,
typeHandler,
Expand All @@ -564,6 +564,24 @@ private void applyResults(Result[] results, Class<?> resultType, List<ResultMapp
}
}

private String nestedResultMapId(Result result) {
String resultMapId = result.one().resultMapId();
if (resultMapId.length() < 1) {
resultMapId = result.many().resultMapId();
}
if (!resultMapId.contains(".")) {
resultMapId = type.getName() + "." + resultMapId;
moonService marked this conversation as resolved.
Show resolved Hide resolved
}
return resultMapId;
}

private boolean hasNestedResultMap(Result result) {
if (result.one().resultMapId().length() > 0 && result.many().resultMapId().length() > 0) {
throw new BuilderException("Cannot use both @One and @Many annotations in the same @Result");
}
return result.one().resultMapId().length() > 0 || result.many().resultMapId().length() > 0;
}

private String nestedSelectId(Result result) {
String nestedSelect = result.one().select();
if (nestedSelect.length() < 1) {
Expand Down
@@ -0,0 +1,61 @@
-- ----------------------------
-- Table structure for role
-- ----------------------------
CREATE TABLE role (
id int,
role_name varchar(10)
);

-- ----------------------------
-- Records of role
-- ----------------------------
INSERT INTO role (id,role_name)
VALUES ('1', '老师');
INSERT INTO role (id,role_name)
VALUES ('2', '学生');
INSERT INTO role (id,role_name)
VALUES ('3', '班主任');
INSERT INTO role (id,role_name)
VALUES ('4', '学习委员');

CREATE TABLE user (
id int,
username varchar(32),
);

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO user (id,username)
VALUES ('1', '赵六');
INSERT INTO user (id,username)
VALUES ('2', '李四');
INSERT INTO user (id,username)
VALUES ('3', '毛六');
INSERT INTO user (id,username)
VALUES ('4', '王五');
moonService marked this conversation as resolved.
Show resolved Hide resolved

-- ----------------------------
-- Table structure for `user_role`
-- ----------------------------
CREATE TABLE user_role (
id int,
role_id int,
user_id int
);

-- ----------------------------
-- Records of user_role
-- ----------------------------
INSERT INTO user_role (id,role_id,user_id)
VALUES ('1', '2', '4');
INSERT INTO user_role (id,role_id,user_id)
VALUES ('2', '3', '1');
INSERT INTO user_role (id,role_id,user_id)
VALUES ('3', '1', '2');
INSERT INTO user_role (id,role_id,user_id)
VALUES ('4', '2', '3');
INSERT INTO user_role (id,role_id,user_id)
VALUES ('5', '4', '4');
INSERT INTO user_role (id,role_id,user_id)
VALUES ('6', '1', '1');
@@ -0,0 +1,65 @@
package org.apache.ibatis.submitted.annotion_many_one_add_resultmapid;

import org.apache.ibatis.BaseDataTest;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import java.io.Reader;
import java.util.List;

class MyBatisTest {

private static SqlSessionFactory sqlSessionFactory;

@BeforeAll
static void setUp() throws Exception {
// create an SqlSessionFactory
try (Reader reader = Resources.getResourceAsReader("org/apache/ibatis/submitted/annotion_many_one_add_resultmapid/SqlMapConfig.xml")) {
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
}

// populate in-memory database
BaseDataTest.runScript(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(),
"org/apache/ibatis/submitted/annotion_many_one_add_resultmapid/CreateDB.sql");
}

@Test
void test() {
try (SqlSession sqlSession = sqlSessionFactory.openSession()){
UserDao mapper = sqlSession.getMapper(UserDao.class);
List<User> users = mapper.flindAll();
Assertions.assertNotNull(users, "users must not be null");
Assertions.assertEquals(4, users.size(), "should return 4 results");
Assertions.assertEquals(2, users.get(0).getRoles().size(), "should have 2 roles");
}
}

@Test
void test2() {
try (SqlSession sqlSession = sqlSessionFactory.openSession()){
UserDao mapper = sqlSession.getMapper(UserDao.class);
List<User> users = mapper.flindAll2();
Assertions.assertNotNull(users, "users must not be null");
Assertions.assertEquals(4, users.size(), "should return 4 results");
Assertions.assertEquals(2, users.get(0).getRoles().size(), "should have 2 roles");
}
}

@Test
void test3() {
try (SqlSession sqlSession = sqlSessionFactory.openSession()){
UserDao mapper = sqlSession.getMapper(UserDao.class);
List<User> users = mapper.flindAll3();
Assertions.assertNotNull(users, "users must not be null");
Assertions.assertEquals(2, users.size(), "should return 2 results");
Assertions.assertEquals(1, users.get(0).getRoles().size(), "should have 1 roles");
Assertions.assertEquals("老师", users.get(0).getRoles().get(0).getRoleName(), "should have 1 roles");
}
}

}
@@ -0,0 +1,31 @@
package org.apache.ibatis.submitted.annotion_many_one_add_resultmapid;

public class Role {
private Integer id; //int

@Override
public String toString() {
return "Role{" +
"id=" + id +
", roleName='" + roleName + '\'' +
'}';
}

private String roleName;//varchar

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getRoleName() {
return roleName;
}

public void setRoleName(String roleName) {
this.roleName = roleName;
}
}
@@ -0,0 +1,30 @@
/**
* Copyright (c) 2019 ucsmy.com, All rights reserved.
*/
moonService marked this conversation as resolved.
Show resolved Hide resolved
package org.apache.ibatis.submitted.annotion_many_one_add_resultmapid;

import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;

import java.util.List;

/**
* @Description:
* @Author: lvyang
* @Created Date: 2019年12月10日
* @LastModifyDate:
* @LastModifyBy:
* @Version:
*/
public interface RoleDao {
@Select("select * from role")
@Results(
id="roleMap1",
value = {
@Result(id = true,column="role_id",property = "id"),
@Result(column="role_name",property = "roleName")
}
)
public List<Role> findAll();
}
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.apache.ibatis.submitted.annotion_many_one_add_resultmapid.RoleDao">
<resultMap id="roleMap2" type="org.apache.ibatis.submitted.annotion_many_one_add_resultmapid.Role">
<id column="role_id" property="id"/>
<result column="role_name" property="roleName" />
</resultMap>
</mapper>
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="UNPOOLED">
<property name="driver" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:mem:annotion_many_one_add_resultmapid" />
<property name="username" value="sa" />
</dataSource>
</environment>
</environments>

<mappers>
<mapper class="org.apache.ibatis.submitted.annotion_many_one_add_resultmapid.RoleDao"/>
<mapper class="org.apache.ibatis.submitted.annotion_many_one_add_resultmapid.UserDao"/>
</mappers>
</configuration>
@@ -0,0 +1,43 @@
package org.apache.ibatis.submitted.annotion_many_one_add_resultmapid;


import java.util.List;

public class User {
private Integer id; //int
private String username; //varchar
private List<Role> roles;

@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", roles=" + roles +
'}';
}

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public List<Role> getRoles() {
return roles;
}

public void setRoles(List<Role> roles) {
this.roles = roles;
}
}
@@ -0,0 +1,54 @@
/**
* Copyright (c) 2019 ucsmy.com, All rights reserved.
*/
moonService marked this conversation as resolved.
Show resolved Hide resolved
package org.apache.ibatis.submitted.annotion_many_one_add_resultmapid;

import org.apache.ibatis.annotations.*;

import java.util.List;

/**
* @Description:
* @Author: lvyang
* @Created Date: 2019年12月10日
* @LastModifyDate:
* @LastModifyBy:
* @Version:
*/
public interface UserDao {
@Select("select\n" +
" u.id,u.username,r.id role_id,r.role_name\n" +
" from user u\n" +
" left join user_role ur on u.id =ur.user_id\n" +
" left join role r on ur.role_id = r.id")
@Results({
@Result(id = true,column="id",property = "id"),
@Result(column="username",property = "username"),
@Result(property = "roles",many = @Many(resultMapId = "org.apache.ibatis.submitted.annotion_many_one_add_resultmapid.RoleDao.roleMap1"))
})
public List<User> flindAll();

@Select("select\n" +
" u.id,u.username,r.id role_id,r.role_name\n" +
" from user u\n" +
" left join user_role ur on u.id =ur.user_id\n" +
" left join role r on ur.role_id = r.id")
@Results({
@Result(id = true,column="id",property = "id"),
@Result(column="username",property = "username"),
@Result(property = "roles",many = @Many(resultMapId = "org.apache.ibatis.submitted.annotion_many_one_add_resultmapid.RoleDao.roleMap2"))
})
public List<User> flindAll2();

@Select("select\n" +
" u.id,u.username,r.id role_id,r.role_name\n" +
" from user u\n" +
" left join user_role ur on u.id =ur.user_id\n" +
" left join role r on ur.role_id = r.id where u.id in (2,3)")
@Results({
@Result(id = true,column="id",property = "id"),
@Result(column="username",property = "username"),
@Result(property = "roles",one = @One(resultMapId = "org.apache.ibatis.submitted.annotion_many_one_add_resultmapid.RoleDao.roleMap2"))
moonService marked this conversation as resolved.
Show resolved Hide resolved
})
public List<User> flindAll3();
}