Mybatis学习笔记

Mybatis学习笔记

1、基础配置

1.1、前期准备

1、新建一个普通maven项目

普通的maven项目即直接点maven不用点下面的框架

2、删除新建项目的src目录
3、在pom.xml中添加依赖
<!--导入依赖-->
  <dependencies>
    <!--MySQL-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.16</version>
    </dependency>
    <!--junit-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13</version>
      <scope>test</scope>
    </dependency>
    <!--mybatis-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.4.6</version>
    </dependency>
  </dependencies>
4、新建module,给这个父项目添加子项目

这个module也是一个普通的maven项目

1.2、创建模块

1、新建mybatis-config.xml

在新建子项目中的src->main->resources下新建mybatis-config.xml文件

在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>
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
        <!--xml中不能直接使用&,要使用&amp;-->
        <property name="url" value="jdbc:mysql://localhost:3306/ob?useUnicode=true&amp;characterEncoding=utf8&amp;serverTimezone=UTC&amp;useSSL=false"/>
        <property name="username" value="root"/>
        <property name="password" value="1234"/>
      </dataSource>
    </environment>
  </environments>
  <!--每一个Mapper.xml都需要在Mybatis核心配置文件中注册-->
  <!--resource写的是接口实现mapper-->
  <mappers>
    <mapper resource="com/ljh/mapper/BookMapper.xml"/>
  </mappers>
</configuration>

注意:每一个Mapper.xml都需要在Mybatis核心配置文件中注册

其他注册方法:

其中的class引入和包引入都要求配置文件名称和接口名称一致,并且位于同一目录下

<!-- 使用相对于类路径的资源引用 (推荐使用)-->
<mappers>
 <mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
<!--
使用映射器接口实现类的完全限定类名
需要配置文件名称和接口名称一致,并且位于同一目录下
-->
<mappers>
 <mapper class="org.mybatis.builder.AuthorMapper"/>
</mappers>
<!--
将包内的映射器接口实现全部注册为映射器
但是需要配置文件名称和接口名称一致,并且位于同一目录下
-->
<mappers>
 <package name="org.mybatis.builder"/>
</mappers>

优化:

新建db配置文件

driver = com.mysql.cj.jdbc.Driver
url = jdbc:mysql://localhost:3306/ob?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false
username = root
password = 1234

在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 resource="db.properties"/>

  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <!--更改value值-->
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>
  </environments>
  <!--每一个Mapper.xml都需要在Mybatis核心配置文件中注册-->
  <mappers>
    <mapper resource="com/ljh/mapper/BookMapper.xml"/>
  </mappers>
</configuration>
2.编写mybatis工具类

在新建子项目中的src->main->java下新建包com.ljh.utils

在utils包下新建class文件MybatisUtils

public class MybatisUtils {
  public static SqlSessionFactory sqlSessionFactory;

  static {
    try {
      //构建 SqlSessionFactory
      //这里的resource路径不要写错,上次文件名和这里的名称不一致报错
      //报错:找不到xxx.xml文件
      String resource = "mybatis-config.xml";
      InputStream inputStream = Resources.getResourceAsStream(resource);
      sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  //既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。
  public static SqlSession getSqlSession() {
    //sqlSessionFactory.openSession(true)里面若是传入true,则代表自动提交事务,在增删改操作时不需要再提交事务,sqlSession.commit()
    return sqlSessionFactory.openSession();
  }
}

1.3、编写代码

1、编写实体类

在新建子项目中的src->main->java下新建包com.ljh.pojo

新建class文件编写实体类

编写无参、有参构造器,get、set方法,toString方法

public class Book {
  private int id;
  private String book_type;
  private String book_author;
  private String book_name;
  private String book_intro;

  public Book() {
  }

  public Book(int id, String book_type, String book_author, String book_name, String book_intro) {
    this.id = id;
    this.book_type = book_type;
    this.book_author = book_author;
    this.book_name = book_name;
    this.book_intro = book_intro;
  }

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }

  public String getBook_type() {
    return book_type;
  }

  public void setBook_type(String book_type) {
    this.book_type = book_type;
  }
  //下面的get、set省略
  @Override
  public String toString() {
    return "Book{" +
            "id=" + id +
            ", book_type='" + book_type + '\'' +
            ", book_author='" + book_author + '\'' +
            ", book_name='" + book_name + '\'' +
            ", book_intro='" + book_intro + '\'' +
            '}';
  }
}
2、编写Mapper文件

在新建子项目中的src->main->java下新建包com.ljh.mapper

新建一个接口(interface)

public interface BookMapper {
  List<Book> getBookList();
}

新建接口实现类,其实是用mapper.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接口,这里绑定刚写好的那个接口-->
<mapper namespace="com.ljh.mapper.BookMapper">
  <!--id里面是接口里面命名的函数-->
  <!--必须有一个resultType或者resultMap-->
  <!--resultType写的是实体类的路径-->
  <select id="getBookList" resultType="com.ljh.pojo.Book">
    select * from ob.ob_books
  </select>
</mapper>

1.4、junit测试

在test文件夹下->java下新建包com.ljh.mapper(与上面同样的目录等级)

在mapper里新建测试类,这里是BookMapperTest类

public class BookMapperTest {
  @Test
  public void test() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BookMapper mapper = sqlSession.getMapper(BookMapper.class);
    List<Book> bookList = mapper.getBookList();

    for (Book book : bookList) {
      System.out.println(book);
    }
    sqlSession.close();
  }
}

1.5、报错

1、mybatis-config.xml名称不要写错

mybatis-config.xml名称写错也会报找不到该文件

2、maven静态资源过滤

由于maven工程约定大于配置,在resources和java文件夹下有我们写的配置文件,可能无法被导出执行 。

解决方法:在父项目和模块中加入以下代码

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>
3、在接口实现Mapper.xml里不能有中文注释

第一次写的时候有中文注释,一直报错:java.lang.ExceptionInInitializerError Error building SqlSession.

把中文注释去掉后就能完美运行。

但是又把中文注释加上后还能正常运行,不知道怎么回事。

2、增删改查

前面的基础项配置好之后,对一个数据的增删改查就比较容易了

只需更改接口类、接口实现mapper就可以,在Test文件夹中测试就可以了

1、接口类

public interface BookMapper {
  //查询所有书籍
  List<Book> getBookList();
  //查询特定ID的书籍
  Book getBookById(int id);
  //增加一本书籍
  int addBook(Book book);
  //更新特定ID的书籍
  int updateBook(Book book);
  //删除特定书籍
  int deleteBookById(int id);
}

2、mapper.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接口-->
<mapper namespace="com.ljh.mapper.BookMapper">
  <select id="getBookList" resultType="com.ljh.pojo.Book">
    select * from ob.ob_books
  </select>
  <select id="getBookById" parameterType="int" resultType="com.ljh.pojo.Book">
    select * from ob.ob_books where id = #{id}
  </select>
  <insert id="addBook" parameterType="com.ljh.pojo.Book">
    insert into ob_books (id,book_type,book_author,book_name,book_intro) values (#{id},#{book_type},#{book_author},#{book_name},#{book_intro})
  </insert>
  <update id="updateBook" parameterType="com.ljh.pojo.Book">
    update ob.ob_books set book_name=#{book_name},book_intro=#{book_intro} where id = #{id}
  </update>
  <delete id="deleteBookById" parameterType="int">
    delete from ob.ob_books where id = #{id}
  </delete>
</mapper>

3、Test测试

public class BookMapperTest {
  @Test
  public void getBookList() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BookMapper mapper = sqlSession.getMapper(BookMapper.class);
    List<Book> bookList = mapper.getBookList();
    for (Book book : bookList) {
      System.out.println(book);
    }
    sqlSession.close();
  }

  @Test
  public void getBookByIdTest() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BookMapper mapper = sqlSession.getMapper(BookMapper.class);
    Book bookById = mapper.getBookById(5);
    System.out.println(bookById);

    sqlSession.close();
  }

  @Test
  public void addBookTest() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BookMapper mapper = sqlSession.getMapper(BookMapper.class);
    Book book = new Book(224, "history", "小李", "非诚勿扰", "这是一本奇书");
    int i = mapper.addBook(book);
    if(i>0) {
      System.out.println("插入成功!");
    }
    sqlSession.commit();
    sqlSession.close();
  }
  @Test
  public void updateBookTest() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BookMapper mapper = sqlSession.getMapper(BookMapper.class);
    Book book = mapper.getBookById(224);
    //先获取这本书,再设置值
    book.setBook_intro("非常好看的一本书");
    book.setBook_name("哈哈哈");
    int i = mapper.updateBook(book);
    if(i>0) {
      System.out.println("更新成功");
    }
    sqlSession.commit();
    sqlSession.close();
  }
  @Test
  public void deleteBookTest() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BookMapper mapper = sqlSession.getMapper(BookMapper.class);
    int i = mapper.deleteBookById(224);
    if(i>0) {
      System.out.println("删除成功");
    }
    sqlSession.commit();
    sqlSession.close();
  }
}

4、注意点

namespace必须绑定一个Mapper接口

接口类中的方法名与映射文件中的SQL语句ID一一对应,注意名称大小写,要对应写好

parameterType是传入参数的类型

resultType是返回值的类型

增删改操作必须要提交事务,即sqlSession.commit();

处理完要关闭,sqlSession.close();

3、万能的Map

Map<String, Object> map = new HashMap<String, Object>();

Map是一个接口,HashMap是具体的实现类。
由于接口是类的蓝图,是一个抽象的概念,不能被实例化,因此接口需要由具体的类来实现。
这条代码指明:由HashMap类来实现接口Map中描述的方法。

上层接口描述的功能不变,下层的具体实现可以不断修改替换。上层的调用者只用知道map的功能,不必关心map的具体实现。

这样做的好处在于:你的程序会更灵活。当你决定更换实现的时候,所要做的就只是:改变构造器中类的名称。就比如:Map<Integer,String> map = new TreeMap<>();

如果不这么做,在最早就使用了HashMap来声明了map,如果客户端在其他地方,使用了HashMap的操作,那么后续若改动了,则无法通过编译了。

可以把接口类中的形参定义为map,然后传入map就可以了

在形参有多个的情况下,用map或者注解

接口类

//查询特定条件的书籍
List<Book> getBooks(Map<String,Object> map);
//用Map增加书籍
int addBookByMap(Map<String,Object> map);

mapper.xml

<select id="getBooks" parameterType="map" resultType="com.ljh.pojo.Book">
    select * from ob.ob_books where id= #{bookId} and book_type = #{bookType}
</select>
<insert id="addBookByMap" parameterType="map">
    insert into ob.ob_books (id,book_type,book_author,book_name) values (#{bookId},#{bookType},#{bookAuthor},#{bookName})
</insert>

Test测试

@Test
public void getBooksTest() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BookMapper mapper = sqlSession.getMapper(BookMapper.class);
    Map<String, Object> map = new HashMap<String, Object>();
    map.put("bookId",72);
    map.put("bookType","magazine");
    List<Book> books = mapper.getBooks(map);
    for (Book book : books) {
        System.out.println(book);
    }
    sqlSession.close();
}
@Test
public void addBookByMapTest() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BookMapper mapper = sqlSession.getMapper(BookMapper.class);
    Map<String, Object> map = new HashMap<String, Object>();
    map.put("bookId",224);
    map.put("bookType","history");
    map.put("bookAuthor","东皇太一");
    map.put("bookName","吸功大法");
    mapper.addBookByMap(map);
    sqlSession.commit();
    sqlSession.close();
}

4、别名(TypeAliases)、注解

类型别名可为 Java 类型设置一个缩写名字

在resultType中,每次都需要把Java包下的实体类给打出来,起个别名更高效

mybatis-config.xml里面添加,注意位置,TypeAliases排第三个

<!--第一种方式-->
<typeAliases>
    <typeAlias type="com.ljh.pojo.Book" alias="Book"/>
</typeAliases>
<!--第二种方式-->
<!--每一个在包 com.kuang.pojo 中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。若有注解,则别名为其注解值。-->
<typeAliases>
    <package name="com.ljh.pojo"/>
</typeAliases>

注解的方式:

先在mybatis-config.xml里面添加下面代码:

<typeAliases>
    <package name="com.ljh.pojo"/>
</typeAliases>

在实体类上面添加@Alias(“别名名称”)

@Alias("book")
public class Book {}

5、ResultMap

在实体类中,定义与数据库表中不同的字段,会使查询到的值为null

解决方案:

  1. 起别名, 别名和java实体类的属性名一致 .

    <select id="selectUserById" resultType="User">
      select id , name , pwd as password from user where id = #{id}
    </select>
    
  2. 使用结果集映射->ResultMap 【推荐】

<resultMap id="UserMap" type="User">
   <!-- id为主键 -->
   <id column="id" property="id"/>
   <!-- column是数据库表的列名 , property是对应实体类的属性名 -->
   <result column="name" property="name"/>
   <result column="pwd" property="password"/>
</resultMap>

<select id="selectUserById" resultMap="UserMap">
  select id , name , pwd from user where id = #{id}
</select>

6、日志

1、 STDOUT_LOGGING

在mybatis-config.xml中配置,注意拼写及setting位置

<settings>
    <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>

2、LOG4J

引入依赖,在pom.xml引入依赖

<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

在resources目录下引入配置文件log4j.properties

#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
log4j.rootLogger=DEBUG,console,file

#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n

#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/ljh.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n

#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

在mybatis-config.xml中配置

<settings>
    <setting name="logImpl" value="LOG4J"/>
</settings>

测试

import org.apache.log4j.Logger;

public class BookMapperTest {
  static Logger logger = Logger.getLogger(BookMapperTest.class);
  @Test
  public void getBookList() {
    logger.info("info");
    logger.debug("debug");
    logger.error("error");
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BookMapper mapper = sqlSession.getMapper(BookMapper.class);
    List<Book> bookList = mapper.getBookList();
    for (Book book : bookList) {
      System.out.println(book);
    }
    sqlSession.close();
  }
}

注意点:导包不要导错,org.apache.log4j.Logger

执行后会在模块下面新建一个log的日志文件,若文件打不开,可以File->setting->File Types

然后再Recognized file types和registered patterns里点击+,添加日志文件*.log即可

7、分页

limit实现分页

起始位置 = (当前页面 - 1 ) * 页面大小

startIndex = ( currentIndex - 1 ) * pageSize

startIndex为起始页,currentIndex为当前页,pageSize为每页的数据个数

接口

//limit分页查询
  List<Book> getBookByLimit(Map<String,Object> map);

mapper.xml

<select id="getBookByLimit" resultType="book" parameterType="map">
    select * from ob_books limit #{startIndex},#{pageSize}
</select>

测试

@Test
public void getBookByLimit() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BookMapper mapper = sqlSession.getMapper(BookMapper.class);
    Map<String, Object> map = new HashMap<String, Object>();
    map.put("startIndex",0);
    map.put("pageSize",2);

    mapper.getBookByLimit(map);
    sqlSession.close();
}

8、注解

注解主要简化代码,不需要在mapper.xml中写sql语句

用法:

在mybatis核心配置文件mybatis-config.xml中注入

<mappers>
    <mapper class="com.ljh.mapper.BookMapper"/>
</mappers>

实现CRUD

Mapper接口中

public interface BookMapper {
  @Select("select * from ob_books")
  List<Book> getBookList();
  @Insert("insert into ob_books(id,book_type,book_author,book_name) values (#{id},#{book_type},#{book_author},#{book_name})")
  int addBook(Book book);
  @Update("update ob_books set book_intro = #{book_intro},book_img = #{book_img} where id = #{id}")
  int updateBook(Map<String,Object> map);
  @Delete("delete from ob_books where id = #{id}")
  int deleteBook(@Param("id") int id);
}

测试

public class BookMapperTest {
  @Test
  public void getBookList() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BookMapper mapper = sqlSession.getMapper(BookMapper.class);
    List<Book> bookLists = mapper.getBookList();
    for (Book bookList : bookLists) {
      System.out.println(bookList);
    }
    sqlSession.close();
  }
  @Test
  public void addBook() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BookMapper mapper = sqlSession.getMapper(BookMapper.class);
    mapper.addBook(new Book(4,"history","司马迁","史记","奇书"));
    sqlSession.commit();
    sqlSession.close();
  }
  @Test
  public void updateBook() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BookMapper mapper = sqlSession.getMapper(BookMapper.class);
    Map<String, Object> map = new HashMap<String, Object>();
    map.put("id",3);
    map.put("book_intro","这本书很好看");
    map.put("book_img","127.0.0.1");
    mapper.updateBook(map);
    sqlSession.commit();
    sqlSession.close();
  }
  @Test
  public void deleteBook() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BookMapper mapper = sqlSession.getMapper(BookMapper.class);
    mapper.deleteBook(2);
    sqlSession.commit();
    sqlSession.close();
  }
}

@param()

在方法只接受一个参数的情况下,可以不使用@Param

在方法接受多个参数的情况下,建议一定要使用@Param注解给参数命名

9、Lombok

不用再写get、set方法,toString方法等,在pojo的实体类中使用注解来简化代码

使用:

  • 下载Lombok插件

  • 在pom.xml中添加依赖

<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.12</version>
    <scope>provided</scope>
</dependency>
  • 在实体类中测试

    @Data:生成get/set、equals、hashCode、toString、无参构造
    @AllArgsConstructor:有参构造
    @NoArgsConstructor:无参构造
    @ToString
    @Getter
    @Setter
    
  • 若不能用Lombok的注解,可以 file–>setting–>build,excecution,deployment–>compiler–>annotation processors勾选上 enable annotation processing。即可生效。

10、多对一:assocaiation

1、获取所有学生及对应老师的信息

sql语句:

select s.id sId,s.name sName,t.name tName
from student s,teacher t
where s.tid = t.id

思路一:

  1. 获取所有学生的信息
  2. 根据获取的学生信息的老师ID->获取该老师的信息
  3. resultMap结果集关联association

实现类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
  private int id;
  private String name;
  //多个学生一个老师
  private Teacher teacher;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Teacher {
  private int id;
  private String name;
}

接口类

List<Student> getStudentList();

Mapper.xml

<select id="getStudentList" resultMap="stMap">
    select * from student
</select>
<!--上面的resultMap参数就是下面的id-->
<resultMap id="stMap" type="Student">
    <association property="teacher" column="tid" javaType="Teacher" select="getTeacherList"/>
</resultMap>
<select id="getTeacherList" resultType="Teacher">
    select * from teacher where id = #{id}
</select>

2、注意

association是resultMap中的一个配置选项

参数property代表实体类中定义的对象的名称

参数 javaType代表关联属性的类型

column的名称是结果表的column名称而不是原表的colum名称,虽然不起别名的话二者相同

参数select要和要关联的select语句的id相同

测试

@Test
public void test() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    List<Student> studentList = mapper.getStudentList();
    for (Student student : studentList) {
        System.out.println(student);
        System.out.println(student.getTeacher().getName());
    }
    sqlSession.close();
}

思路二:通过整个sql语句查询

接口类

List<Student> getStudentTeacherList();

Mapper.xml

<select id="getStudentTeacherList" resultMap="StudentTeacher">
    select s.id sId,s.name sName,t.name tName
    from student s,teacher t
    where s.tid = t.id
</select>
<resultMap id="StudentTeacher" type="Student">
    <result property="id" column="sId"/>
    <result property="name" column="sName"/>
    <association property="teacher" javaType="Teacher">
        <result property="name" column="tName"/>
    </association>
</resultMap>

测试

@Test
public void getStudentList() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    List<Student> studentList = mapper.getStudentTeacherList();
    for (Student student : studentList) {
        System.out.println(student);
    }
    sqlSession.close();
}

11、一对多:collection

1、通过老师ID获取对应学生信息

1.1、方法一

实现:

实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
  private int id;
  private String name;
  private int tid;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Teacher {
  private int id;
  private String name;
  //一个老师对应多个学生
  private List<Student> students;
}

接口类

Teacher getStudentByTeacherId(@Param("tid") int id);

Mapper.xml

<select id="getStudentByTeacherId" resultMap="getStudent">
    select t.id tid,t.name tname,s.name sname
    from student s,teacher t
    where s.tid = t.id and t.id = #{tid}
</select>
<resultMap id="getStudent" type="Teacher">
    <result property="id" column="tid"/>
    <result property="name" column="tname"/>
    <collection property="students" ofType="Student">
        <result property="name" column="sname"/>
        <result property="id" column="id"/>
        <result property="tid" column="tid"/>
    </collection>
</resultMap>

测试

@Test
public void getStudentByTeacherId() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
    Teacher teacher = mapper.getStudentByTeacherId(1);
    System.out.println(teacher);
    sqlSession.close();
}
1.2、方法二

接口类

Teacher getStudentByTeacherId2(@Param("id") int id);

Mapper.xml

<select id="getStudentByTeacherId2" resultMap="getStudent2">
    select * from teacher where id = #{id}
</select>
<resultMap id="getStudent2" type="Teacher">
    <!--下面的column是Teacher实体类里面的id-->
    <collection property="students" javaType="ArrayList" ofType="Student" column="id" select="getStu"/>
</resultMap>
<select id="getStu" resultType="Student">
    select * from student where tid = #{tid}
</select>

测试

@Test
public void getStudentByTeacherId2() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
    Teacher teacher = mapper.getStudentByTeacherId2(1);
    System.out.println(teacher);
    sqlSession.close();
}

2、注意

1、关联-association

2、集合-collection

3、所以association是用于一对一和多对一,而collection是用于一对多的关系

4、JavaType和ofType都是用来指定对象类型的

  • JavaType是用来指定pojo中属性的类型
  • ofType指定的是映射到list集合属性中pojo的类型。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值