🐳 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>
相关推荐
跃ZHD2 分钟前
前后端分离,Jackson,Long精度丢失
java
blammmp23 分钟前
Java:数据结构-枚举
java·开发语言·数据结构
暗黑起源喵41 分钟前
设计模式-工厂设计模式
java·开发语言·设计模式
WaaTong1 小时前
Java反射
java·开发语言·反射
齐 飞1 小时前
MongoDB笔记01-概念与安装
前端·数据库·笔记·后端·mongodb
九圣残炎1 小时前
【从零开始的LeetCode-算法】1456. 定长子串中元音的最大数目
java·算法·leetcode
wclass-zhengge1 小时前
Netty篇(入门编程)
java·linux·服务器
LunarCod1 小时前
WorkFlow源码剖析——Communicator之TCPServer(中)
后端·workflow·c/c++·网络框架·源码剖析·高性能高并发
Re.不晚2 小时前
Java入门15——抽象类
java·开发语言·学习·算法·intellij-idea
雷神乐乐2 小时前
Maven学习——创建Maven的Java和Web工程,并运行在Tomcat上
java·maven