• 56-MyBatis关联映射之一对多映射


    转载自:MyBatis学习(六)MyBatis关联映射之一对多映射

    他写的真详细!!!

    数据库中一对多通常使用主外键关联,外键应该在多方,即多方维护关系。

    补充:如果映射时存在多个参数时:

    <collection property="answers" column="id=id,userid=userId" fetchType="lazy"
    javaType="ArrayList" ofType="Answer"
    select="findAnsByQidAndUserid">

    	<!-- 根据问题id和用户id找到单个答案(v_paper_answer) -->
    	<select id="findAnsByQidAndUserid" resultType="PaperAns2">
    		select * 
    		from v_paper_answer v
    		where 1=1 and v.questionId = #{id} and v.userId = #{userid}
    		<!-- where 1=1 and v.questionId = #{id} and v.userId = #{userid} -->
    	</select>
    	<!--  查询 paper + ques + ans(为ans链表) -->
    	<select id="findAnswerList" resultMap="paperQuesAns2ResultMap">
    		SELECT
    			q.id,
    			q.paperid,
    			p.title,	
    			p.createTime,
    			p.createUserId,
    			p.description,
    			p.status,
    			p.level,
    			q.id as quesId,
    			q.qid,
    			q.content,
    			q.ismust,
    			q.type,
    			q.min_num,
    			q.max_num,
    			a.userId
    		FROM
    			db_paper p, db_question2 q  
    			left join db_answer a on a.questionId = q.id  
    		WHERE
    			q.paperId = #{id} and p.id = q.paperId and a.userId = #{userId}
    		AND (
    			 content IS NOT NULL ) order by (qid+0)
    	</select>
    	<resultMap type="PaperQuesAns2" id="paperQuesAns2ResultMap">
            <id property="id" column="id"/>
            <result property="paperId" column="paperId"/>
            <result property="title" column="title"/>
            <result property="createTime" column="createTime"/>
            <result property="createUserId" column="createUserId"/>
            <result property="description" column="description"/>
            <result property="status" column="status"/>
            <result property="level" column="level"/>
            <result property="quesId" column="quesId"/>
            <result property="qid" column="qid"/>
            <result property="content" column="content"/>
            <!-- <result property="remark" column="remark"/> -->
            <!-- <result property="num" column="num"/> -->
            <result property="ismust" column="ismust"/>
            <result property="type" column="type"/>
            <result property="min_num" column="min_num"/>
            <result property="max_num" column="max_num"/>
            <!--property表示返回类型Question2的属性options
                column表示将id作为参数进行之后的查询
                fetchtype表示懒加载
                javaType表示属性对应的类型 
                ofType表示集合当中的类型
            -->
            <!-- 填充选项链表 -->
            <collection property="options" column="id" fetchType="lazy" 
                    javaType="ArrayList" ofType="PaperOption2" 
                    select="findAllOption">
                    <id property="id" column="id"/>
                    <result property="quesid" column="quesid"/>
                    <result property="orderid" column="orderid"/>
                    <result property="content" column="content"/>
                    <result property="remark" column="remark"/>
            </collection>
            <!-- 填充答案链表 -->
            <collection property="answers" column="id=id,userid=userId" fetchType="lazy"
                    javaType="ArrayList" ofType="Answer" 
                    select="findAnsByQidAndUserid">
                    <id property="id" column="id"/>
                    <result property="answer" column="answer"/>
                    <result property="subTime" column="subTime"/>
                    <result property="userId" column="userId"/>
            </collection> 
        </resultMap>
    

      

      

    下面举一个简单实例来看看MyBatis怎么处理一对多的关系。

    1.创建一个项目,导入所需jar包,导入db.properties配置文件,导入log4j.properties配置文件

    2.创建一个数据库,在里面创建两张表

    复制代码
    -- Table structure for `t_clazz`
    -- ----------------------------
    DROP TABLE IF EXISTS `t_clazz`;
    CREATE TABLE `t_clazz` (
      `id` int(11) NOT NULL,
      `code` varchar(18) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of t_clazz
    -- ----------------------------
    INSERT INTO `t_clazz` VALUES ('1', '一班');
    INSERT INTO `t_clazz` VALUES ('2', '二班');
    复制代码
    复制代码
    -- Table structure for `t_student`
    -- ----------------------------
    DROP TABLE IF EXISTS `t_student`;
    CREATE TABLE `t_student` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(18) NOT NULL,
      `sex` varchar(3) NOT NULL,
      `age` int(11) NOT NULL,
      `cid` int(11) NOT NULL,
      PRIMARY KEY (`id`),
      KEY `cid` (`cid`),
      CONSTRAINT `cid` FOREIGN KEY (`cid`) REFERENCES `t_clazz` (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of t_student
    -- ----------------------------
    INSERT INTO `t_student` VALUES ('1', '张三', '男', '11', '1');
    INSERT INTO `t_student` VALUES ('2', '李四', '男', '12', '2');
    INSERT INTO `t_student` VALUES ('3', '小红', '女', '13', '1');
    复制代码

    3.编写对应的实体类

    复制代码
    public class Student {
    
        private Integer id;
        private String name;
        private String sex;
        private Integer age;
        //关联的clazz对象
        private Clazz clazz;
    复制代码
    复制代码
    public class Clazz {
    
        private Integer id;
        private String code;
        //关联的student集合
        private List<Student> students;
    复制代码

    4.编写对应的SQL映射文件

    ClazzMapper.xml

    复制代码
    <?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.dj.mapper.ClazzMapper">
    
        <select id="selectClazzById" parameterType="int" resultMap="clazzResultMap">
            select * from t_clazz where id =#{id}
        </select>
        <resultMap type="com.dj.domain.Clazz" id="clazzResultMap">
            <id property="id" column="id"/>
            <resultproperty="code" column="code"/>
            <!--property表示返回类型Clazz的属性students
                column表示将id作为参数进行之后的查询
                fetchtype表示懒加载
                javaType表示属性对应的类型 
                ofType表示集合当中的类型
            -->
            <collection property="students" column="id" fetchType="lazy" 
                    javaType="ArrayList" ofType="com.dj.domain.Student" 
                    select="com.dj.mapper.StudentMapper.selectStudentByClazzId">
                    <id property="id" column="id"/>
                    <resultproperty="name" column="name"/>
                    <resultproperty="sex" column="sex"/>
                    <resultproperty="age" column="age"/>
                    </collection>
        </resultMap>
        
        
    </mapper>
    复制代码

    StudentMapper.xml

    复制代码
    <?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">
    
    <!-- namespace指用户自定义的命名空间 -->
    <mapper namespace="com.dj.mapper.StudentMapper">
    
        <select id="selectStudentByClazzId" parameterType="int" resultType="com.dj.domain.Student">
            select * from t_student where cid=#{id}
        </select>
    </mapper>
    复制代码

    5.编写mybatis-config.xml文件

    复制代码
    <?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>
         <!-- 引入 外部db.properties文件-->
         <properties resource="db.properties"/>
         <!-- 指定 MyBatis 所用日志的具体实现-->
         <settings>
             <setting name="logImpl" value="log4j"/>
         </settings>
         <!-- 环境配置 -->
         <environments default="mysql">
             <environment id="mysql">
                 <!-- 指定事务类型 -->
                 <transactionManager type="JDBC"/>
                     <!--  dataSource指数据源配置,POOLED是JDBC连接对象的数据源连接池的实现。 -->
                 <dataSource type="POOLED">
                     <property name="driver" value="${driver}"/>
                     <property name="url" value="${url}"/>
                     <property name="username" value="${username}"/>
                     <property name="password" value="${password}"/>
                 </dataSource>
             </environment>
         </environments>
         <!-- SQL映射文件位置 -->
         <mappers>
             <mapper resource="com/dj/mapper/StudentMapper.xml"/>
             <mapper resource="com/dj/mapper/ClazzMapper.xml"/>
         </mappers>
     </configuration>
    复制代码

    6.mybatis建议通过mapper接口的代理对象访问mybatis,该对象关联了一个sqlsession对象,开发者可以通过该对象直接调用方法操作数据库。

    注意: mapper接口对象的类名必须和之前的mapper.xml的namespace一致,方法名和参数名及返回类型也要与mapper.xml的配置一致。

    public interface ClazzMapper {
        //根据id查询班级信息
        Clazz selectClazzById(int id);
        
    }

    7.测试

    复制代码
    public class OneToManyTest {
        
        public static void main(String[] args) throws Exception {
            InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession sqlSession = sqlSessionFactory.openSession();
            //获得mapper接口的代理对象
            ClazzMapper mapper = sqlSession.getMapper(ClazzMapper.class);
            //调用接口中的方法
            Clazz clazz = mapper.selectClazzById(1);
            List<Student> students = clazz.getStudents();
            for (Student student : students) {
                System.out.println(student);
            }
            
        }
    
    }
    复制代码

    在控制台可以看到如下结果:

    测试成功。

  • 相关阅读:
    CF708B
    P4308 [CTSC2011]幸福路径
    P3631 [APIO2011]方格染色
    P1436棋盘分割 记忆化搜索解法
    P2463 [SDOI2008]Sandy的卡片[差分+串拼接后缀数组]
    P2743(poj1743) Musical Themes[差分+后缀数组]
    BZOJ3230 相似子串[后缀数组+二分+st表]
    hdu3518 Boring Counting[后缀排序]
    Robot Framework自动化_Selenium2Library 关键字
    Robot Framework自动化_环境搭建以及第一个用例
  • 原文地址:https://www.cnblogs.com/zhumengdexiaobai/p/11111969.html
Copyright © 2020-2023  润新知