MyBatis中的接口代理机制及其使用

1. MyBatis中的接口代理机制及其使用

@[toc]


MyBatis 中的接口代理类机制,MyBatis 框架中使用了动态代理的设计模式,让我们可以不用写,对应XxxMapper.java 接口的实现类,而是通过动态代理的方式,让MyBatis 自动为我们生成对应实现了该 XxxMapper.java接口的实现类,这个动态代理实现的类,我们可以直接使用。

核心代码:

java 复制代码
 		// 获取到 SqlSessionFactoryBuilder
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        // 获取到SqlSessionFactory 对象
        // SQlsessionFactory对象,一个SqlSessionFactory对应一个 environment, 一个environment通常是一个数据库
        SqlSessionFactory sessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml"), "mybatis");
        // 获取到 SalSession 会话,一次会话一个
        SqlSession sqlSession = sessionFactory.openSession();
        Car car = new Car(null, "999", "奥迪", 3.0, "2000-10-10", "新能源");
        // 面向接口编程,获取接口的代理对象,也就是接口的实现类,实现类该接口中的方法
		// 需要注意的是参数的 Xxxmapper.class 和 返回值是保持一致的。
        XxxMapper mapper = sqlSession.getMapper(XxxMapper.class);
		mapper.xxx(); // 执行的是该XxxMapper接口中的方法
java 复制代码
		// 获取到 SalSession 会话,一次会话一个
        SqlSession sqlSession = sessionFactory.openSession();
        Car car = new Car(null, "999", "奥迪", 3.0, "2000-10-10", "新能源");
        // 面向接口编程,获取接口的代理对象,也就是接口的实现类,实现类该接口中的方法
		// 需要注意的是参数的 Xxxmapper.class 和 返回值是保持一致的。
        XxxMapper mapper = sqlSession.getMapper(XxxMapper.class);
		mapper.xxx(); // 执行的是该XxxMapper接口中的方法

使用以上代码的前提是:XxxMapper.xml 文件中的 namespace 必须和 dao(mapper)接口的全限定名称一致,id 必须和 dao(mapper) 接口中方法名一致。

比如:我们这里的是:

CarMappe.xml

  • XxxMapper.xml 文件中的 namespace 必须和 dao(mapper)接口的全限定名称一致
  • 对应的接口上的方法名,id 必须dao(mapper) 接口中方法名一致。
  • 使用的是 POJO 属性类赋值的话,#{} 的括号中的值,必须是 POJO类当中的属性名,比如这里我们用的是 Car ,则#{}括号中的值,则必须是 Car 的属性名。同时 #{} 括号中一定要有值(就算只有一个参数,也要有值(随便写都要有值),才行,不然编译无法通过)

2. 实操

下面我们使用 MyBatis 的接口代理机制,对数据库进行CRUD,(增删改查)的操作。

2.1 准备工作

数据表结构的设计,数据表名为:t_car

t_car 表中的数据信息:

pom.xml 文件当中配置相关的依赖的 jar 包如下:

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.rainbowsea</groupId>
    <artifactId>mybatis-005-crud-blog</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
    </properties>

    <dependencies>
        <!--        mybatis 的依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.10</version>
        </dependency>

        <!--        mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.30</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>

        <!--        引入 logback的依赖,这个日志框架实现了slf4j 规范-->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.11</version>
        </dependency>
    </dependencies>

</project>

配置 logback 的配置文件,用于打印显示,我们的日志信息,方便我们查看我们的运行过程,效果。

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>

<configuration debug="false">
    <!-- 控制台输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        </encoder>
    </appender>

    <!--mybatis log configure-->
    <logger name="com.apache.ibatis" level="TRACE"/>
    <logger name="java.sql.Connection" level="DEBUG"/>
    <logger name="java.sql.Statement" level="DEBUG"/>
    <logger name="java.sql.PreparedStatement" level="DEBUG"/>

    <!-- 日志输出级别,logback日志级别包括五个:TRACE < DEBUG < INFO < WARN < ERROR -->
    <root level="DEBUG">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="FILE"/>
    </root>

</configuration>

配置 MyBatis 的核心配置文件,

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>
    <!--    起别名-->
    <typeAliases>
        <!--  使用 <package>	还可以将这个包下的所有的类的全部自动起别名,别名就是简名,不区分大小写 -->
        <package name="com.rainbowsea.mybatis.pojo"/>
    </typeAliases>
    <environments default="mybatis">

        <environment id="mybatis">
            <!--            MANAGED 没有用第三框架管理的话,都是会被提交的,没有事务上的管理了 -->
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="MySQL123"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!-- 这里也是可以使用 package 包名扫描,但是同样的:对应接口路径要一致,接口名一致-->
        <mapper resource="CarMapper.xml"></mapper>
    </mappers>
</configuration>

对照 t_car 创建的ORM 映射的 Car 类

注意:在MyBatis 当中对应的ORM ,一般在框架里对应的 Bean实体类,一定要实现该 set 和 get 方法以及无参数构造方法,无法框架无法使用反射机制,进行操作

建议用包装类,这样可以防止 Null的问题,因为(简单类型 int num = null ,是不可以赋值为 null)的编译无法通过

java 复制代码
package com.rainbowsea.mybatis.pojo;

public class Car {
    // 数据库表当中的字段应该和pojo类的属性一一对应
    // 建议使用包装类,这样可以防止null的问题
    private Long id;
    private String carNum;
    private String brand;
    private Double guidePrice;
    private String produceTime;
    private String carType;

    public Car() {
    }

    public Car(Long id, String carNum, String brand, Double guidePrice, String produceTime, String carType) {
        this.id = id;
        this.carNum = carNum;
        this.brand = brand;
        this.guidePrice = guidePrice;
        this.produceTime = produceTime;
        this.carType = carType;
    }

    @Override
    public String toString() {
        return "Car{" +
                "id=" + id +
                ", carNum='" + carNum + '\'' +
                ", brand='" + brand + '\'' +
                ", guidePrice=" + guidePrice +
                ", produceTime='" + produceTime + '\'' +
                ", catType='" + carType + '\'' +
                '}';
    }

    public Long getId() {
        return id;
    }

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

    public String getCarNum() {
        return carNum;
    }

    public void setCarNum(String carNum) {
        this.carNum = carNum;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public Double getGuidePrice() {
        return guidePrice;
    }

    public void setGuidePrice(Double guidePrice) {
        this.guidePrice = guidePrice;
    }

    public String getProduceTime() {
        return produceTime;
    }

    public void setProduceTime(String produceTime) {
        this.produceTime = produceTime;
    }

    public String getcarType() {
        return carType;
    }

    public void setcarType(String catType) {
        this.carType = catType;
    }
}

对应操作实现CRUD(增删改查)的接口(这里是:CarMapper接口),在MyBtis 当中 ,关于 CRUD(增删改查)操作的接口/实现类,都是 mapper 结尾的作为持久层,而在 MVC的三层架构中,则是以 dao 为后缀作为CRUD(增删改查)操作的接口/实现类。

java 复制代码
package com.rainbowsea.mybatis.mapper;

import com.rainbowsea.mybatis.pojo.Car;

import java.util.List;

public interface CarMapper {


    /**
     * 新增 Car
     * @param car
     * @return
     */
    int insert(Car car);


    /**
     * 根据id 删除 Car
     * @param id
     * @return
     */
    int deleteById(Long id);


    /**
     * 修改汽车信息
     * @param car
     * @return
     */
    int update(Car car);


    /**
     * 根据id查询汽车信息
     * @param id
     * @return
     */
    Car selectById(Long id);


    /**
     * 获取所有的汽车信息
     * @return
     */
    List<Car> selectAll();
}

2.2 insert 增加操作

对应 CarMapper 接口中的 insert( ) 抽象方法。

java 复制代码
public interface CarMapper {


    /**
     * 新增 Car
     * @param car
     * @return
     */
    int insert(Car car);
}

对应 CarMapper.xml SQL语句映射文件,上编写 insert 插入的 SQL语句。

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 namespace="com.rainbowsea.mybatis.mapper.CarMapper">

    <!--	id 要是 namespace 对应接口上的方法名: -->
    <insert id="insert" parameterType="com.rainbowsea.mybatis.pojo.Car">
        insert into t_car values(null,#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType})
    </insert>

</mapper>

Java当中编程运行程序:

注意:因为是对数据库进行了修改,所以需要 commit() 提交给数据库,以及 close() 关闭资源

java 复制代码
package com.rainbowsea.mybatis.test;

import com.rainbowsea.mybatis.mapper.CarMapper;
import com.rainbowsea.mybatis.pojo.Car;
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 org.junit.Test;

import java.io.IOException;

public class CarMapperTest {

    @Test
    public void testInsert() throws IOException {
        // 获取到 SqlSessionFactoryBuilder
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        // 获取到SqlSessionFactory 对象
        // SQlsessionFactory对象,一个SqlSessionFactory对应一个 environment, 一个environment通常是一个数据库
        SqlSessionFactory sessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml"), "mybatis");
        // 获取到 SalSession 会话,一次会话一个
        SqlSession sqlSession = sessionFactory.openSession();
        Car car = new Car(null, "999", "奥迪", 3.0, "2000-10-10", "新能源");
        // 面向接口编程,获取接口的代理对象,也就是接口的实现类,实现类该接口中的方法
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
        int count = mapper.insert(car);

        System.out.println(count);
        sqlSession.commit();
        sqlSession.close();


    }
}

2.3 delete 删除操作

根据 id 删除一条记录,删除id为 124的一条记录。

对应 CarMapper 接口中的 deleteById( Long id) 抽象方法。

java 复制代码
public interface CarMapper {


    /**
     * 新增 Car
     * @param car
     * @return
     */
    int insert(Car car);


    /**
     * 根据id 删除 Car
     * @param id
     * @return
     */
    int deleteById(Long id);
}

对应 CarMapper.xml SQL语句映射文件,上编写 delete 删除的 SQL语句。

使用以上代码的前提是:XxxMapper.xml 文件中的 namespace 必须和 dao(mapper)接口的全限定名称一致,id 必须和 dao(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 namespace="com.rainbowsea.mybatis.mapper.CarMapper">


<!--    如果只有一个参数需要传的话,#{} 括号中的值,可以随便写,但最后见名知意-->
    <delete id="deleteById" >
        delete from t_car where id=#{id}
    </delete>




</mapper>

Java当中编程运行程序:

注意:因为是对数据库进行了修改,所以需要 commit() 提交给数据库,以及 close() 关闭资源

删除id为 124的一条记录。

java 复制代码
import org.junit.Test;

import java.io.IOException;

public class CarMapperTest {

    @Test
    public void testDeleteById() throws IOException {
        // 获取到 SqlSessionFactoryBuilder
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        // 获取到SqlSessionFactory 对象
        // SQlsessionFactory对象,一个SqlSessionFactory对应一个 environment, 一个environment通常是一个数据库
        SqlSessionFactory sessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml"), "mybatis");
        // 获取到 SalSession 会话,一次会话一个
        SqlSession sqlSession = sessionFactory.openSession();
        // 面向接口编程,获取接口的代理对象,也就是接口的实现类,实现类该接口中的方法
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);

        // 删除id为 124的一条记录。
        int count = mapper.deleteById(124L);
        sqlSession.commit(); // 提交给数据库
        sqlSession.close(); // 关闭资源
        System.out.println(count);

    }
}

2.4 update 修改操作

根据 id 修改记录信息。

将 id 为 128的 brand 改为小米su7, guide_price 改为 21.00 , 时间改为 2024-03-28

对应 CarMapper 接口中的 update( ) 抽象方法。

java 复制代码
package com.rainbowsea.mybatis.mapper;

import com.rainbowsea.mybatis.pojo.Car;

import java.util.List;

public interface CarMapper {


    /**
     * 修改汽车信息
     * @param car
     * @return
     */
    int update(Car car);

}

对应 CarMapper.xml SQL语句映射文件,上编写 update 修改的 SQL语句。

使用以上代码的前提是:XxxMapper.xml 文件中的 namespace 必须和 dao(mapper)接口的全限定名称一致,id 必须和 dao(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 namespace="com.rainbowsea.mybatis.mapper.CarMapper">


    <!--	id 要是 namespace 对应接口上的方法名: -->
    <update id="update">
        update t_car
        set car_num=#{carNum},
            brand=#{brand},
            guide_price=#{guidePrice},
            produce_time=#{produceTime},
            car_type=#{carType}
        where id = #{id}
    </update>


</mapper>

Java当中编程运行程序:

注意:因为是对数据库进行了修改,所以需要 commit() 提交给数据库,以及 close() 关闭资源

将 id 为 128的 brand 改为小米su7, guide_price 改为 21.00 , 时间改为 2024-03-28

java 复制代码
import com.rainbowsea.mybatis.mapper.CarMapper;
import com.rainbowsea.mybatis.pojo.Car;
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 org.junit.Test;

import java.io.IOException;

public class CarMapperTest {

    @Test
    public void testUpdate() throws IOException {
        // 获取到 SqlSessionFactoryBuilder
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        // 获取到SqlSessionFactory 对象
        // SQlsessionFactory对象,一个SqlSessionFactory对应一个 environment, 一个environment通常是一个数据库
        SqlSessionFactory sessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml"), "mybatis");
        // 获取到 SalSession 会话,一次会话一个
        SqlSession sqlSession = sessionFactory.openSession();
        Car car = new Car(128L, "999", "小米su7", 21.0, "2022-03-28", "新能源");
        // 面向接口编程,获取接口的代理对象,也就是接口的实现类,实现类该接口中的方法
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
        int count = mapper.update(car);
        sqlSession.commit(); // 提交给数据库
        sqlSession.close();



    }
}

2.5 select 查询一条记录操作

根据 id 查询一条记录。

查询 id 为 130 的一条记录。

对应 CarMapper 接口中的 selectById ( Long id) 抽象方法。

java 复制代码
package com.rainbowsea.mybatis.mapper;

import com.rainbowsea.mybatis.pojo.Car;

import java.util.List;

public interface CarMapper {



    /**
     * 根据id查询汽车信息
     * @param id
     * @return
     */
    Car selectById(Long id);

}

对应 CarMapper.xml SQL语句映射文件,上编写 select 查询 的 SQL语句。

使用以上代码的前提是:XxxMapper.xml 文件中的 namespace 必须和 dao(mapper)接口的全限定名称一致,id 必须和 dao(mapper) 接口中方法名一致。

需要注意的是:查询是会返回结果集的,所以我们需要在 <select> 查询标签当中,通过 resultType 属性指定返回的类型(如果没有用别名机制的话,要用全限定类名(带包名的))

同时由于我们的数据表的字段的命名方式是下划线 ,部分数据表的字段名与我们设置的 ORM 映射的POJO类的属性名不一致,需要将他们二者的名字保持一致,所以我们需要使用 AS 定义别名,不然无法将对应数据表中的值,赋值到 对应的 POJO的类当中(这里是 Car 类当中)

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 namespace="com.rainbowsea.mybatis.mapper.CarMapper">


    <!--	id 要是 namespace 对应接口上的方法名: -->
    <select id="selectById" resultType="com.rainbowsea.mybatis.pojo.Car">
        select id,
               car_num      as carNum,
               brand,
               guide_price  as guidePrice,
               produce_time as produceTime,
               car_type     as carType
        from t_car
        where id = #{id}
    </select>



</mapper>

Java当中编程运行程序:

注意:因为我们仅仅是查询数据表中的信息,不涉及到对数据表的修改,删除操作,所以无需提交数据库commit,只要 close() 关闭资源就可以了

查询 id 为 130 的一条记录。

java 复制代码
import com.rainbowsea.mybatis.mapper.CarMapper;
import com.rainbowsea.mybatis.pojo.Car;
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 org.junit.Test;

import java.io.IOException;

public class CarMapperTest {

    @Test
    public void testSelectById() throws IOException {
        // 获取到 SqlSessionFactoryBuilder
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        // 获取到SqlSessionFactory 对象
        // SQlsessionFactory对象,一个SqlSessionFactory对应一个 environment, 一个environment通常是一个数据库
        SqlSessionFactory sessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml"), "mybatis");
        // 获取到 SalSession 会话,一次会话一个
        SqlSession sqlSession = sessionFactory.openSession();
        // 面向接口编程,获取接口的代理对象,也就是接口的实现类,实现类该接口中的方法
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
        Car car = mapper.selectById(130L);
        System.out.println(car);
        sqlSession.close();
    }
}

2.6 select 查询多条记录操作

查询t_car 数据表中的所有信息。

对应 CarMapper 接口中的 selectAll( Long id) 抽象方法。返回的是一个List 集合

java 复制代码
package com.rainbowsea.mybatis.mapper;

import com.rainbowsea.mybatis.pojo.Car;

import java.util.List;

public interface CarMapper {

  

    /**
     * 获取所有的汽车信息
     * @return
     */
    List<Car> selectAll();
}

对应 CarMapper.xml SQL语句映射文件,上编写 select 查询 的 SQL语句。

使用以上代码的前提是:XxxMapper.xml 文件中的 namespace 必须和 dao(mapper)接口的全限定名称一致,id 必须和 dao(mapper) 接口中方法名一致。

需要注意的是:查询是会返回结果集的,所以我们需要在 <select> 查询标签当中,通过 resultType 属性指定返回的类型(如果没有用别名机制的话,要用全限定类名(带包名的))

同时由于我们的数据表的字段的命名方式是下划线 ,部分数据表的字段名与我们设置的 ORM 映射的POJO类的属性名不一致,需要将他们二者的名字保持一致,所以我们需要使用 AS 定义别名,不然无法将对应数据表中的值,赋值到 对应的 POJO的类当中(这里是 Car 类当中)

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 namespace="com.rainbowsea.mybatis.mapper.CarMapper">


    <!--	id 要是 namespace 对应接口上的方法名: -->
    <select id="selectAll" resultType="com.rainbowsea.mybatis.pojo.Car">
        select id,
               car_num      as carNum,
               brand,
               guide_price  as guidePrice,
               produce_time as produceTime,
               car_type     as carType
        from t_car
    </select>

</mapper>

Java当中编程运行程序:

注意:因为我们仅仅是查询数据表中的信息,不涉及到对数据表的修改,删除操作,所以无需提交数据库commit,只要 close() 关闭资源就可以了

查询 t_car 数据表中的所有记录。

java 复制代码
import com.rainbowsea.mybatis.mapper.CarMapper;
import com.rainbowsea.mybatis.pojo.Car;
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 org.junit.Test;

import java.io.IOException;
import java.util.List;

public class CarMapperTest {
    @Test
    public void testSelectAll() throws IOException {
        // 获取到 SqlSessionFactoryBuilder
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        // 获取到SqlSessionFactory 对象
        // SQlsessionFactory对象,一个SqlSessionFactory对应一个 environment, 一个environment通常是一个数据库
        SqlSessionFactory sessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml"), "mybatis");
        // 获取到 SalSession 会话,一次会话一个
        SqlSession sqlSession = sessionFactory.openSession();
        // 面向接口编程,获取接口的代理对象,也就是接口的实现类,实现类该接口中的方法
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
        List<Car> cars = mapper.selectAll();
        cars.forEach(car -> {
            System.out.println(car);
        });

        sqlSession.close();
    }
}

3. 总结:

java 复制代码
		// 获取到 SalSession 会话,一次会话一个
        SqlSession sqlSession = sessionFactory.openSession();
        Car car = new Car(null, "999", "奥迪", 3.0, "2000-10-10", "新能源");
        // 面向接口编程,获取接口的代理对象,也就是接口的实现类,实现类该接口中的方法
		// 需要注意的是参数的 Xxxmapper.class 和 返回值是保持一致的。
        XxxMapper mapper = sqlSession.getMapper(XxxMapper.class);
		mapper.xxx(); // 执行的是该XxxMapper接口中的方法

使用以上代码的前提是:XxxMapper.xml 文件中的 namespace 必须和 dao(mapper)接口的全限定名称一致,id 必须和 dao(mapper) 接口中方法名一致。

  1. 注意:因为是对数据库进行了修改,删除,改动了,所以需要 commit() 提交给数据库,以及 close() 关闭资源

  2. 需要注意的是:查询是会返回结果集的,所以我们需要在 <select> 查询标签当中,通过 resultType 属性指定返回的类型(如果没有用别名机制的话,要用全限定类名(带包名的))

    同时由于我们的数据表的字段的命名方式是下划线 ,部分数据表的字段名与我们设置的 ORM 映射的POJO类的属性名不一致,需要将他们二者的名字保持一致,所以我们需要使用 AS 定义别名,不然无法将对应数据表中的值,赋值到 对应的 POJO的类当中(这里是 Car 类当中)

  3. 注意:因为我们仅仅是查询数据表中的信息,不涉及到对数据表的修改,删除操作,所以无需提交数据库commit,只要 close() 关闭资源就可以了。

  4. 如果只有一个参数需要传的话,#{} 括号中的值,可以随便写(#{}括号的值不能空着,不然不编译无法通过),但最好见名知意。

4. 最后:

"在这个最后的篇章中,我要表达我对每一位读者的感激之情。你们的关注和回复是我创作的动力源泉,我从你们身上吸取了无尽的灵感与勇气。我会将你们的鼓励留在心底,继续在其他的领域奋斗。感谢你们,我们总会在某个时刻再次相遇。"

相关推荐
小小寂寞的城3 分钟前
JAVA策略模式demo【设计模式系列】
java·设计模式·策略模式
志辉AI编程18 分钟前
别人还在入门,你已经精通!Claude Code进阶必备14招
后端·ai编程
JAVA学习通21 分钟前
图书管理系统(完结版)
java·开发语言
代码老y25 分钟前
Spring Boot项目中大文件上传的高级实践与性能优化
spring boot·后端·性能优化
abigalexy27 分钟前
深入Java锁机制
java
paishishaba28 分钟前
处理Web请求路径参数
java·开发语言·后端
神仙别闹30 分钟前
基于Java+MySQL实现(Web)可扩展的程序在线评测系统
java·前端·mysql
程序无bug31 分钟前
Java中的8中基本数据类型转换
java·后端
雨落倾城夏未凉35 分钟前
8.Qt文件操作
c++·后端·qt
51738 分钟前
Django中序列化与反序列化
后端·python·django