Mybatis进阶
发布日期:2021-05-07 03:09:23 浏览次数:20 分类:精选文章

本文共 23364 字,大约阅读时间需要 77 分钟。

Mybatis进阶

1.接口代理方式实现Dao层

1.1 接口代理方式-实现规则

传统方式实现Dao层,我们既要写接口,还要写实现类。而MyBatis框架可以帮助我们省略编写Dao层皆苦实现类的步骤。程序员只需要编写接口,有MyBatis框架根据接口的定义来创建该接口的动态代理对象

实现规则:

  1. 映射配置文件中的名称空间必须和Dao层接口的全类名相同
  2. 映射配置文件中的增删改查标签的id属性必须和Dao层接口的方法名相同
  3. 映射配置文件中的增删改查标签的parameterType属性必须和Dao层接口方法的参数相同
  4. 映射配置文件中的增删改查标签的resultType属性必须和Dao层接口方法的返回值相同

1.2 接口代理方式-代码实现

  1. 删除mapper(dao)层接口的实现类
  2. 修改映射配置文件
  3. 修改service层接口的实现类,采用接口代理方式实现功能

修改映射配置文件:名称空间改为全类名

修改service层接口实现类:

/*    业务层实现类 */public class StudentServiceImpl implements StudentService {       @Override    public List
selectAll() { List
list = null; SqlSession sqlSession = null; InputStream is = null; try { //1.加载核心配置文件 is = Resources.getResourceAsStream("MyBatisConfig.xml"); //2.获取SqlSession工厂对象 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); //3.通过工厂对象获取SqlSession对象 sqlSession = sqlSessionFactory.openSession(true); //4.获取StudentMapper接口的实现类对象 StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);//StudentMapper mapper = new StudentMapperImpl(); //5.通过实现类对象调用方法,接收结果 list = mapper.selectAll(); } catch (IOException e) { e.printStackTrace(); }finally { //6.释放资源 if (sqlSession != null) { sqlSession.close(); } if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } //7.返回结果 return list; } @Override public Student selectById(Integer id) { Student student = null; SqlSession sqlSession = null; InputStream is = null; try { //1.加载核心配置文件 is = Resources.getResourceAsStream("MyBatisConfig.xml"); //2.获取SqlSession工厂对象 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); //3.通过工厂对象获取SqlSession对象 sqlSession = sqlSessionFactory.openSession(true); //4.获取StudentMapper接口的实现类对象 StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);//StudentMapper mapper = new StudentMapperImpl(); //5.通过实现类对象调用方法,接收结果 student = mapper.selectById(id); } catch (IOException e) { e.printStackTrace(); }finally { //6.释放资源 if (sqlSession != null) { sqlSession.close(); } if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } //7.返回结果 return student; } @Override public Integer insert(Student student) { Integer result = 0; SqlSession sqlSession = null; InputStream is = null; try { //1.加载核心配置文件 is = Resources.getResourceAsStream("MyBatisConfig.xml"); //2.获取SqlSession工厂对象 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); //3.通过工厂对象获取SqlSession对象 sqlSession = sqlSessionFactory.openSession(true); //4.获取StudentMapper接口的实现类对象 StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);//StudentMapper mapper = new StudentMapperImpl(); //5.通过实现类对象调用方法,接收结果 result = mapper.insert(student); } catch (IOException e) { e.printStackTrace(); }finally { //6.释放资源 if (sqlSession != null) { sqlSession.close(); } if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } //7.返回结果 return result; } @Override public Integer update(Student student) { Integer result = null; SqlSession sqlSession = null; InputStream is = null; try { //1.加载核心配置文件 is = Resources.getResourceAsStream("MyBatisConfig.xml"); //2.获取SqlSession工厂对象 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); //3.通过工厂对象获取SqlSession对象 sqlSession = sqlSessionFactory.openSession(true); //4.获取StudentMapper接口的实现类对象 StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);//StudentMapper mapper = new StudentMapperImpl(); //5.通过实现类对象调用方法,接收结果 result = mapper.update(student); } catch (IOException e) { e.printStackTrace(); }finally { //6.释放资源 if (sqlSession != null) { sqlSession.close(); } if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } //7.返回结果 return result; } @Override public Integer delete(Integer id) { Integer result = null; SqlSession sqlSession = null; InputStream is = null; try { //1.加载核心配置文件 is = Resources.getResourceAsStream("MyBatisConfig.xml"); //2.获取SqlSession工厂对象 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); //3.通过工厂对象获取SqlSession对象 sqlSession = sqlSessionFactory.openSession(true); //4.获取StudentMapper接口的实现类对象 StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);//StudentMapper mapper = new StudentMapperImpl(); //5.通过实现类对象调用方法,接收结果 result = mapper.delete(id); } catch (IOException e) { e.printStackTrace(); }finally { //6.释放资源 if (sqlSession != null) { sqlSession.close(); } if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } //7.返回结果 return result; }}

1.3 接口代理方式实-源码分析

分析动态代理对象如何生成的?

通过动态代理开发模式,我们只编写一个接口,不写实现类,我们通过getMapper()方法最终获取到org.apache.ibatis.binding.MapperProxy代理对象,然后执行功能,而这个代理对象正是MyBatis使用了JDK的动态代理技术,帮助我们生成了代理实现类对象,从而可以进行相关持久化操作。

分析方法是如何执行的?

动态代理实现类对象在执行方法的时候最终调用了mapperMethod.execute()方法,这个方法通过switch语句根据操作类型来判断是新增、修改、删除、查询操作,最后一步回到MyBatis最原生的SqlSession方式来执行增删改查

2.动态sql

2.1 动态sql介绍

MyBatis映射配置文件中,前面我们的sql都是比较简单的,有些时候业务逻辑复杂时,我们的sql就是动态变化的,此时在前面学习的sql就不能满足要求了

多条件查询

id:3 name:王五 age:25

select * from student where id= ?and name = ?and age = ?

id:3 name:王五

select * from student where id= ?and name = ?

动态sql标签

  • <if>:条件判断标签
  • <foreach>:循环遍历标签

2.2 <if>标签

<where>:条件标签。如果有动态条件,则使用该标签代替where关键字

<if>:条件判断标签

查询条件拼接

映射配置文件中标签设置:

测试类中方法:

@Test    public void selectCondition() throws IOException {           InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);        SqlSession sqlSession = sqlSessionFactory.openSession(true);        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);//        Student student = new Student(2,"李四",23);        Student student = new Student(2,"李四",null);        List
list = mapper.selectCondition(student); System.out.println(list); sqlSession.close(); is.close(); }
  1. 当传递参数student = new Student(2,“李四”,null)时,测试结果打印信息:

    DEBUG [main] -==> Preparing: select * from student WHERE id = ? and name = ?

    DEBUG [main] -==> Parameters: 2(Integer), 李四(String)
    DEBUG [main] -<== Total: 1
    [Student{id=2, name=‘李四’, age=23}]

  2. 当传递参数student = new Student(2,“李四”,23)时,测试结果打印信息:

    DEBUG [main] -==> Preparing: select * from student WHERE id = ? and name = ? and age = ?

    DEBUG [main] -==> Parameters: 2(Integer), 李四(String), 23(Integer)
    DEBUG [main] -<== Total: 1
    [Student{id=2, name=‘李四’, age=23}]

2.3 <foreach>标签

<foreach>:循环遍历标签。适用于多个参数或者的关系

获取参数

属性:

  • collection:参数容器类型,list集合,array数组
  • open:开始的sql语句
  • close:结束的sql语句
  • item:参数变量名
  • separator:分隔符

映射配置文件中标签设置:

测试类中方法:

@Testpublic void selectByIds() throws IOException {       InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);    SqlSession sqlSession = sqlSessionFactory.openSession(true);    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);    List
ids = new ArrayList
(); ids.add(1); ids.add(2); //ids.add(3); List
list = mapper.selectByIds(ids); for (Student student : list) { System.out.println(student); } sqlSession.close(); is.close();}

运行测试方法结果:

  1. 当list集合中添加1,2时

    DEBUG [main] -==> Preparing: select * from student WHERE id in ( ? , ? )

    DEBUG [main] -==> Parameters: 1(Integer), 2(Integer)
    DEBUG [main] -<== Total: 2
    Student{id=1, name=‘张三’, age=20}
    Student{id=2, name=‘李四’, age=23}

  2. 当再向集合添加一个3时

    DEBUG [main] -==> Preparing: select * from student WHERE id in ( ? , ? , ? )

    DEBUG [main] -==> Parameters: 1(Integer), 2(Integer), 3(Integer)
    DEBUG [main] -<== Total: 3
    Student{id=1, name=‘张三’, age=20}
    Student{id=2, name=‘李四’, age=23}
    Student{id=3, name=‘王五’, age=18}

2.4 sql片段抽取

我们可以将一些重复性的sql语句进行抽取,以达到复用的效果

<sql>:抽取sql语句标签

  1. <sql id=“片段唯一标识”>抽取的sql语句</sql>

<include>:导入sql片段标签

  1. <include refid = “片段唯一标识” />

sql片段抽取后映射配置文件:

select * from student

3.分页插件

3.1 分页插件介绍

分页的特点:

  • 分页可以将很多条结果进行分页显示

  • 如果当前在第一页,则没有上一页。如果当前在最后一页,则没有下一页

  • 需要明确当前是第几页,这一页中显示多少条结果

分页的实现:

在企业级开发中,分页也是一种常见的技术。而目前使用的MyBatis是不带分页功能的,如果想实现分页功能,需要我们手动编写limit语句。但是,不同数据库实现分页的sql语句也不相同,所以手动编写成本较高。这个时候就可以借助分页插件来帮助我们实现分页功能。

PageHelper:第三方分页助手,将复杂的分页操作进行封装,从而让分页功能变得非常简单

3.2 分页插件实现步骤

  1. 导入jar包

    下载地址:

  2. 在核心配置文件中集成分页助手插件

  3. 在测试类中使用分页助手相关API实现分页功能

    PageHelper.startPage(3,3);//当前页,页面数据量

测试类:

@Test    public void selectPaging() throws IOException {           InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);        SqlSession sqlSession = sqlSessionFactory.openSession(true);        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);        //通过分页助手来实现分页功能        //第一页:显示3条数据//        PageHelper.startPage(1,3);        //第二页:显示3条数据//        PageHelper.startPage(2,3);        //第三页:显示3条数据        PageHelper.startPage(3,3);        List
list = mapper.selectAll(); for (Student student : list) { System.out.println(student); } sqlSession.close(); is.close(); }

3.3 分页插件相关参数

PageInfo:封装分页相关参数的功能类

核心方法:

返回值 方法名 说明
long getTotal() 获取总条数
int getPages() 获取总页数
int getPageNum() 获取当前页
int getPageSize() 获取每页显示条数
int getPrePage() 获取上一页
int getNextPage() 获取下一页
boolean isIsFirstPage() 获取是否是第一页
boolean isIsLastPage() 获取是否是最后一页
@Test    public void selectPaging() throws IOException {           InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);        SqlSession sqlSession = sqlSessionFactory.openSession(true);        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);        //通过分页助手来实现分页功能        //第一页:显示3条数据//        PageHelper.startPage(1,3);        //第二页:显示3条数据//        PageHelper.startPage(2,3);        //第三页:显示3条数据        PageHelper.startPage(3,3);        List
list = mapper.selectAll(); //PageInfo:分页相关参数和功能类 PageInfo
info = new PageInfo
(list); System.out.println("总条数:"+info.getTotal()); System.out.println("总页数:"+info.getPages()); System.out.println("当前页:"+info.getPageNum()); System.out.println("每页条数:"+info.getPageSize()); System.out.println("上一页:"+info.getPrePage()); System.out.println("下一页:"+info.getNextPage()); System.out.println("是否为第一页:"+info.isIsFirstPage()); System.out.println("是否为最后一页:"+info.isIsLastPage()); for (Student student : list) { System.out.println(student); } sqlSession.close(); is.close(); }

4.多表操作

4.1 多表模型

我们之前学习的都是基于单表操作的,而实际开发中,随着业务难度加深,肯定需要多表操作的

多表模型分类:

  • 一对一:在任意一方建立外键,关联对方的主键
  • 一对多:在多的一方建立外键,关联一的一方的主键
  • 多对多:借助中间表,中间表至少两个字段,分别关联两张表的主键

4.2 一对一

一对一模型:人和身份证,一个人只有一个身份证

环境准备

创建数据库、表:

CREATE DATABASE db2USE db2CREATE TABLE person(	id INT PRIMARY KEY AUTO_INCREMENT,	NAME VARCHAR(20),	age INT)ENGINE=INNODB DEFAULT CHARSET=utf8;INSERT INTO person VALUES(NULL,'张三',23);INSERT INTO person VALUES(NULL,'李四',24);INSERT INTO person VALUES(NULL,'王五',25);CREATE TABLE card(	id INT PRIMARY KEY AUTO_INCREMENT,	NUMBER VARCHAR(30),	pid INT,	CONSTRAINT cp_fk FOREIGN KEY (pid) REFERENCES person(id))ENGINE=INNODB DEFAULT CHARSET=utf8;INSERT INTO card VALUES(NULL,'123456',1);INSERT INTO card VALUES(NULL,'223456',2);INSERT INTO card VALUES(NULL,'323456',3);

实体类:Person

package cn.itcast.bean;public class Person {       private Integer id; //主键id    private String name;//人的姓名    private Integer age;//人的年龄    public Person() {       }    public Person(Integer id, String name, Integer age) {           this.id = id;        this.name = name;        this.age = age;    }    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 Integer getAge() {           return age;    }    public void setAge(Integer age) {           this.age = age;    }    @Override    public String toString() {           return "Person{" +                "id=" + id +                ", name='" + name + '\'' +                ", age=" + age +                '}';    }}

实体类:Card

package cn.itcast.bean;public class Card {       private Integer id; //主键id    private String number;//身份证号    private Person p; //所属人的对象    public Card() {       }    public Card(Integer id, String number, Person p) {           this.id = id;        this.number = number;        this.p = p;    }    public Integer getId() {           return id;    }    public void setId(Integer id) {           this.id = id;    }    public String getNumber() {           return number;    }    public void setNumber(String number) {           this.number = number;    }    public Person getP() {           return p;    }    public void setP(Person p) {           this.p = p;    }    @Override    public String toString() {           return "Card{" +                "id=" + id +                ", number='" + number + '\'' +                ", p=" + p +                '}';    }}

核心配置文件:

映射配置文件:

  • <resultMap>:配置字段和对象属性的映射关系标签
    • id属性:唯一标识
    • type属性:实体对象类型
  • <id>:配置主键映射关系标签
  • <result>:配置非主键映射关系标签
    • column属性:表中字段名称
    • property属性:实体对象变量名称
  • <association>:配置被包含对象的映射关系标签
    • property属性:被包含对象的变量名
    • javaType属性:被包含对象的数据类型

测试类:

@Testpublic void selectAll() throws IOException {       //1.加载核心配置文件    InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");    //2.获取SqlSession工厂对象    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);    //3.通过SqlSession工厂对象获取SqlSession对象    SqlSession sqlSession = sqlSessionFactory.openSession();    //4.获取OneToOneMapper接口的实现类对象    OneToOneMapper mapper = sqlSession.getMapper(OneToOneMapper.class);    //5.调用实现类方法,接收结果    List
list = mapper.selectAll(); //6.处理结果 for (Card card : list) { System.out.println(card); } //7.释放资源 sqlSession.close(); is.close();}

测试方法运行结果:

Card{id=1, number=‘123456’, p=Person{id=1, name=‘张三’, age=23}}

Card{id=2, number=‘223456’, p=Person{id=2, name=‘李四’, age=24}}
Card{id=3, number=‘323456’, p=Person{id=3, name=‘王五’, age=25}}

4.3 一对多

一对多模型:班级和学生,一个班级可以有多个学生

环境准备

创建表并添加数据:

CREATE TABLE classes(	id INT PRIMARY KEY AUTO_INCREMENT,	NAME VARCHAR(20))ENGINE=INNODB DEFAULT CHARSET=utf8;INSERT INTO classes VALUES(NULL,'一班'),(NULL,'二班');CREATE TABLE student(	id INT PRIMARY KEY AUTO_INCREMENT,	NAME VARCHAR(30),	age INT,	cid INT,	CONSTRAINT cs_fk FOREIGN KEY(cid) REFERENCES classes(id))ENGINE=INNODB DEFAULT CHARSET=utf8;INSERT INTO student VALUES(NULL,'张三',23,1),(NULL,'李四',24,1),(NULL,'王五',25,2),(NULL,'赵六',26,2);SELECT c.id cid, c.name cname, s.id sid, s.name sname, s.age sage  FROM classes c, student s WHERE c.id = s.cid;

实体类:Classes

package cn.itcast.bean;import java.util.List;public class Classes {       private Integer id; //主键id    private String name; //班级名称    private List
students; //班级中所有学生对象 public Classes() { } public Classes(Integer id, String name) { this.id = id; this.name = name; } 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 List
getStudents() { return students; } public void setStudents(List
students) { this.students = students; } @Override public String toString() { return "Classes{" + "id=" + id + ", name='" + name + '\'' + ", students=" + students + '}'; }}

实体类:Student

package cn.itcast.bean;public class Student {       private Integer id; //主键id    private String name; //学生姓名    private Integer age; //学生年龄    public Student() {       }    public Student(Integer id, String name, Integer age) {           this.id = id;        this.name = name;        this.age = age;    }    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 Integer getAge() {           return age;    }    public void setAge(Integer age) {           this.age = age;    }    @Override    public String toString() {           return "Student{" +                "id=" + id +                ", name='" + name + '\'' +                ", age=" + age +                '}';    }}

核心配置文件:

映射配置文件:

  • <resultMap>:配置字段和对象属性的映射关系标签
    • id属性:唯一标识
    • type属性:实体对象类型
  • <id>:配置主键映射关系标签
  • <result>:配置非主键映射关系标签
    • column属性:表中字段名称
    • property属性:实体对象变量名称
  • <collection>:配置被包含集合对象的映射关系标签
    • property属性:被包含对象的变量名
    • ofType属性:集合中保存的对象的数据类型

测试类:

@Testpublic void selectAll() throws IOException {       //1.加载核心配置文件    InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");    //2.获取SqlSession工厂对象    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);    //3.通过SqlSession工厂对象获取SqlSession对象    SqlSession sqlSession = sqlSessionFactory.openSession();    //4.获取OneToManyMapper接口的实现类对象    OneToManyMapper mapper = sqlSession.getMapper(OneToManyMapper.class);    //5.调用实现类方法,接收结果    List
list = mapper.selectAll(); //6.处理结果 for (Classes c : list) { System.out.println(c.getId()+", "+c.getName()); List
students = c.getStudents(); for (Student student : students) { System.out.println("\t"+student); } } //7.释放资源 sqlSession.close(); is.close();}

测试方法运行结果:

1, 一班

     Student{id=1, name=‘张三’, age=23}
     Student{id=2, name=‘李四’, age=24}
2, 二班
     Student{id=3, name=‘王五’, age=25}
     Student{id=4, name=‘赵六’, age=26}

4.4 多对多

多对多模型:学生和课程,一个学生可以选择多门课程,一个课程也可以被多个学生所选择

环境准备

创建表并添加数据:

CREATE TABLE course(	id INT PRIMARY KEY AUTO_INCREMENT,	NAME VARCHAR(20))ENGINE=INNODB DEFAULT CHARSET=utf8;INSERT INTO course VALUES(NULL,'语文'),(NULL,'数学');CREATE TABLE stu_cr(	id INT PRIMARY KEY AUTO_INCREMENT,	sid INT,	cid INT,	CONSTRAINT sc_fk1 FOREIGN KEY(sid) REFERENCES student(id),	CONSTRAINT sc_fk2 FOREIGN KEY(cid) REFERENCES course(id))ENGINE=INNODB DEFAULT CHARSET=utf8;INSERT INTO stu_cr VALUES(NULL,1,1),(NULL,1,2),(NULL,2,1),(NULL,2,2);SELECT s.id sid, s.name sname, s.age sage, c.id cid, c.name cname FROM student s,course c,stu_cr WHERE s.id = stu_cr.sid AND c.id = stu_cr.cid;

实体类:Student(该类在上面Student类基础上添加一个属性:private List<Course> courses; //学生所选课程的集合)

实体类:Course

package cn.itcast.bean;public class Course {       private Integer id; //主键id    private String name;//课程名称    public Course() {       }    public Course(Integer id, String name) {           this.id = id;        this.name = name;    }    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;    }    @Override    public String toString() {           return "Course{" +                "id=" + id +                ", name='" + name + '\'' +                '}';    }}

核心配置文件:

映射配置文件:

  • <resultMap>:配置字段和对象属性的映射关系标签
    • id属性:唯一标识
    • type属性:实体对象类型
  • <id>:配置主键映射关系标签
  • <result>:配置非主键映射关系标签
    • column属性:表中字段名称
    • property属性:实体对象变量名称
  • <collection>:配置被包含集合对象的映射关系标签
    • property属性:被包含对象的变量名
    • ofType属性:集合中保存的对象的数据类型

测试类:

@Testpublic void selectAll() throws IOException {       //1.加载核心配置文件    InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");    //2.获取SqlSession工厂对象    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);    //3.通过SqlSession工厂对象获取SqlSession对象    SqlSession sqlSession = sqlSessionFactory.openSession();    //4.获取ManyToManyMapper接口的实现类对象    ManyToManyMapper mapper = sqlSession.getMapper(ManyToManyMapper.class);    //5.调用实现类方法,接收结果    List
list = mapper.selectAll(); //6.处理结果 for (Student stu : list) { System.out.println(stu.getId()+", "+stu.getName()); List
courses = stu.getCourses(); for (Course course : courses) { System.out.println("\t"+course); } } //7.释放资源 sqlSession.close(); is.close();}

测试方法运行结果:

1, 张三

     Course{id=1, name=‘语文’}
     Course{id=2, name=‘数学’}
2, 李四
     Course{id=1, name=‘语文’}
     Course{id=2, name=‘数学’}

相关文章:、

上一篇:Mybatis高级
下一篇:每日一算法-4-数组

发表评论

最新留言

初次前来,多多关照!
[***.217.46.12]2025年03月20日 01时27分09秒