首页 > 文章列表 > MyBatis注解CRUD与执行流程深入探究

MyBatis注解CRUD与执行流程深入探究

java
498 2023-03-17

结果映射ResultMap

引入resultMap–MyBatis中最强大的元素

数据库字段名::

实体类字段名:

public class User {

    private int id;

    private String name;

    private String password;

如上所示,当sql的字段名与实体类冲突时测试结果:

User{id=1, name='张三', password='null'}

User{id=2, name='李四', password='null'}

User{id=3, name='王五', password='null'}

解决方案一:在sql语句中为字段起别名

select id,name,pwd as password from mybatis.user;

解决方案二:结果集映射ReaultMap

<resultMap id="UserMap" type="User" >

     <result column="pwd" property="password"/>

</resultMap>

<select id="getUserList" resultMap="UserMap">

     select * from mybatis.user;

</select>

resultMap中的id对应具体的sql操作的resultMap属性,在映射时只需设置子标签result的column(sql的列、字段名)映射到实体类的名称属性property便可以成功操作

概括来讲就是:将数据库中的列映射到实体类具体的某一字段

MyBatis 会在幕后自动创建一个 ResultMap,再根据属性名来映射列到 JavaBean 的属性上 。这就是上述示例代码中,因为字段名冲突无法正确查询到password的原因

日志工厂

MyBatis的配置当中settings设置了内置的日志工厂,但需要开发人员在使用时指定具体的日志实现。

MyBatis内置日志工厂: SLF4J | LOG4J(3.5.9 起废弃) | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING

STDOUT_LOGGING在settings中配置后直接就可以运行使用,不需要额外的properties等配置文件

STDOUT_LOGGING

配置信息:

<settings>

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

</settings>

打印出来一堆日志,我们只用看下面的具体执行信息即可

-- 表示正在创建连接

Created connection 1346201722.

Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@503d687a]

-- 当前执行的sql

==>  Preparing: select * from mybatis.user;

-- 参数

==> Parameters: 

-- sql中的字段名

<==    Columns: id, name, pwd

-- 所查询到的数据 三行数据

<==        Row: 1, 张三, 123

<==        Row: 2, 李四, 234

<==        Row: 3, 王五, 345

-- 数据总数

<==      Total: 3

-- 打印结果

User{id=1, name='张三', password='123'}

User{id=2, name='李四', password='234'}

User{id=3, name='王五', password='345'}

Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@503d687a]

-- 关闭连接

Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@503d687a]

-- 将连接回收

Returned connection 1346201722 to pool.

Process finished with exit code 0

LOG4J

配置文件:

<settings>

        <setting name="logImpl" value="LOG4J"/>

    </settings>

log4j.properties

# 将等级为DEBUG的日志信息输出到控制台(console)、文件(file)两个目的地

log4j.rootLogger=DEBUG,console,file

# 输出到控制台的相关设置

log4j.appender.console=org.apache.log4j.ConsoleAppender

log4j.appender.console.Threshold=DEBUG

log4j.appender.console.Target=System.out

log4j.appender.console.Encoding=UTF-8

log4j.appender.console.layout=org.apache.log4j.PatternLayout

log4j.appender.console.layout.ConversionPattern=[%p]%d{yyyy-MM-dd HH:mm:ss} %l -  %m%n

# 输出到文件的相关设置

log4j.appender.file = org.apache.log4j.RollingFileAppender

log4j.appender.file.File = ./log/test.log

log4j.appender.file.Threshold = DEBUG

log4j.appender.file.MaxFileSize=10mb

log4j.appender.file.layout = org.apache.log4j.PatternLayout

log4j.appender.file.layout.ConversionPattern = [%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

注解开发CRUD

mybatis注解开发通常用于简单的sql执行,较复杂的sql还是需要用xml文件进行配置。

注解开发示例:

在接口中针对方法配置对应的sql注解

@Select("select * from user")

List<User> getUsers();

在mybatis-config.xml中配置

<!--  注册接口mapper  -->

<mappers>

    <mapper class="com.yuqu.dao.UserMapper"/>

</mappers>

CRUD:

// 增

@Insert("insert into user (id,name,pwd) values(#{id},#{name},#{password})")

int insertUser(User user);

// 删

@Delete("delete from user where id = #{nb}")

int deleteUser(@Param("nb") int id);

// 改

@Update("update user set name=#{name},pwd=#{password} where id = #{id}")

int updateUser(Map<String,Object> map);

// 查询全部

@Select("select id,name,pwd as password from user")

List<User> getUsers();

关于@Param注解:

基本数据类型或String类型需要加Param注解

引用类型不需要

只有一个基本数据类型可以不加,但建议加上

在sql中引用的变量名就是@Param中命名的参数

如:

@Delete("delete from user where id = #{nb}")

int deleteUser(@Param("nb") int id);

MyBatis执行流程

  • Resources加载全局配置文件–> mybatis-config.xml
String resource = "mybatis-config.xml";

InputStream inputStream = Resources.getResourceAsStream(resource);

  • 实例化SqlSessionFactoryBuilder构造器
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  • build解析配置文件流
// 以下为SqlSessionFactoryBuilder源码

XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);

可以看到,build方法将输入流、环境、属性一一解析到Cconfiguration中

  • 实例化SqlSessionFactory
  • transactionalCaches事务管理器

  • 创建executor执行器
  • 创建SqlSession实例
public static SqlSession getSqlSession(){

   return sqlSessionFactory.openSession();

}

  • 实现CRUD
  • 判断是否执行成功
  • 执行成功提交事务
  • 执行失败则跳转到事务管理器重新进行