吴旭华 发表于 2024-6-2 13:43:06

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

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

@
目次

[*]1. MyBatis中的接口代理机制及其利用
[*]2. 实操

[*]2.1 准备工作
[*]2.2 insert 增长操作
[*]2.3 delete 删除操作
[*]2.4 update 修改操作
[*]2.5 select 查询一条记录操作
[*]2.6 select 查询多条记录操作

[*]3. 总结:
[*]4. 最后:

MyBatis 中的接口代理类机制,MyBatis 框架中利用了动态代理的设计模式,让我们可以不消写,对应XxxMapper.java 接口的实现类,而是通过动态代理的方式,让MyBatis 自动为我们生成对应实现了该 XxxMapper.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接口中的方法                // 获取到 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)接口的全限定名称一致
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737833-409622271.png

[*]对应的接口上的方法名,id 必须 和 dao(mapper) 接口中方法名一致。
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737710-1710062031.png

[*]利用的是 POJO 属性类赋值的话,#{} 的括号中的值,必须是 POJO类当中的属性名,比如这里我们用的是 Car ,则#{}括号中的值,则必须是 Car 的属性名。同时 #{} 括号中肯定要有值(就算只有一个参数,也要有值(任意写都要有值),才行,否则编译无法通过)
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737916-516335654.png
2. 实操

下面我们利用 MyBatis 的接口代理机制,对数据库进行CRUD,(增编削查)的操作。
2.1 准备工作

数据表结构的设计,数据表名为:t_car
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737736-782609782.png
t_car 表中的数据信息:
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737773-1645039192.png
在pom.xml 文件当中设置相关的依靠的 jar 包如下:
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737814-1631998774.png
<?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>
      
      <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.10</version>
      </dependency>

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

      
      <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.11</version>
      </dependency>
    </dependencies>

</project>设置 logback 的设置文件,用于打印显示,我们的日志信息,方便我们查看我们的运行过程,效果。
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737834-284805971.png
<?xml version="1.0" encoding="UTF-8"?>

<configuration debug="false">
   
    <appender name="STDOUT" >
      <encoder >
            
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
      </encoder>
    </appender>

   
    <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"/>

   
    <root level="DEBUG">
      <appender-ref ref="STDOUT"/>
      <appender-ref ref="FILE"/>
    </root>

</configuration>设置 MyBatis 的焦点设置文件,
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737808-1286665326.png
<?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 name="com.rainbowsea.mybatis.pojo"/>
    </typeAliases>
    <environments default="mybatis">

      <environment id="mybatis">
            
            <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>
      
      <mapper resource="CarMapper.xml"></mapper>
    </mappers>
</configuration>对照 t_car 创建的ORM 映射的 Car 类
注意:在MyBatis 当中对应的ORM ,一般在框架里对应的 Bean实体类,肯定要实现该 set 和 get 方法以及无参数构造方法,无法框架无法利用反射机制,进行操作 。
发起用包装类,如许可以防止 Null的问题,由于(简单类型 int num = null ,是不可以赋值为 null)的编译无法通过
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737714-935359148.png
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(增编削查)操作的接口/实现类。
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737905-804342749.png
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( ) 抽象方法。
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737794-2104428117.png
public interface CarMapper {


    /**
   * 新增 Car
   * @param car
   * @return
   */
    int insert(Car car);
}对应 CarMapper.xml SQL语句映射文件,上编写 insert 插入的 SQL语句。
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737788-340828268.png
<?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">


<mapper namespace="com.rainbowsea.mybatis.mapper.CarMapper">

   
    <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() 关闭资源
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737788-826432599.png
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();


    }
}https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737833-953759252.png
2.3 delete 删除操作

根据 id 删除一条记录,删除id为 124的一条记录。
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737885-1213333178.png
对应 CarMapper 接口中的 deleteById( Long id) 抽象方法。
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737757-2093906334.png
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) 接口中方法名一致。
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737915-1437440146.png
<?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">


<mapper namespace="com.rainbowsea.mybatis.mapper.CarMapper">



    <delete id="deleteById" >
      delete from t_car where id=#{id}
    </delete>




</mapper>Java当中编程运行程序:
注意:由于是对数据库进行了修改,所以须要 commit() 提交给数据库,以及 close() 关闭资源
删除id为 124的一条记录。
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737878-1746009471.png
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);

    }
}https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737877-1052170752.png
2.4 update 修改操作

根据 id 修改记录信息。
将 id 为 128的 brand 改为小米su7, guide_price 改为 21.00 , 时间改为 2024-03-28
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737733-1164101852.png
对应 CarMapper 接口中的 update( ) 抽象方法。
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737884-1930121357.png
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) 接口中方法名一致。
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737778-1558612266.png
<?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">


<mapper namespace="com.rainbowsea.mybatis.mapper.CarMapper">


   
    <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
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737877-244120718.png
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737742-1550059357.png
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 的一条记录。
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737786-1966894373.png
对应 CarMapper 接口中的 selectById ( Long id) 抽象方法。
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737801-961463541.png
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) 接口中方法名一致。
须要注意的是:查询是会返回效果集的,所以我们须要在查询标签当中,通过 resultType 属性指定返回的类型(如果没有效别名机制的话,要用全限定类名(带包名的)) 。
同时由于我们的数据表的字段的定名方式是下划线 ,部分数据表的字段名与我们设置的 ORM 映射的POJO类的属性名不一致,须要将他们二者的名字保持一致,所以我们须要利用 AS 定义别名,否则无法将对应数据表中的值,赋值到 对应的 POJO的类当中(这里是 Car 类当中)
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737801-231367663.png
<?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">


<mapper namespace="com.rainbowsea.mybatis.mapper.CarMapper">


   
    <select id="selectById" resultType="com.rainbowsea.mybatis.pojo.Car">
      select id,
               car_num      as carNum,
               brand,
               guide_priceas guidePrice,
               produce_time as produceTime,
               car_type   as carType
      from t_car
      where id = #{id}
    </select>



</mapper>Java当中编程运行程序:
注意:由于我们仅仅是查询数据表中的信息,不涉及到对数据表的修改,删除操作,所以无需提交数据库commit,只要 close() 关闭资源就可以了
查询 id 为 130 的一条记录。
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737788-1582078105.png
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737761-735430155.png
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 数据表中的全部信息。
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737755-1503134012.png
对应 CarMapper 接口中的 selectAll( Long id) 抽象方法。返回的是一个List 聚集
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737748-1808970461.png
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) 接口中方法名一致。
须要注意的是:查询是会返回效果集的,所以我们须要在查询标签当中,通过 resultType 属性指定返回的类型(如果没有效别名机制的话,要用全限定类名(带包名的)) 。
同时由于我们的数据表的字段的定名方式是下划线 ,部分数据表的字段名与我们设置的 ORM 映射的POJO类的属性名不一致,须要将他们二者的名字保持一致,所以我们须要利用 AS 定义别名,否则无法将对应数据表中的值,赋值到 对应的 POJO的类当中(这里是 Car 类当中)
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737801-1962049622.png
<?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">


<mapper namespace="com.rainbowsea.mybatis.mapper.CarMapper">


   
    <select id="selectAll" resultType="com.rainbowsea.mybatis.pojo.Car">
      select id,
               car_num      as carNum,
               brand,
               guide_priceas guidePrice,
               produce_time as produceTime,
               car_type   as carType
      from t_car
    </select>

</mapper>Java当中编程运行程序:
注意:由于我们仅仅是查询数据表中的信息,不涉及到对数据表的修改,删除操作,所以无需提交数据库commit,只要 close() 关闭资源就可以了
查询 t_car 数据表中的全部记录。
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737916-340198630.png
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737755-1325004860.png
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. 总结:


[*]
                // 获取到 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) 接口中方法名一致。

[*]注意:由于是对数据库进行了修改,删除,改动了,所以须要 commit() 提交给数据库,以及 close() 关闭资源
[*]须要注意的是:查询是会返回效果集的,所以我们须要在查询标签当中,通过 resultType 属性指定返回的类型(如果没有效别名机制的话,要用全限定类名(带包名的)) 。
同时由于我们的数据表的字段的定名方式是下划线 ,部分数据表的字段名与我们设置的 ORM 映射的POJO类的属性名不一致,须要将他们二者的名字保持一致,所以我们须要利用 AS 定义别名,否则无法将对应数据表中的值,赋值到 对应的 POJO的类当中(这里是 Car 类当中)
[*]注意:由于我们仅仅是查询数据表中的信息,不涉及到对数据表的修改,删除操作,所以无需提交数据库commit,只要 close() 关闭资源就可以了。
[*]如果只有一个参数须要传的话,#{} 括号中的值,可以任意写(#{}括号的值不能空着,否则不编译无法通过),但最好见名知意。
4. 最后:

“在这个最后的篇章中,我要表达我对每一位读者的感激之情。你们的关注和回复是我创作的动力源泉,我从你们身上吸取了无尽的灵感与勇气。我会将你们的鼓励留在心底,继续在其他的范畴奋斗。感谢你们,我们总会在某个时刻再次相遇。”
https://img2024.cnblogs.com/blog/3084824/202406/3084824-20240602143737917-1626020956.gif

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: MyBatis中的接口代理机制及其利用