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 4 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 resultMap() default "";
/**
* 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 resultMap() default "";
/**
* 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().resultMap();
if (resultMapId.length() < 1) {
resultMapId = result.many().resultMap();
}
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().resultMap().length() > 0 && result.many().resultMap().length() > 0) {
throw new BuilderException("Cannot use both @One and @Many annotations in the same @Result");
}
return result.one().resultMap().length() > 0 || result.many().resultMap().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', 'teacher');
INSERT INTO role (id,role_name)
VALUES ('2', 'student');
INSERT INTO role (id,role_name)
VALUES ('3', 'Headmaster');
INSERT INTO role (id,role_name)
VALUES ('4', 'Learning-commissary');

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

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO user (id,username)
VALUES ('1', 'James Gosling');
INSERT INTO user (id,username)
VALUES ('2', 'Doug Lea');
INSERT INTO user (id,username)
VALUES ('3', 'Rod johnson');
INSERT INTO user (id,username)
VALUES ('4', 'Juergen Hoeller');

-- ----------------------------
-- 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,77 @@
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 testFindAll() {
try (SqlSession sqlSession = sqlSessionFactory.openSession()){
UserDao mapper = sqlSession.getMapper(UserDao.class);
List<User> users = mapper.findAll();
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 testFindAll2() {
try (SqlSession sqlSession = sqlSessionFactory.openSession()){
UserDao mapper = sqlSession.getMapper(UserDao.class);
List<User> users = mapper.findAll2();
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 testFindAll3() {
try (SqlSession sqlSession = sqlSessionFactory.openSession()){
UserDao mapper = sqlSession.getMapper(UserDao.class);
List<User> users = mapper.findAll3();
Assertions.assertNotNull(users, "users must not be null");
Assertions.assertEquals(2, users.size(), "should return 2 results");
Assertions.assertNotNull(users.get(0).getRole(), "role must not be null");
Assertions.assertEquals("teacher", users.get(0).getRole().getRoleName(), "roleName should be teacher");
}
}


@Test
void testFindHeadmaster() {
try (SqlSession sqlSession = sqlSessionFactory.openSession()){
UserDao mapper = sqlSession.getMapper(UserDao.class);
User headmaster = mapper.findHeadmaster();
Assertions.assertNotNull(headmaster, "users must not be null");
Assertions.assertEquals(3, headmaster.getTeachers().size(), "should return 3 results");
Assertions.assertEquals("Doug Lea", headmaster.getTeachers().get(0).getUsername(), "userName should be lisi");
}
}

}
@@ -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,61 @@
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<User> teachers;
private Role role;
private List<Role> roles;

public Role getRole() {
return role;
}

public void setRole(Role role) {
this.role = role;
}


@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;
}
public List<User> getTeachers() {
return teachers;
}

public void setTeachers(List<User> teachers) {
this.teachers = teachers;
}
}