One-to-many relationship processing in Mybatis basic learning

Keywords: Java MySQL Mybatis IDEA

Preface:

Hello, ladies and gentlemen, I'm running like a snail rz. Of course you can call me Snail Jun. I'm a beginner who has studied Java for more than half a year. At the same time, I have a great dream that I will become an excellent Java architect one day.

This Mybatis Basic Learning series is used to record the whole process of my learning the fundamentals of the Mybatis framework (this series was written with reference to the latest Mybatis tutorial from Station B. Since it was sorted out before, but it was not published at that time, there may be errors in some places, I hope you can correct them in time!)

After that, I will try to update this series as soon as possible in two days, and those who have not yet learned the Mybatis3 framework can refer to my blog to learn it. Of course, the little buddy who has studied can also review the basics with me by the way. Finally, I hope I can make progress with you! Come on! Boys!

Special Reminder: If you are interested in the Mybatis Basic Learning Series, you can read this series of future blogs:
First: The Beginning of Mybatis Basic Learning Mybatis
Article 2: The first Mybatis program for basic Mybatis learning
Article 3: CRUD Addition and Deletion Check for Mybatis Basic Learning
Article 4: Map and Fuzzy Query for Mybatis Basic Learning
Article 5: Configuration Analysis of Mybatis Basic Learning (Previous)
Article 6: Configuration Analysis of Mybatis Basic Learning (Next)
Article 7: Mybatis Basic Learning uses ResultMap to resolve field name inconsistencies
Article 8: Simple use of the Mybatis Basic Learning Log Factory
Article 9: Simple use of data paging for basic Mybatis learning
Article 10: Development of Use Notes for Mybatis Basic Learning
Article 11: Simple use of Lombok for Mybatis Basic Learning
Article 12: Mybatis Basic Learning Many-to-One Relationship Processing

Today we come to the twelfth station of basic Mybatis learning: one-to-many relationship processing. Say nothing more. Let's start today's learning.

12. One-to-many relationship processing

  • What is one-to-many relationship processing?

For example, a teacher has more than one student. For a teacher, this is a one-to-many relationship!

12.1 Build Basic Environment

12.1.1 Write entity and tool classes

1. Write Student entity classes

package com.kuang.pojo;
@Data // Introduce parameterless construction, get, set, toString, etc.
@AllArgsConstructor // Introducing a parametric construction method
@NoArgsConstructor // Introduce parameterless construction method again to prevent overwriting by parameterized construction
public class Student {
    private int id;
    private String name;
    private int tid;
}

2. Write Teacher entity classes

package com.kuang.pojo;

@Data // Introduce parameterless construction, get, set, toString, etc.
@AllArgsConstructor // Introducing a parametric construction method
@NoArgsConstructor // Introduce parameterless construction method again to prevent overwriting by parameterized construction

public class Teacher {
    
    private int id; // Teacher number
    private String name; // Teacher Name
    // A teacher has more than one student and uses the List collection, which is generic to Student, to achieve one-to-many
    private List<Student> students;
    
}

3. Write the MybatisUtils tool class

package com.kuang.utils;

/** 
 * SqlSessionFactoryBuilder(Build factories)
 * --> sqlSessionFactory(Production sqlSession)
 * --> sqlSession  
 */
public class MybatisUtils {
    
    // Get Static SQL Session Factory
    private static SqlSessionFactory sqlSessionFactory;
    // Static Method Body
    static {
        try {
            // Read Configuration File
            String resource = "mybatis-config.xml";
            // Parse Profile Stream
            InputStream inputStream = Resources.getResourceAsStream(resource);
            // Get Factory
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
   /**
    * SqlSession Provides all the methods required to execute SQL commands in a database
    */
   public static SqlSession getSqlSession() {
       // Set parameter to true for automatic submission
       return sqlSessionFactory.openSession(true);
   }
    
}

12.1.2 Write Mapper interfaces and their mapping files

1. Write the StudentMapper interface and its mapping file

1-1 Write StudentMapper interface
package com.kuang.dao;

public interface StudentMapper {
    
}
1-2 Write StudentMapper.xml mapping file
  • Create a com.kuang.dao package in the resources file directory

  • Create and write a StudentMapper.xml file

<?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="com.kuang.dao.StudentMapper">
    
</mapper>

2. Write the TeacherMapper interface and its mapping file

1-1 Write the TeacherMapper interface
package com.kuang.dao;

public interface TeacherMapper {
    
    // Get all the teacher information
    List<Teacher> getTeacher();
}
1-2 Write StudentMapper interface profile
  • Write a TeacherMapper.xml mapping file in the com.kuang.dao package created under the resources source file
<?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="com.kuang.dao.TeacherMapper">
    
    <!-- Query all teacher information -->
    <select id="getTeacher" resultType="Teacher">
        Select * from mybatis.teacher
    </select>
    
</mapper>

12.1.3 Create Write Core Profile

1. Write db.properties configuration file

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8
username=root
pwd=123456

2. Write mybatis-config.xml file

Register mapper interface using class file binding

<?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: Core Profile -->
<configuration>
    
    <!-- Introducing external profiles, Prefer external profiles -->
    <properties resource="db.properties"/>
    
    <!-- Set Standard Log Output -->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
    
    <!-- By aliasing the package -->
    <typeAliases>
        <package name="com.kuang.pojo"/>
    </typeAliases>
    
    <!-- Set default environment as development environment -->
    <environments default="development">
        <!-- Set up an environment for development -->
        <environment id="development">
            <!-- transactionManager: Represents a transaction manager, and MyBatis The default manager for is JDBC-->
            <transactionManager type="JDBC"/>
            <!-- dataSource: Represents a data source, Main role: Connect to database, MyBatis The default data source type is POOLED,This is a pooled connection -->
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${pwd}"/>
            </dataSource>
        </environment>
    </environments>
    
    <!-- Binding interface: using class File Binding Registration -->
    <mappers>
        <mapper class="com.kuang.dao.TeacherMapper"/>
        <mapper class="com.kuang.dao.StudentMapper"/>
    </mappers>
    
</configuration>

12.1.4 Create write test classes

1. Write test class code

package com.kuang.dao;

public class MyTest {
    
    @Test
    public void getTeacher() {
        // Get sqlSession object
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        // Getting the TeacherMapper interface (essentially through reflection)
        TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
        // Get Queried Teacher Information Collection
        List<Teacher> teachers = mapper.getTeacher();
        // Traversing a collection of teacher information using a foreach loop
        for (Teacher teacher : teachers) {
            // Print Teacher Information
            System.out.println(teacher);
        }
        // The following is an abbreviation of the above lines of code, but this is not recommended
/*        
for (Teacher teacher : sqlSession.getMapper(TeacherMapper.class).getTeacher()) {
            System.out.println(teacher);
        }
        */
        // Close sqlSession object
        sqlSession.close();
    }
    
}

2. Test results

Result: Successfully queried all the teachers'information! But the student information is null!

12.2 Perfect basic environment and set up test

12.2.1 Create Writing Entity Classes and Tool Classes

  • Same as 12.1.1

12.2.2 Create a Mapper interface and configuration file

1. Write StudentMapper interface and configuration file

  • Same as writing the StudentMapper interface and its mapping file in 12.1.2

2. Write the TeacherMapper interface and configuration file

  • Further modifications to the TeacherMapper interface and its mapping file, written in 12.1.2
2-1 Writing the TeacherMapper interface
package com.kuang.dao;

public interface TeacherMapper {
    
    /**
     * Get information about all students and teachers under a given teacher
     */    
    // Use result nesting
    Teacher getTeacher2(@Param("tid") int id);
    
    // Using query nesting
    Teacher getTeacher3(@Param("tid") int id);
    
}
2-2 Write TeacherMapperx.xml file
1. Nested processing according to results
<?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="com.kuang.dao.TeacherMapper">
    
    <!-- Query all students and teachers under a given teacher -->
    <!-- Nested query by result -->
    <select id="getTeacher2" resultMap="TeacherStudent">
        Select s.id sid,s.name sname,t.id tid,t.name tname
        from student s,teacher t
        where s.tid = t.id and t.id = #{tid}
    </select>
    
    <!-- resultMap Result Set -->
    <resultMap id="TeacherStudent" type="Teacher">
        <result property="id" column="tid"/>
        <result property="name" column="tname"/>
        <!-- Complex attributes that need to be handled separately;
             among association: Represent Object; collection: Represents a collection
             javaType=""Specify the type of attribute; For generic information in a collection, use ofType Obtain-->
        <collection property="students" ofType="Student">
            <result property="id" column="sid"/>
            <result property="name" column="sname"/>
            <result property="tid" column="tid"/>
        </collection>
    </resultMap>

</mapper>
2. Nested Processing by Query
<?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"> 

     <!-- Nested Processing by Query -->
    <select id="getTeacher3" resultMap="TeacherStudent2">
        Select * from mybatis.teacher where id = #{tid}
    </select>

    <!-- Result Set Mapping -->
    <resultMap id="TeacherStudent2" type="Teacher">
        <!-- collection: Represents a collection, where a teacher contains more than one student, a one-to-many relationship;
             property="students": For injection into Teacher Attributes of Entity Classes students;
             javaType="ArrayList": Used to specify attributes students The type of is ArrayList;
             ofType="Student": Generic information in a collection, Use ofType Obtain, The set here is the value List<Student>,So the value is Student
             select="getStudentByTeacherId": Next to execute SQL Sentence, This refers to the following query for all student information for a given teacher, column="id": adopt id Find the corresponding teacher -->
        <collection property="students" javaType="ArrayList" ofType="Student" select="getStudentByTeacherId" column="id"/>
    </resultMap>

    <!-- Query all student information for the assigned teacher -->
    <select id="getStudentByTeacherId" resultType="Student">
        Select * from mybatis.student where tid = #{tid}
    </select>

</mapper>

12.2.3 Create Write Core Profile

  • Same as 12.1.3 core profile

12.2.4 Create write test classes

1. Write test class code

package com.kuang.dao;

public class MyTest {
    
    /**
     * Query all students and teachers under a given teacher
     */
    
    // Use result nesting
    @Test
    public void getTeacher2() {
        // Get SqlSession object
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        // Get Teacher to get Mapper interface
        TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
        // Get information about designated teachers through id
        Teacher teacher = mapper.getTeacher2(1);
        // Print Teacher Information
        System.out.println(teacher);
        // Close sqlSession object
        sqlSession.close();
    }
    
    // Using query nesting
    @Test
    public void getTeache3() {
        sqlSession.close();
        // Get SqlSession object
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        // Get Teacher to get Mapper interface
        TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
        // Get information about designated teachers through id
        Teacher teacher = mapper.getTeacher3(1);
        // Print Teacher Information
        System.out.println(teacher);
        // Close sqlSession object
        sqlSession.close();
    }
    
}

2. Test results

2-1 Nested Processing by Result

Query results:

Teacher(id=1, name=Lv Yanting, students=[Student(id=1, name=Zhao Qianjing, tid=1), Student(id=2, name=Chen Zhangtaikang, tid=1), Student(id=3, name=Hu Liangwei, tid=1), Student(id=4, name=Koi, tid=1), Student(id=5, name=Ma Zhengyang, tid=1)])

Result: Queried information about the teachers and all the students under the assigned teachers!

2-2 Nested Processing by Query

Result: Same as nested processing according to result!

12.3 Summary of many-to-one and one-to-many use

Use of 12.3.1 association

association: association [many-to-one]

Use of 12.3.2 collection

Collection: collection [one-to-many]

The difference between 12.3.3 javaType and ofType

  • The javaType is used to specify the type of attribute in the entity class
  • ofType is used to specify the pojo type mapped to a List or collection, the constraint type in a generic!

12.3.4 Use Notes

  • Keep SQL readable and as easy as possible to understand
  • Notice the problem of attribute names and fields in one-to-many and many-to-one
  • If the problem is not easy to troubleshoot, log can be used and Log4j is recommended

Okay, that's the end of today's learning about one-to-many relationship processing. You are welcome to actively study and discuss with your friends. If you like, you can give Jun Snail a little attention, and by the way, you can do it one click three times. Let's meet next time. Bye!

Reference video link: Mybatis latest complete tutorial IDEA version is easy to understand

Posted by ataylor20 on Fri, 12 Nov 2021 13:55:50 -0800