🐳 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>
相关推荐
kinlon.liu2 分钟前
零信任安全架构--持续验证
java·安全·安全架构·mfa·持续验证
王哲晓23 分钟前
Linux通过yum安装Docker
java·linux·docker
java66666888828 分钟前
如何在Java中实现高效的对象映射:Dozer与MapStruct的比较与优化
java·开发语言
Violet永存29 分钟前
源码分析:LinkedList
java·开发语言
执键行天涯29 分钟前
【经验帖】JAVA中同方法,两次调用Mybatis,一次更新,一次查询,同一事务,第一次修改对第二次的可见性如何
java·数据库·mybatis
Adolf_199343 分钟前
Flask-JWT-Extended登录验证, 不用自定义
后端·python·flask
Jarlen44 分钟前
将本地离线Jar包上传到Maven远程私库上,供项目编译使用
java·maven·jar
蓑 羽1 小时前
力扣438 找到字符串中所有字母异位词 Java版本
java·算法·leetcode
叫我:松哥1 小时前
基于Python flask的医院管理学院,医生能够增加/删除/修改/删除病人的数据信息,有可视化分析
javascript·后端·python·mysql·信息可视化·flask·bootstrap
Reese_Cool1 小时前
【C语言二级考试】循环结构设计
android·java·c语言·开发语言