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中不能直接使用&,要使用&-->
<property name="url" value="jdbc:mysql://localhost:3306/ob?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&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
解决方案:
-
起别名, 别名和java实体类的属性名一致 .
<select id="selectUserById" resultType="User"> select id , name , pwd as password from user where id = #{id} </select>
-
使用结果集映射->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
思路一:
- 获取所有学生的信息
- 根据获取的学生信息的老师ID->获取该老师的信息
- 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的类型。