Mybatis

Mybatis

框架是一个半成品 我们可以在框架离快速的开发

持久化

数据持久化

  • 持久化就是将程序的数据在持久状态和瞬时状态转化的过程
  • 内存:断电即失
  • 数据库(Jdbc),io文件持久化。

持久层

Dao层、Service层、Controller层

  • 完成持久化工作的代码块
  • 层界限十分明显

查询

dao层

package Mybait.dao;



import Mybait.pojo.User;

import java.util.List;

public interface IuserDao {
    public List<User> getUserList();
}

Service已改xml


DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="Mybait.dao.IuserDao">

    
<select id="getUserList" resultType="Mybait.pojo.User">
    select * from User
    select>
mapper>

数据库配置文件


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.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/smbms?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            dataSource>
        environment>
    environments>

configuration>


Mybatis工具类

package Mybait.utils;


import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

public class MybaitUser {
    private static SqlSessionFactory sqlSessionFactory;
    static{
        try {
            //使用Mybatis第一步:获取sqlSessionFactory对象
            String resource = "mysql-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    //既然有了 SqlSessionFactory,顾名思义,我们就可以从中获得 SqlSession 的实例了。
    // SqlSession 完全包含了面向数据库执行 SQL 命令所需的所有方法。
    public static SqlSession  getSqlSession(){
        return sqlSessionFactory.openSession();
    }

}

测试类

@Test
public void test(){
    //第一步:获得SqlSession对象
    SqlSession sqlSession = MybatisUtils.getSqlSession();


    //方式一:getMapper
    UserDao userDao = sqlSession.getMapper(UserDao.class);
    List<User> userList = userDao.getUserList();

    for (User user : userList) {
        System.out.println(user);
    }



    //关闭SqlSession
    sqlSession.close();
}




小心数据过滤问题


    <build>
        <resources>
            <resource>
                <directory>src/main/resourcesdirectory>
                <includes>
                    <include>**/*.propertiesinclude>
                    <include>**/*.xmlinclude>
                includes>
            resource>
            <resource>
                <directory>src/main/javadirectory>
                <includes>
                    <include>**/*.propertiesinclude>
                    <include>**/*.xmlinclude>
                includes>
            resource>
        resources>
    build>

数据过滤问题 刷新 test
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BukylvZL-1669197960879)(Mybatis.assets/image-20220601150602850.png)]

小心数据库时钟问题 serverTimezone=GMT



增删改查

  • id:就是对应的namespace中的方法名;
  • resultType:Sql语句执行的返回值!
  • parameterType:参数类型

接口


package yu.dao;

import yu.po.User;


import java.util.List;

public interface UserDao {
     List<User> getUserList();
    User getUserById(int id);
    int addUser(User u);
    int updateUser(User u);
    int deleteUser(User user);
}

DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">


<mapper namespace="yu.dao.UserDao">

    
    <select id="getUserList" resultType="yu.po.User">
        select * from user
    select>
    <select id="getUserById" parameterType="int" resultType="yu.po.User">
        select * from user where id=#{id}
    select>
    <insert id="addUser" parameterType="yu.po.User">
insert into user (id,username,birthday,sex,address) value (#{id},#{username},#{birthday},#{sex},#{address})

insert>

    <update id="updateUser" parameterType="yu.po.User">
        update USER
        set sex =#{sex}
        where id=#{id};
    update>

    <delete id="deleteUser" parameterType="User">
delete from user where id=#{id} and sex =#{sex}
    delete>
mapper>

测试类

import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import yu.dao.UserDao;
import yu.po.User;
import yu.utils.MybaitUser;

import javax.xml.crypto.Data;
import java.util.Date;
import java.util.List;

public class main {
    SqlSession sqlSession = MybaitUser.getSqlSession();

    UserDao mapper = sqlSession.getMapper(UserDao.class);
    @Test
    //查询全面
    public void m(){

        List<User> userList = mapper.getUserList();
        for (User a:userList
             ) {
            System.out.println(a);
        }
        sqlSession.close();

    }    @Test
    //id单个查询
    public void id(){

        User userById = mapper.getUserById(6);
        System.out.println(userById);
        sqlSession.close();


    }

    @Test//添加
    public void add() {
        User user = new User();
        Date a = new Date();
        System.out.println("1111111111111111111111111111111111111");
        System.out.println(a);
        user.setId(6);
        user.setUsername("老六");
        user.setSex("66");
        user.setBirthday(a);
        user.setAddress("我不知道");
        System.out.println("--------------------");
        System.out.println(mapper.addUser(user));
        sqlSession.commit();
        sqlSession.close();


    }

    @Test//修改
    public void up() {
        User user = new User();
        user.setSex("女");
        user.setId(6);
        mapper.updateUser(user);
        sqlSession.commit();
        sqlSession.close();

    }

    @Test//删除
    public void dele() {
        User user = new User();
        user.setSex("女");
        user.setId(6);
        mapper.
                deleteUser(user);
        sqlSession.commit();
        sqlSession.close();
    }
}

Map导入

Map传递参数,直接在sql中取出key即可!【parameterType=“map”】
对象传递参数,直接在sql中取对象的属性即可!【parameterType=“Object”】
只有一个基本类型参数的情况下,可以直接在sql中取到!
多个参数用Map,或者注解!

接口

int addUser01(Map map);

配置


    insert into user (id, username) value (#{id},#{username})


测试类

@Test
public void map(){
    Map map = new HashMap();
    map.put("id", 10086);
    map.put("username", "钰钰");
    mapper.addUser01(map);
    sqlSession.commit();
    sqlSession.close();
}

模糊查询

接口

List  getUserByjn(User U);

配置

  

配置解析

核心配置文件
1、configuration(配置)

Mybatis可以配置成适应多种环境
不过要记住:尽管可以配置多个环境,但每个实例只能选择一种环境。
使用配置多套运行环境!
Mybatis默认的事务管理器就是JDBC,连接池:POOLED2、

properties(属性)

我们可以通过properties属性来实现引用配置文件
这些属性都是可外部配置且可动态替换的,既可以在典型的Java属性文件中配置,亦可通过properties元素的子元素来传递。【db.properties】
编写一个配置文件
db.properties3、settings(设置)
4、typeAliases(类型别名)

5、typeHandlers(类型处理器)
6、objectFactory(对象工厂)
7、plugins(插件)
8、environments(环境配置)
9、environment(环境变量)
10、transactionManager(事务管理器)
11、dataSource(数据源)
12、databaseIdProvider(数据库厂商标识)
13、mappers(映射器)

<?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核心配置文件-->
<configuration>
<!-- 注册别名-->
    <typeAliases>
        <package name="yu.po"/>
    </typeAliases>
    <!--environments叫做环境-->
    <environments default="test">
<!--        //多少套环境-->
        <environment id="development">
            <transactionManager type="JDBC"/>
<!--            jdbc-->
            <dataSource type="POOLED">
<!--                有池链接-->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <!--&amp相当于and,userSSL=true安全连接等于true,
                userUnicode=true,编码使用Unicode-->
                <!--配置时区 serverTimezone=GMT-->
                <property name="url" value="jdbc:mysql://localhost:3306/mybatisdb?useSSL=true&useUnicode=true&serverTimezone=GMT&characterEncoding=UTF-8"/>

                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
        <!--        //多少套环境-->
        <environment id="test">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <!--&amp相当于and,userSSL=true安全连接等于true,
                userUnicode=true,编码使用Unicode-->
                <!--配置时区 serverTimezone=GMT-->
                <property name="url" value="jdbc:mysql://localhost:3306/mybatisdb?useSSL=true&useUnicode=true&serverTimezone=GMT&characterEncoding=UTF-8"/>

                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

    <!--每一个Mapper.xml都需要在Mybatis核心配置文件中注册!-->
    <mappers>
        <mapper resource="yu/dao/UserDao.xml"/>
    </mappers>

</configuration>

注解类别名typeAliases

@Alias("666")//注解别名
public interface UserDao {
     List getUserList();
    User getUserById(int id);
    List  getUserByjn(User U);
    int addUser(User u);
    int addUser01(Map map);
    int updateUser(User u);
    int deleteUser(User user);
}

    
    

配置environments

这是MyBatis中极为重要的调整设置,它们会改变MyBatis的运行时行为。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lTk1N0BJ-1669197960881)(Mybatis.assets/20201023095101296.png#pic_center)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yqozpy9d-1669197960881)(Mybatis.assets/20201023095121579.png#pic_center)]

映射器

方式一resource

    
        
       
    

方式二class

    

        
    

注意点:

  • 接口和它的Mapper配置文件必须同名!
  • 接口和它的Mapper配置文件必须在同一个包下!

方式三使用扫描包进行注入绑定

    


        
    

生命周期和作用域

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-skM7bHf2-1669197960882)(Mybatis.assets/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xpNjQzOTM3NTc5,size_16,color_FFFFFF,t_70#pic_center.png)]

SqlSessionFactoryBuilder

一旦创建了 SqlSessionFactory,就不再需要它了。
局部变量

SqlSessionFactory:

可以想象为:数据库连接池。
SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。
SqlSessionFactory 的最佳作用域是应用作用域。
最简单的就是使用单例模式或者静态单例模式。

SqlSession:

连接到连接池的一个请求!
SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。
用完后需要赶紧关闭,防止资源被占用!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rJAyrgAL-1669197960882)(Mybatis.assets/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xpNjQzOTM3NTc5,size_16,color_FFFFFF,t_70#pic_center-16544203483402.png)]

resultMap

测试实体类字段不一致的情况

public class User {
    private Integer  id;
    private String username;
    private Date birthday;
    private String sexx;
    private String address;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eqkDlGi3-1669197960883)(Mybatis.assets/image-20220605185248005.png)]

//    select * from mybatis.user where id = #{id}
// 类型处理器
//    select id,name,pwd from mybatis.user where id = #{id}

解决方法 起别名

    

resultMap



    
        
        
        
        
        
    



   
  • resultMap 元素是 MyBatis 中最重要最强大的元素。
  • ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。
  • ResultMap 的优秀之处——你完全可以不用显式地配置它们。
  • 如果这个世界总是这么简单就好了。

动态sql

什么是动态SQL:动态SQL就是 指根据不同的条件生成不同的SQL语句

利用动态SQL这一特性可以彻底摆脱这种痛苦。

Foreach

动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)。

foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符,看它多智能!

提示你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。

public void setIds(){
    QueryVo queryVo = new QueryVo();
    List integers = new ArrayList<>();
    integers.add(1);
    integers.add(2);
    integers.add(3);
    queryVo.setIds(integers);
    mapper.getUserNameId(queryVo);

}
<select id="getUserNameId" resultType="666" parameterType="yu.dao.QueryVo">
        select * from user
    <where>
    <if test="ids">
        <foreach collection="ids" item="id" open="and (" close=")" separator="or">
            id = #{id}
        </foreach>
    </if>
    </where>

    </select>

日志

日志工厂

日志排错小能手
曾经:sout、debug
现在:日志工厂!

  • SLF4J
  • LOG4J 【掌握】
  • LOG4J2
  • JDK_LOGGING
  • COMMONS_LOGGING
  • STDOUT_LOGGING【掌握】
  • NO_LOGGING

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Petf9bab-1669197960883)(Mybatis.assets/20201024092353850-16546513358602.png#pic_center)]STDOUT_LOGGING标准日志输出config.xml核心配置文件中,配置我们的日志!


    

在这里插入图片描述在mybatis-

Log4j

什么是Log4j?

Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件
我们也可以控制每一条日志的输出格式;
通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。

1.先在pom.xml文件中导入log4j的依赖包


    
    
        log4j
        log4j
        1.2.17
    

2.在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/kuang.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

3.在mybatis-config.xml核心配置文件中,配置log4j为日志的实现!


    

4.Log4j的使用,直接测试运行

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GuMKEJ0k-1669197960884)(Mybatis.assets/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xpNjQzOTM3NTc5,size_16,color_FFFFFF,t_70#pic_center.png)]

简单使用

  1. 在要使用Log4j的测试类中,导入包import org.apache.log4j.Logger;
  2. 日志对象,参数为当前类的class
static Logger logger = Logger.getLogger(UserDaoTest.class);

日志级别

logger.info("info 进入LoggerTest");
logger.debug("debug进入LoggerTest");
logger.error("error进入LoggerTest");

limit分页

语法:SELECT * from user limit startIndex,pageSize SELECT  * from user limit 3 *#[0,n]*

接口

//分页
Listlimit(Map map);

xml


测试

@Test
    public void limit (){
 
    Map map = new HashMap();
    map.put("a", 0);
    map.put("b", 2);
    List limit = mapper.limit(map);
    for ( User A:limit
         ) {
        System.out.println(A);
    }

}

RowBounds分页

public void RowBound(){
    RowBounds rowBounds = new RowBounds(0,2);
//    类加方法名
    List objects = sqlSession.selectList("yu.dao.UserDao.getUserByRowBounds", null, rowBounds);
    for ( User A:objects
    ) {
        System.out.println(A);
    }
}
}

注解开发

面向接口编程
之前学过面向对象编程,也学习过接口,但在真正的开发中,很多时候会选择面向接口编程。
根本原因:解耦,可拓展,提高复用,分层开发中,上层不用管具体的实现,大家都遵守共同的标准,使得开发变得容易,规范性更好
在一个面向对象的系统中,系统的各种功能是由许许多多的不同对象协作完成的。在这种情况下,各个对象内部是如何实现自己的,对系统设计人员来讲就不那么重要了;
而各个对象之间的协作关系则成为系统设计的关键。小到不同类之间的通信,大到各模块之间的交互,在系统设计之初都是要着重考虑的,这也是系统设计的主要工作内容。面向接口编程就是指按照这种思想来编程。

接口

package yu.dao;

import org.apache.ibatis.annotations.Select;
import yu.po.User;

import java.util.List;

public interface zhujUser0 {
    @Select("select * from user")
    List getUser();


}

测试

package yu.dao;

import org.apache.ibatis.annotations.Select;
import yu.po.User;

import java.util.List;

public interface zhujUser0 {
    @Select("select * from user")
    List getUser();


}

增删改查

public interface zhujUser0 {
    @Select("select * from user")
    List getUser();
    @Select("select account.*,user.* from account left join user on account.uid=user.id")
    List vs2();
    @Select("select user.*,account.* from user left join account on account.uid=user.id")
    List VS1();
    @Select("select * from user where id=#{id} and username=#{name}")
   User idAndName(@Param("id") int id1,@Param("name") String name1);//Param是从Select取的参数
    @Insert("insert into dept (id,NAME) values(#{id},#{NAME})")
    int add(Dept U);
    @Delete("delete from dept where id = #{uid}")
    int Delete(@Param("uid") int uid);
    @Update("update dept set NAME=#{NAME} where id=#{id}")
    int updateUser(Dept user);


}

延迟加载

延迟加载: 就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据。延迟加载也称懒加载. 好处:先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速 度要快。 坏处: 因为只有当需要用到数据时,才会进行数据库查询,这样在大批量数据查询时,因为查询工作也要消耗 时间,所以可能造成用户等待时间变长,造成用户体验下降。

一对多查询

AccountUser 继承Account 实习User

package yu.po;

public class AccountUser extends User {
    private   int uuID;
    private int UID;
    private Double MONEY;




    public int getUID() {
        return UID;
    }

    public void setUID(int UID) {
        this.UID = UID;
    }

    public Double getMONEY() {
        return MONEY;
    }

    public void setMONEY(Double MONEY) {
        this.MONEY = MONEY;
    }

    public int getUuID() {
        return uuID;
    }

    public void setUuID(int uuID) {
        this.uuID = uuID;
    }

    @Override
    public String toString() {
        return "AccountUser{" +
                "uuID=" + uuID +
                ", UID=" + UID +
                ", MONEY=" + MONEY +
                '}';
    }
}

多对多

  package yu.po;

import java.util.Date;
import java.util.List;

public class User {
    private Integer  id;
    private String username;
    private Date birthday;
    private String sexx;
    private String address;
    private List accountList;

    public List getAccountList() {
        return accountList;
    }

    public void setAccountList(List accountList) {
        this.accountList = accountList;
    }

    public User() {
    }

    public Integer getId() {
        return id;
    }

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

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getSexx() {
        return sexx;
    }

    public void setSexx(String sexx) {
        this.sexx = sexx;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", birthday=" + birthday +
                ", sexx='" + sexx + '\'' +
                ", address='" + address + '\'' +
                ", accountList=" + accountList +
                '}';
    }
}

狂神多对一

多对一处理
多对一:

多个学生,对应一个老师
对于学生而言,关联–多个学生,关联一个老师【多对一】
对于老师而言,集合–一个老师,有很多个学生【一对多】
SQL语句:

CREATE TABLE `teacher` (
	`id` INT(10) NOT NULL,
	`name` VARCHAR(30) DEFAULT NULL,
	PRIMARY KEY (`id`)
)ENGINE = INNODB DEFAULT CHARSET=utf8

INSERT INTO teacher(`id`,`name`) VALUES (1,'秦老师');

CREATE TABLE `student` (
	`id` INT(10) NOT NULL,
	`name` VARCHAR(30) DEFAULT NULL,
	`tid` INT(10) DEFAULT NULL,
	PRIMARY KEY (`id`),
	KEY `fktid`(`tid`),
	CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
)ENGINE = INNODB DEFAULT CHARSET=utf8

INSERT INTO `student`(`id`,`name`,`tid`) VALUES ('1','小明','1');
INSERT INTO `student`(`id`,`name`,`tid`) VALUES ('2','小红','1');
INSERT INTO `student`(`id`,`name`,`tid`) VALUES ('3','小张','1');
INSERT INTO `student`(`id`,`name`,`tid`) VALUES ('4','小李','1');
INSERT INTO `student`(`id`,`name`,`tid`) VALUES ('5','小王','1');
测试环境搭建

导入Lombok
新建实体类Teacher,Student
建立Mapper接口
建立Mapper.XML文件
在核心配置文件中绑定注册我们的Mapper接口或者文件!【方式很多,随心选】
测试查询是否能够成功!

按照结果嵌套处理
    
    

    
    
    
        
    

按照查询嵌套处理

    
    

    
    
    
    



回顾Mysql多对一查询方式:

子查询
联表查询

狂神一对多处理

比如:一个老师拥有多个学生!
对于老师而言,就是一对多的关系!

环境搭建
环境搭建,和刚才一样
实体类:

@Data
public class Student {
    private int id;
    private String name;
    private int tid;
@Data
public class Teacher {
    private int id;
    private String name;
//一个老师拥有多个学生
private List students;
}

按照结果嵌套处理






    
    
    
    
        
        
        
    

小结
关联-association【多对一】
集合-collection【一对多】
javaType & ofType
javaType 用来指定实体类中属性的类型
ofType 用来指定映射到List或者集合中的pojo类型,泛型中的约束类型!
注意点:

保证SQL的可读性,尽量保证通俗易懂
注意一对多和多对一中,属性名和字段的问题!
如果问题不好排查错误,可以使用日志,建议使用Log4j

lass Teacher {
private int id;
private String name;
//一个老师拥有多个学生
private List students;
}

按照结果嵌套处理






    
    
    
    
        
        
        
    

小结
关联-association【多对一】
集合-collection【一对多】
javaType & ofType
javaType 用来指定实体类中属性的类型
ofType 用来指定映射到List或者集合中的pojo类型,泛型中的约束类型!
注意点:

保证SQL的可读性,尽量保证通俗易懂
注意一对多和多对一中,属性名和字段的问题!
如果问题不好排查错误,可以使用日志,建议使用Log4j

你可能感兴趣的:(教学笔记,mybatis,java,mysql)