🐳 Mybatis 入门学习

1. MyBatis是什么?

之前使用的是JDBC,其中大量的代码是重复的冗余的。只有SQL是程序员需要控制的。 MyBatis是一个半自动化的ORM框架。半自动化是相对于Hibernate而言的。 Hibernate是完全的ORM框架,但是学习成本较高,因为封装的程度太高,导致性能不佳。 因此,MyBatis是目前较好的一个选择。 什么是ORM?指的是对象和关系之间的映射。

2. MyBatis的开发步骤

1.新建数据库、三个表 (mybatis-example)

2.建POJO

java 复制代码
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Emp {
    private Integer empId ;
    private String empName ;
    private Double empSalary ;
}

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person {
    private Integer pid ;
    private String pname , address ;
}

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Tiger {
    private String tid ;
    private String tname ;
    private Integer age ;
}

3.添加依赖 (mysql , mybatis , junit , lombok)

xml 复制代码
<dependencies>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.11</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.32</version>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>5.10.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.24</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
         <version>1.2.3</version>
    </dependency>
</dependencies>

4.新建EmpMapperPersonMapperTigerMapper接口

java 复制代码
public interface EmpMapper {
    List<Emp> getEmpList();

    List<Emp> getEmpList2();

    List<Emp> getEmpList3();

}

public interface PersonMapper {

    List<Person> getPersonList();

    Person getPerson(Integer pid);
    Person getPersonByPname(String pname);

    List<Person> getPersonList2(String tableName);
}


public interface TigerMapper {
    Tiger getTiger(Integer tid);

    void addTiger(Tiger tiger);

    List<Tiger> getTigerByCondition(Integer tid , String tname , Integer age);

    List<Tiger> getTigerByCondition2(@Param("tid") Integer tid ,@Param("tname") String tname ,@Param("age") Integer age);

    List<Tiger> getTigerByCondition3(Map paramMap);

    int getTigerCount(String tname);

    Map<String,Object> getTigerInfoByTid(Integer tid);

    void addTiger2(Tiger tiger);
}

5.resources 目录下新建com.bottom.mybatis.mapper 目录,并新建三个mapper.xml文件

EmpMapper.xml

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">
<mapper namespace="com.bottom.mybatis.mapper.EmpMapper">
    <select id="getEmpList" resultType="Emp">
        select * from t_emp
    </select>

    <select id="getEmpList2" resultType="Emp">
        select emp_id as empId ,
                   emp_name as empName ,
            emp_salary from t_emp
    </select>

    <select id="getEmpList3" resultMap="EmpResultMap">
        select a ,
               b ,
               c from t_emp
    </select>

    <!-- 定义EmpResultMap这种映射关系 -->
    <resultMap id="EmpResultMap" type="Emp">
        <id property="empId" column="a"/>
        <result property="empName" column="b"/>
        <result property="empSalary" column="c"/>
    </resultMap>

</mapper>

PersonMapper.xml

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的全类名 -->
<mapper namespace="com.bottom.mybatis.mapper.PersonMapper">
    <!-- id的取值本质上是字符串,可以随便写,只要保证namespace+id是唯一的即可。但是强烈建议是方法名 -->
    <select id="getPersonList" resultType="Person">
        select * from t_person
    </select>

    <select id="getPerson" resultType="Person">
        select * from t_person where pid = #{pid}
    </select>

    <select id="getPersonByPname" resultType="Person">
        select * from t_person where pname = ${pname}
    </select>

    <select id="getPersonList2" resultType="Person">
        select * from ${tableName}
    </select>

</mapper>

TigerMapper.xml

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的全类名 -->
<mapper namespace="com.bottom.mybatis.mapper.TigerMapper">

    <!-- 当输入参数是单个的基本类型时,#{}中随便写 , 一般取值是tid(和Mapper方法中的形参名称一致)或者是'value' -->
    <select id="getTiger" resultType="Tiger">
        select * from t_tiger where tid = #{value}
    </select>

    <!--
     parameterType="Tiger"可以省略
     select表示查询,此时resultType必须要写。相反的,insert,update,delete都不需要写
     -->
    <!-- useGeneratedKeys=true 表示执行insert操作之后,返回自增长的值 -->
    <!-- keyProperty 表示 得到的自增长的值将设置给哪一个属性 -->
    <insert id="addTiger" parameterType="Tiger" useGeneratedKeys="true" keyProperty="tid">
        insert into t_tiger values(0,#{tname},#{age})
    </insert>

    <select id="getTigerByCondition" resultType="Tiger">
        select * from t_tiger
        where tid = #{param1} or tname like #{arg1} or age = #{arg2}
    </select>

    <select id="getTigerByCondition2" resultType="Tiger">
        select * from t_tiger
        where tid = #{tid} or tname like #{tname} or age = #{age}
    </select>

    <select id="getTigerByCondition3" resultType="Tiger">
        select * from t_tiger
        where tid = #{tid} or tname like #{tname} or age = #{age}
    </select>

    <select id="getTigerCount" resultType="int">
        select count(*) from t_tiger
        where tname like concat('%',#{value},'%')
    </select>

    <select id="getTigerInfoByTid" parameterType="int" resultType="map">
        select * from t_tiger where tid = #{value}
    </select>

    <insert id="addTiger2" parameterType="Tiger">
        <!-- keyProperty="tid" 查询结果集中的数据赋值给Tiger中的"tid"属性 -->
        <!-- keyColumn="abcd"  查询结果集中的列名为"abcd"这一列的值取出来作为key -->
        <selectKey keyProperty="tid" keyColumn="abcd" resultType="string" order="BEFORE">
            select UUID() as abcd , 1 , 'hello' , 'java'
        </selectKey>
        insert into t_tiger values(#{tid},#{tname},#{age})
    </insert>

</mapper>

6.新增mybatis的配置文件: (mybatis-config.xml)

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>
    <settings>
        <setting name="logImpl" value="SLF4J"/>
        <!-- 开启驼峰命名法规则 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    <typeAliases>
        <package name="com.bottom.mybatis.pojo"/>
    </typeAliases>
    <environments default="dev">
        <environment id="dev">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis-example"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!-- 注册mapper映射文件 -->
    <mappers>
        <!--
        <mapper resource="mapper/PersonMapper.xml"/>
        <mapper resource="mapper/TigerMapper.xml"/>
        <mapper resource="mapper/EmpMapper.xml"/>
        -->
        <!-- 当使用package标签时,name属性的值必须是Mapper接口的包名 -->
        <package name="com.bottom.mybatis.mapper"/>
    </mappers>
</configuration>

7.新建单元测试类

java 复制代码
public class EmpTest {

  private SqlSession sqlSession ;
  private EmpMapper empMapper ;

  @BeforeEach
  public void setup() throws IOException {
      InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
      SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
      sqlSession = sqlSessionFactory.openSession();
      empMapper = sqlSession.getMapper(EmpMapper.class);
  }

  @AfterEach
  public void teardown() throws SQLException {
      if(sqlSession!=null && !sqlSession.getConnection().isClosed()){
          sqlSession.commit();
          sqlSession.close();
      }
  }

  //1.演示结果集的列名和要映射的对象中的属性名称不一致的情况
  @Test
  public void test01(){
      empMapper.getEmpList().forEach(System.out::println);
  }

  //2.通过使用别名的方式解决列名和属性名不一致的情况
  @Test
  public void test02(){
      empMapper.getEmpList2().forEach(System.out::println);
  }

  //3.通过使用ResultMap的方式解决列名和属性名不一致的情况
  @Test
  public void test03(){
      empMapper.getEmpList3().forEach(System.out::println);
  }
}

3. MyBatis中的传参符号

  1. #{} 相当于 占位符 ?

  2. ${} 拼凑字符串,可能会导致注入式漏洞

4. MyBatis中的输入参数

1) 单个基本类型 - 名称任意

#{value} , #{pid} , #{abcdefg}

2) 实体类型 - 名称是实体类的属性名

#{tid} , #{tname} , #{age}

3) 零散的输入类型

- arg0 , arg1 , arg2 ...

- param1 , param2 ....

- @Param("tid")

4) Map输入类型

5. MyBatis中的输出参数

  1. 输出单个的简单类型 resultType="int"
  1. 输出实体类型 resultType="Tiger"
  1. 输出List类型 resultType="Tiger"
  1. 输出Map类型 resultType="map"

6. 查询结果集的列名和属性名不一致的三种解决方法 (用自己定义的resultmap去解决)

7. 在mybatis-config.xml文件中注册Mapper.xml文件的两种方式

  1. mapper resource 每一个xml都注册进去
xml 复制代码
<!-- 注册mapper映射文件 -->
<mappers>
    <mapper resource="mapper/PersonMapper.xml"/>
    <mapper resource="mapper/PersonMapper.xml"/>
    <mapper resource="mapper/TigerMapper.xml"/>
</mappers>
  1. package 直接注册包路径
xml 复制代码
<mappers>
   <package name="com.bottom.mybatis.mapper"/>
</mappers>
相关推荐
阿丰资源10 分钟前
SpringBoot+MySQL+MyBatis-Plus+Vue前后端分离仓库管理系统 (附资料)
spring boot·mysql·mybatis
小信丶11 分钟前
Spring Cloud Stream EnableBinding注解详解:定义、应用场景与示例代码
java·spring boot·后端·spring
无限进步_15 分钟前
【C++】验证回文字符串:高效算法详解与优化
java·开发语言·c++·git·算法·github·visual studio
亚历克斯神16 分钟前
Spring Cloud 2026 架构演进
java·spring·微服务
七夜zippoe20 分钟前
Spring Cloud与Dubbo架构哲学对决
java·spring cloud·架构·dubbo·配置中心
海派程序猿20 分钟前
Spring Cloud Config拉取配置过慢导致服务启动延迟的优化技巧
java
阿维的博客日记31 分钟前
为什么不逃逸代表不需要锁,JIT会直接删掉锁
java
William Dawson32 分钟前
CAS的底层实现
java
ffqws_36 分钟前
Spring Boot入门:通过简单的注册功能串联Controller,Service,Mapper。(含有数据库建立,连接,及一些关键注解的讲解)
数据库·spring boot·后端
程序边界42 分钟前
行标识符机制的技术演进与实践(下)——ROWID与实战应用
后端