🐳 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>
相关推荐
葫芦和十三1 小时前
图解 MongoDB 21|选举与 failover:Primary 是怎么选出来的
后端·mongodb·agent
GetcharZp2 小时前
26k Star 开源内网穿透神器 NetBird,一分钟实现全球设备互联!
后端
考虑考虑2 小时前
Mybatis实现批量插入
java·后端·mybatis
咖啡八杯3 小时前
GoF设计模式——中介者模式
java·后端·spring·设计模式
lizhongxuan5 小时前
多Agent之间的区别
后端
青石路7 小时前
记一次多JDK版本问题的排查,一坑套一坑,差点没爬上来
java
杨充7 小时前
1.面向对象设计思想
后端
IT_陈寒8 小时前
Java的Date类又坑了我一次,改用时间戳真香
前端·人工智能·后端
systemPro8 小时前
2.6亿条设备数据,历史查询从超时到50ms,我做了什么
后端
要阿尔卑斯吗8 小时前
提示词优化启示:为什么“按顺序输出“比“关键度评分“更有效
后端