MyBatis注解之一对多关联实战 一 领域模型1 Clazzpackage org.fkit.domain; import java.io.Serializable; import java.util.List; public class Clazz implements Serializable { private static final long serialVersionUID 1L; private Integer id; // 班级id主键 private String code; // 班级编号 private String name; // 班级名称 // 班级和学生是一对多的关系即一个班级可以有多个学生 private ListStudent students; public Clazz() { super(); // TODO Auto-generated constructor stub } public Integer getId() { return id; } public void setId(Integer id) { this.id id; } public String getCode() { return code; } public void setCode(String code) { this.code code; } public String getName() { return name; } public void setName(String name) { this.name name; } public ListStudent getStudents() { return students; } public void setStudents(ListStudent students) { this.students students; } Override public String toString() { return Clazz [id id , code code , name name ]; } }2 Studentpackage org.fkit.domain; import java.io.Serializable; /** * CREATE TABLE tb_clazz( id INT PRIMARY KEY AUTO_INCREMENT, CODE VARCHAR(18), NAME VARCHAR(18) ); INSERT INTO tb_clazz(CODE,NAME) VALUES(j1601,Java就业班); CREATE TABLE tb_student( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(18), sex VARCHAR(18), age INT, clazz_id INT, FOREIGN KEY (clazz_id) REFERENCES tb_clazz(id) ); INSERT INTO tb_student(NAME,sex,age,clazz_id) VALUES(jack,男,23,1); INSERT INTO tb_student(NAME,sex,age,clazz_id) VALUES(rose,女,18,1); INSERT INTO tb_student(NAME,sex,age,clazz_id) VALUES(tom,男,21,1); INSERT INTO tb_student(NAME,sex,age,clazz_id) VALUES(alice,女,20,1); * */ public class Student implements Serializable { private static final long serialVersionUID 1L; private Integer id; // 学生id主键 private String name; // 姓名 private String sex; // 性别 private Integer age; // 年龄 // 学生和班级是多对一的关系即一个学生只属于一个班级 private Clazz clazz; public Student() { super(); // TODO Auto-generated constructor stub } public Integer getId() { return id; } public void setId(Integer id) { this.id id; } public String getName() { return name; } public void setName(String name) { this.name name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex sex; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age age; } public Clazz getClazz() { return clazz; } public void setClazz(Clazz clazz) { this.clazz clazz; } Override public String toString() { return Student [id id , name name , sex sex , age age ]; } }二 会话工厂package org.fkit.factory; import java.io.InputStream; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; public class FKSqlSessionFactory { private static SqlSessionFactory sqlSessionFactory null; // 初始化创建SqlSessionFactory对象 static{ try (// 读取mybatis-config.xml文件 InputStream is Resources.getResourceAsStream(mybatis-config.xml); ){ sqlSessionFactory new SqlSessionFactoryBuilder() .build(is); } catch (Exception e) { e.printStackTrace(); } } // 获取SqlSession对象的静态方法 public static SqlSession getSqlSession(){ return sqlSessionFactory.openSession(); } // 获取SqlSessionFactory的静态方法 public static SqlSessionFactory getSqlSessionFactory() { return sqlSessionFactory; } }三 mapper1 ClazzMapperpackage org.fkit.mapper; import org.apache.ibatis.annotations.Many; import org.apache.ibatis.annotations.Result; import org.apache.ibatis.annotations.Results; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.mapping.FetchType; import org.fkit.domain.Clazz; public interface ClazzMapper { // 根据id查询班级信息 Select(SELECT * FROM TB_CLAZZ WHERE ID #{id}) Results({ Result(idtrue,columnid,propertyid), Result(columncode,propertycode), Result(columnname,propertyname), Result(columnid,propertystudents, manyMany( selectorg.fkit.mapper.StudentMapper.selectByClazzId, fetchTypeFetchType.LAZY)) }) Clazz selectById(Integer id); }2 StudentMapperpackage org.fkit.mapper; import java.util.List; import org.apache.ibatis.annotations.Result; import org.apache.ibatis.annotations.Results; import org.apache.ibatis.annotations.Select; import org.fkit.domain.Student; public interface StudentMapper { // 根据班级id查询班级所有学生 Select(SELECT * FROM TB_STUDENT WHERE CLAZZ_ID #{id}) Results({ Result(idtrue,columnid,propertyid), Result(columnname,propertyname), Result(columnsex,propertysex), Result(columnage,propertyage) }) ListStudent selectByClazzId(Integer clazz_id); }四 配置文件1 db.propertiesdrivercom.mysql.jdbc.Driver urljdbc:mysql://127.0.0.1:3306/mybatis usernameroot password1234562 log4j.xml?xml version1.0 encodingUTF-8? !DOCTYPE log4j:configuration SYSTEM log4j.dtd log4j:configuration xmlns:log4jhttp://jakarta.apache.org/log4j/ appender nameSTDOUT classorg.apache.log4j.ConsoleAppender layout classorg.apache.log4j.PatternLayout param nameConversionPattern value%5p [%t] %m%n / /layout /appender logger nameorg.fkit.mapper level valueDEBUG / /logger root level valueERROR / appender-ref refSTDOUT / /root /log4j:configuration3 mybatis-config.xml?xml version1.0 encodingUTF-8 ? !DOCTYPE configuration PUBLIC -//mybatis.org//DTD Config 3.0//EN http://mybatis.org/dtd/mybatis-3-config.dtd !-- XML 配置文件包含对 MyBatis 系统的核心设置 -- configuration properties resourcedb.properties/ !-- 指定 MyBatis 所用日志的具体实现 -- settings setting namelogImpl valueLOG4J/ !-- 要使延迟加载生效必须配置下面两个属性 -- setting namelazyLoadingEnabled valuetrue/ setting nameaggressiveLazyLoading valuefalse/ /settings environments defaultmysql !-- 环境配置即连接的数据库。 -- environment idmysql !-- 指定事务管理类型typeJDBC指直接简单使用了JDBC的提交和回滚设置 -- transactionManager typeJDBC/ !-- dataSource指数据源配置POOLED是JDBC连接对象的数据源连接池的实现。 -- dataSource typePOOLED property namedriver value${driver}/ property nameurl value${url}/ property nameusername value${username}/ property namepassword value${password}/ /dataSource /environment /environments !-- mappers告诉了MyBatis去哪里找持久化类的映射文件 -- mappers mapper classorg.fkit.mapper.ClazzMapper/ mapper classorg.fkit.mapper.StudentMapper/ /mappers /configuration五 测试package org.fkit.test; import org.apache.ibatis.session.SqlSession; import org.fkit.domain.Clazz; import org.fkit.factory.FKSqlSessionFactory; import org.fkit.mapper.ClazzMapper; public class OneToManyTest { public static void main(String[] args) { // 定义SqlSession变量 SqlSession sqlSession null; try { // 创建SqlSession实例 sqlSession FKSqlSessionFactory.getSqlSession(); // 获取ClazzMapper实例 ClazzMapper cm sqlSession.getMapper(ClazzMapper.class); // 根据id查询Clazz对象 Clazz clazz cm.selectById(1); // 查看查询到的Clazz对象 System.out.println(clazz.getId() clazz.getCode() clazz.getName()); // 查看关联的学生集合因为配置使用的是LAZY懒加载所以当使用时才执行SQL语句 clazz.getStudents().forEach(student-System.out.println(student)); // 提交事务 sqlSession.commit(); } catch (Exception e) { // 回滚事务 sqlSession.rollback(); e.printStackTrace(); }finally { // 关闭SqlSession if(sqlSession ! null) sqlSession.close(); } } }测试结果DEBUG [main] Preparing: SELECT * FROM TB_CLAZZ WHERE ID ? DEBUG [main] Parameters: 1(Integer) DEBUG [main] Total: 1 1 j1601 Java就业班 DEBUG [main] Preparing: SELECT * FROM TB_STUDENT WHERE CLAZZ_ID ? DEBUG [main] Parameters: 1(Integer) DEBUG [main] Total: 4 Student [id1, namejack, sex男, age23] Student [id2, namerose, sex女, age18] Student [id3, nametom, sex男, age21] Student [id4, namealice, sex女, age20]