likes
comments
collection
share

🐳 Mybatis 入门学习

作者站长头像
站长
· 阅读数 5

1. MyBatis是什么?

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

2. MyBatis的开发步骤

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

🐳 Mybatis 入门学习

🐳 Mybatis 入门学习

🐳 Mybatis 入门学习

🐳 Mybatis 入门学习

2.建POJO

@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)

<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接口

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文件

🐳 Mybatis 入门学习

EmpMapper.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 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 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 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.新建单元测试类

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);
  }
}

🐳 Mybatis 入门学习

3. MyBatis中的传参符号

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

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

🐳 Mybatis 入门学习

4. MyBatis中的输入参数

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

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

🐳 Mybatis 入门学习

🐳 Mybatis 入门学习

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

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

🐳 Mybatis 入门学习

🐳 Mybatis 入门学习

3) 零散的输入类型

- arg0 , arg1 , arg2 ...

- param1 , param2 ....

🐳 Mybatis 入门学习

🐳 Mybatis 入门学习

- @Param("tid")

🐳 Mybatis 入门学习

🐳 Mybatis 入门学习

4) Map输入类型

🐳 Mybatis 入门学习

🐳 Mybatis 入门学习

🐳 Mybatis 入门学习

5. MyBatis中的输出参数

  1. 输出单个的简单类型 resultType="int"

🐳 Mybatis 入门学习

  1. 输出实体类型 resultType="Tiger"

🐳 Mybatis 入门学习

  1. 输出List类型 resultType="Tiger"
  1. 输出Map类型 resultType="map"

🐳 Mybatis 入门学习

🐳 Mybatis 入门学习

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

🐳 Mybatis 入门学习

🐳 Mybatis 入门学习

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

  1. mapper resource 每一个xml都注册进去
<!-- 注册mapper映射文件 -->
<mappers>
    <mapper resource="mapper/PersonMapper.xml"/>
    <mapper resource="mapper/PersonMapper.xml"/>
    <mapper resource="mapper/TigerMapper.xml"/>
</mappers>
  1. package 直接注册包路径
<mappers>
   <package name="com.bottom.mybatis.mapper"/>
</mappers>
转载自:https://juejin.cn/post/7350320544527892519
评论
请登录