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

<?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=绑定一个对应的Dao/Mapper接口-->
<mapper namespace="Mybait.dao.IuserDao">

    <!--select查询语句  id是方法名 -->
<select id="getUserList" resultType="Mybait.pojo.User">
    select * from User
    </select>
</mapper>

数据库配置文件

<?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>

    <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&amp;useUnicode=true&amp;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 , 来防止我们资源导出失败的问题-->
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>
    </build>

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

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

<!--配置时区 serverTimezone=GMT-->
<property name="url" value="jdbc:mysql://localhost:3306/smbms?useSSL=true&amp;useUnicode=true&amp;serverTimezone=GMT&amp;characterEncoding=UTF-8"/>

增删改查

  • 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);
}
<?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=绑定一个对应的Dao/Mapper接口-->
<mapper namespace="yu.dao.UserDao">

    <!--select查询语句  id是方法名 -->
    <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>
<!--    已经在sql写了类的别名 所以说直接User-->
    <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<String,Object> map);

配置

<insert id="addUser01" parameterType="map">
    insert into user (id, username) value (#{id},#{username})

</insert>

测试类

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

模糊查询

接口

List<User>  getUserByjn(User U);

配置

</select>  <select id="getUserByjn" resultType="yu.po.User">
    select * from user where address like "%"#{address}"%"

</select>

配置解析

核心配置文件
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&amp;useUnicode=true&amp;serverTimezone=GMT&amp;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&amp;useUnicode=true&amp;serverTimezone=GMT&amp;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<User> getUserList();
    User getUserById(int id);
    List<User>  getUserByjn(User U);
    int addUser(User u);
    int addUser01(Map<String,Object> map);
    int updateUser(User u);
    int deleteUser(User user);
}
<typeAliases>
    <typeAlias type="yu.po.User" alias="666"></typeAlias>
    <package name="yu.po"/>
</typeAliases>

配置environments

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

映射器

方式一resource

    <mappers>
        <mapper resource="yu/dao/UserDao.xml"/>
       
    </mappers>

方式二class

    <mappers>

        <mapper class="yu.dao.UserDao"></mapper>
    </mappers>

注意点:

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

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

    <mappers>
<!--        <mapper resource="yu/dao/UserDao.xml"/>-->
<!--        <mapper class="yu.dao.UserDao"></mapper>-->
        <package name="yu.dao"></package>
    </mappers>

生命周期和作用域

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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}

解决方法 起别名

    <select id="getUserList" resultType="yu.po.User">

 select id,username,birthday,address ,sex as sexx
 from user

    </select>

resultMap

<!--column数据库中的字段,property实体类中的属性 666是我的类别名-->

    <resultMap id="rmap" type="666">
        <id column="id" property="id"></id>
        <result column="username" property="username"></result>
        <result column="birthday" property="birthday"></result>
        <result column="address" property="address"></result>
        <result column="sex" property="sexx"></result>
    </resultMap>



  <select id="getUserById" parameterType="int" resultType="yu.po.User" resultMap="rmap"><--resultMap 是定位到 resultMap l-->
        select *
        from user
        where id = #{id}
    </select> 
  • 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<Integer> 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核心配置文件中,配置我们的日志!

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

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

Log4j

什么是Log4j?

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

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

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

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为日志的实现!

<settings>
    <setting name="logImpl" value="LOG4J"/>
</settings>
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]*

接口

//分页
List<User >limit(Map<String,Object> map);

xml

<select id="limit" resultType="666" parameterType="map">
    select *
    from user limit #{a},#{b}

</select>

测试

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

}

RowBounds分页

public void RowBound(){
    RowBounds rowBounds = new RowBounds(0,2);
//    类加方法名
    List<User> 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<User> 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<User> getUser();


}

增删改查

public interface zhujUser0 {
    @Select("select * from user")
    List<User> getUser();
    @Select("select account.*,user.* from account left join user on account.uid=user.id")
    List<Account> vs2();
    @Select("select user.*,account.* from user left join account on account.uid=user.id")
    List<User> 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<Account> accountList;

    public List<Account> getAccountList() {
        return accountList;
    }

    public void setAccountList(List<Account> 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接口或者文件!【方式很多,随心选】
测试查询是否能够成功!

按照结果嵌套处理
    <!--按照结果嵌套处理    -->
    <select id="getStudent2" resultMap="StudentTeacher2">
        select s.id sid,s.name sname,t.name tname
        from mybatis.student s,mybatis.teacher t
        where s.tid = t.id
    </select>
<resultMap id="StudentTeacher2" type="Student">
    <result property="id" column="sid"/>
    <result property="name" column="sname"/>
    <association property="teacher" javaType="Teacher">
        <result property="name" column="tname"/>
    </association>
</resultMap>

按照查询嵌套处理

    <!--
      思路:
          1.查询所有的学生信息
          2.根据查询出来的学生的tid,寻找对应的老师! 子查询-->
    <select id="getStudent" resultMap="StudentTeacher">
        select * from mybatis.student
    </select>
<resultMap id="StudentTeacher" type="Student">
    <result property="id" column="id"/>
    <result property="name" column="name"/>
    <!--  复杂的属性,我们需要单独处理 对象:association 集合:collection      -->
    <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>

<select id="getTeacher" resultType="Teacher">
    select * from mybatis.teacher where id = #{id}
</select>

回顾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<Student> students;
}

按照结果嵌套处理

<select id="getTeacher" resultMap="TeacherStudent">
        SELECT  s.id sid,s.name sname,t.name tname,t.id,tid
        from student s,teacher t
        where s.tid = t.id and t.id = #{tid}
</select>



<resultMap id="TeacherStudent" type="Teacher">
    <result property="id" column="tid"/>
    <result property="name" column="tname"/>
    <!--  复杂的属性,我们需要单独处理 对象:association 集合:collection
         javaType="" 指定属性的类型!
         集合中的泛型信息,我们使用ofType获取
         -->
    <collection property="students" ofType="Student">
        <result property="id" column="sid"/>
        <result property="name" column="sname"/>
        <result property="tid" column="tid"/>
    </collection>
</resultMap>

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

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

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

按照结果嵌套处理

<select id="getTeacher" resultMap="TeacherStudent">
        SELECT  s.id sid,s.name sname,t.name tname,t.id,tid
        from student s,teacher t
        where s.tid = t.id and t.id = #{tid}
</select>



<resultMap id="TeacherStudent" type="Teacher">
    <result property="id" column="tid"/>
    <result property="name" column="tname"/>
    <!--  复杂的属性,我们需要单独处理 对象:association 集合:collection
         javaType="" 指定属性的类型!
         集合中的泛型信息,我们使用ofType获取
         -->
    <collection property="students" ofType="Student">
        <result property="id" column="sid"/>
        <result property="name" column="sname"/>
        <result property="tid" column="tid"/>
    </collection>
</resultMap>

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值