MyBatis学习:基本使用

学习之前:

        MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。

2.1 向SQL语句传参

2.1.1 mybatis日志输出配置

MyBatis配置文件详解:

<?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>

    <!-- environments表示配置Mybatis的开发环境,可以配置多个环境,在众多具体环境中,使用default属性指定实际运行时使用的环境。default属性的取值是environment标签的id属性的值。 -->
    <environments default="development">
        <!-- environment表示配置Mybatis的一个具体的环境 -->
        <environment id="development">
            <!-- Mybatis的内置的事务管理器 -->
            <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="hutao"/>
                <property name="password" value="lld666666"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <!-- Mapper注册:指定Mybatis映射文件的具体位置 -->
        <!-- mapper标签:配置一个具体的Mapper映射文件 -->
        <!-- resource属性:指定Mapper映射文件的实际存储位置,这里需要使用一个以类路径根目录为基准的相对路径 -->
        <!--    对Maven工程的目录结构来说,resources目录下的内容会直接放入类路径,所以这里我们可以以resources目录为基准 -->
        <mapper resource="mappers/EmployeeMapper.xml"/>
    </mappers>

</configuration>

官方文档:mybatis – MyBatis 3 | 简介

<environments>标签:

用于选择MyBatis配置环境的标签,如开发、测试和生产环境需要不同的配置。更换环境,只需更开<environments>标签中的default属性值即可。如上述XML文件中的配置说明当前使用的是开发环境。<environment>标签则配置了不同环境需要的配置信息。

<transcationManager>标签:

MyBatis中有两种事务管理器:type = "JDBC" / "MANAGED"

JDBC:直接使用JDBC的提交和回滚功能。(常用)

MANAGED:不提交或回滚一个连接(基本什么都不做),需要自己提交。

<datasource>标签:

配置数据源,使用JDBC数据源接口来配置JDBC连接对象的资源。

UNPOOLED:每次请求时打开和关闭连接。

POOLED:利用“池”的概念讲JDBC连接对象组织起来。(常用)

<mappers>标签:

定义SQL映射语句,告诉MyBatis去哪里找到这些语句。

<mapper class="com.xx.yy.ZzzMapper"> 使用类的全限定符来定位Mapper映射文件。

如何打开日志?

按照配置文件的顺序,声明<settings>标签。<settings>标签内声明<setting>标签,name="logImpl",value="STDOUT_LOGGING"。

<settings>
    <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>

2.1.2 传参的两种形式

#{key} 形式

以?占位符的形式动态传参

${key}形式

以字符串拼接的形式传参

推荐使用#{key} 形式传参:

防止注入攻击。但是#{key}形式不能动态传入标签、列名、SQL关键字

故动态传入列名或表名时,可以用${key}形式传入

<mapper namespace="com.landy.mapper.EmployeeMapper">
<!--
    两种传参符号:
    #{ key }:占位符+赋值 id = ? ? = 赋值
    ${ key }:拼接字符串 "id = " + id
    推荐使用#{}:防止注入攻击的问题,不能替代容器名(标签、列明、SQL关键字)
    若列名或表名是动态传入的,则需要${}
  -->
    <select id="queryById" resultType="com.landy.pojo.Employee">
        select emp_id empId, emp_name empName, emp_salary empSalary from t_emp where emp_id = ${id}
    </select>
</mapper>

2.2 数据输入

2.2.1 传入单个简单数据类型

key名可以任意指定

<delete id="deleteById">
   delete from t_emp where emp_id = #{id123}
</delete>
<select id="queryBySalary" resultType="com.landy.pojo.Employee">
        select emp_id empId, emp_name empName, emp_salary empSalary from t_emp where emp_salary = #{salary}
</select>

2.2.2 传入单个实体数据类型

传入对象时,key名需要对应为对象的属性名(严格对应)

<insert id="insertEmp">
        insert into t_emp(emp_id, emp_name, emp_salary) values(#{empId}, #{empName}, #{empSalary})
</insert>

 传入对应的Employee类

public class Employee {

    private Integer empId;

    private String empName;

    private Double empSalary;

    //getter | setter

    public Integer getEmpId() {
        return empId;
    }

    public void setEmpId(Integer empId) {
        this.empId = empId;
    }

    public String getEmpName() {
        return empName;
    }

    public void setEmpName(String empName) {
        this.empName = empName;
    }

    public Double getEmpSalary() {
        return empSalary;
    }

    public void setEmpSalary(Double empSalary) {
        this.empSalary = empSalary;
    }
}

2.2.3 多个简单数据类型

有多个简单数据类型时,key值不可以随便传入!

方案1:(推荐)

@Param(value="keyName")注解指定

List<Employee> queryByNameAndSalary(@Param("name") String name,@Param("salary") Double salary);
<select id="queryByNameAndSalary" resultType="com.landy.pojo.Employee">
        select emp_id empId, emp_name empName, emp_salary empSalary from t_emp where emp_name = #{name} and emp_salary = #{salary}
</select>

方案2:

MyBatis默认机制:从左至右按顺序依次传入 name = param1/args0, salary = param2/args1

<select id="queryByNameAndSalary" resultType="com.landy.pojo.Employee">
        select emp_id empId, emp_name empName, emp_salary empSalary 
            from t_emp where emp_name = #{param1} and emp_salary = #{param2}
</select>

 2.2.4 Map数据类型

传入的keyName与Map的keyName对应即可

<insert id="insertEmpMap">
        insert into t_emp(emp_name, emp_salary) values (#{name}, #{salary})
</insert>

2.3 数据输出

2.3.1 概述

数据输出:resultType一般有两种形式:

        增、删、改操作所影响的行数:返回值为int类型

        查询操作的查询结果所对应的数据类型

2.3.2 单个简单类型

resultType = "类的全限定符" / “别名简称”。

<delete id="deleteById">
        delete from t_emp where emp_id = #{id};
</delete>
<!-- resultType语法:类的全限定符 / 别名简称   -->
<!-- 如果没有别名,需要声明类的全限定符号,或者自己声明别名   -->
<select id="queryById" resultType="int">
        select emp_name empName from t_emp where emp_id = #{id}
</select>

如果自定义类没有别名,可以自己声明别名:

<settings>标签后,<environments>标签前,声明<typeAlias>标签。

<typeAliases>
        <typeAlias type="com.landy.pojo.Employee" alias="emp" />
</typeAliases>

或通过指定包名,自动将类名首字母小写的名称作为别名Alias。 (批量定义)

<typeAliases>
    <package name="com.landy.pojo"/>
</typeAliases>

同时,批量设置后,可以使用@Alias("otherName"),把默认的首字母小写别名改为指定的otherName,如在Employee类上方声明@Alias("name")即可把emp作为别名

2.3.3 返回实体对象类型

resultType = "返回类型的全限定符" / "别名"

要求:

返回单个实体类型时,要求返回的列名和对象实体的属性名保持一致,这样才可以实现属性映射。

设置:

若emp_id 去掉下划线 -> empId 能够与属性名对应,则可以实现属性映射。

<settings>标签中设置如下:

<settings>
        ...
        <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

2.3.4 返回Map类型

直接讲resultType声明为"map"即可。列名为key,查询结果为value。

<select id="selectEmpNameAndSalary" resultType="map">
   select emp_name, emp_salary from t_emp where emp_id = #{id};
</select>
Map<String,Object> selectEmpNameAndSalary(int id);

2.3.5 返回List类型 

如果返回值有多个同类型的实体对象,需要用List集合承接,resultType类型无需声明为List,声明为集合类对应的泛型,及同类型的实体对象即可。

<select id="queryEmpNameBySalary" resultType="String">
        select emp_name from t_emp where emp_salary > #{salary}
</select>
<select id="queryAllEmp" resultType="Employee">
        select * from t_emp;
</select>
// 查询工资高于传入值的员工姓名
List<String> queryEmpNameBySalary(double salary);
// 查询全部员工
List<Employee> queryAllEmp();

因为MyBatis框架底层都是按照selectList方法进行查询,即都是按照集合去查询,故resultType只要声明为泛型类即可!

2.3.6 返回主键值

插入对象时想获得对象primary_key的value值用于后续操作:需要返回主键值。

当主键auto increament时,<insert>标签中声明属性:

        userGeneratedKeys="true":需要数据库自增长的主键值

        keyColumn="emp_id":主键列的名称

        keyProperty="empId":接收主键列值得属性

<insert id="insertEmp" useGeneratedKeys="true" keyColumn="emp_id" keyProperty="empId">
        insert into t_emp(emp_name, emp_salary) values(#{empName}, #{empSalary})
</insert>

 当主键没有自增长时:

<insert>标签内声明<selectKey>标签:在插入之前先指定一段sql语句用于生成主键值

<selectKey order="BEFORE" resultType="" keyProperty="">

        order:声明selectKey中得语句在插入语句前或后执行 value="BEFORE" | "AFTER"

        resultType:返回值类型

        keyProperty:查询结果给哪个动态key赋值

<!-- 希望mybatis帮忙维护非自增长得主键   -->
<insert id="insertTeacher">
        <selectKey keyProperty="tId" resultType="String" order="BEFORE">
            select uuid()
        </selectKey>
        insert into teacher(t_id, t_name)
            values (#{tId}, #{tName})
</insert>

2.3.7 实体类属性

<!--
    列名和属性名不一致如何解决?
        1. 起别名,使列名与属性名对应
        2. 开始驼峰映射:<setting name="mapUnderscoreToCamelCase" value="true"/>
        3. resultMap自定义映射,
            vs:resultType按照规则自动映射,只能映射一层结构
  -->
<!--
    id:resultMap的唯一标识,其他组件引用
    type:具体的返回值类型
        <id>:主键映射关系
        <result>:普通映射关系
 -->
    <resultMap id="tMap" type="teacher">
        <id column="t_id" property="tId"/>
        <result column="t_name" property="tName"/>
    </resultMap>
    <select id="queryById" resultMap="tMap">
        select * from teacher where t_id = #{id}
    </select>

 resultMap:自定义属性映射方式,实现深层次映射

id:resultMap的唯一标识,其他组件引用id以引用map组件

tyep:返回值对应类型:别名 | 全限定符 | 泛型

<id column="primary_key主键列" property="对应属性名">

<result column="其他列" property="对应属性名">

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值