MyBatis基本使用

目录

向sql语句传参

1.mybatis日志输出配置

2.#{}形式

3.${}形式

数据输入

1.单个简单类型参数

2.实体类类型参数

3.多个简单类型参数

4.Map类型参数

数据输出

1.返回单个简单类型

2.返回实体类对象

3.返回Map类型

4.返回主键值

1)自增长类型主键

2)非自增长类型主键

5.实体类属性和数据库字段对应关系


向sql语句传参

1.mybatis日志输出配置

注意:标签按顺序书写

mybatis开启日志:使用settings标签

<settings>
  <!-- SLF4J 选择slf4j输出! -->
  <setting name="logImpl" value="SLF4J"/>
</settings>

2.#{}形式

在MyBatis中,会将sql语句中的#{}置换成问号占位符

3.${}形式

${}形式传参,底层MyBatis做的是字符串拼接操作

结论:实际开发中,能用#{}实现的,肯定不用${}。

特殊情况: 动态的不是值,是列名或者关键字,需要使用${}拼接

//注解方式传入参数!!
@Select("select * from user where ${column} = #{value}")
User findByColumn(@Param("column") String column, 
                                @Param("value") String value);

数据输入

1.单个简单类型参数

随意命名(但一般还是和接口方法参数名相同)

    int deleteById(Integer id);
    <!-- 场景 1:传入的单个简单类型  key随便写,一般情况下推荐使用参数名!!!-->
    <delete id="deleteById">
        delete from t_emp where emp_id = #{hahhhhh}
    </delete>

2.实体类类型参数

一般和实体类属性名相同

    int insertEmp(Employee employee);
    <!-- 场景 2:传入的是一个实体对象,key如何写? ==》 key = 属性名 即可 -->

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

对应关系

结论

Mybatis会根据#{}中传入的数据,加工成getXxx()方法,通过反射在实体类对象中调用这个方法,从而获取到对应的数据。填充到#{}解析后的问号占位符这个位置。

3.多个简单类型参数

使用注解@Param("别名")

    List<Employee> queryByNameAndSalary(@Param("nam") String name, @Param("sal") Double salary);
    <!--
        场景 3:传入多个简单类型,key如何写?
                可不可以随便写?不可以
                按照形参名称获取?也不可以
                方案1:使用注解@Param("abc") ===> #{abc} 【推荐】
                方案2:mybatis默认机制,从左到右一次arg0,arg1;或者从左到右依次param1,param2;例如#{arg0}
                可混用!
    -->
    <select id="queryByNameAndSalary" resultType="com.atguigu.pojo.Employee">
        select emp_id empId,emp_name empName,emp_salary empSalary
            from t_emp where emp_name = #{nam} and emp_salary = #{sal}
<!--        select emp_id empId,emp_name empName,emp_salary empSalary-->
<!--            from t_emp where emp_name = #{arg0} and emp_salary = #{arg1}-->
<!--        select emp_id empId,emp_name empName,emp_salary empSalary-->
<!--            from t_emp where emp_name = #{param1} and emp_salary = #{param2}-->
<!--        select emp_id empId,emp_name empName,emp_salary empSalary-->
<!--            from t_emp where emp_name = #{param1} and emp_salary = #{param2}-->
<!--        select emp_id empId,emp_name empName,emp_salary empSalary-->
<!--            from t_emp where emp_name = #{param1} and emp_salary = #{sal}-->
    </select>

对应关系

4.Map类型参数

    int insertEmpMap(Map<String,Object> map);
    <!--
        场景 4:传入map 如何指定key的值?
                key = map的key值即可
    -->

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

junit测试

private SqlSession session;
//junit5会在每一个@Test方法前执行@BeforeEach方法
@BeforeEach
public void init() throws IOException {
    session = new SqlSessionFactoryBuilder()
            .build(
                    Resources.getResourceAsStream("mybatis-config.xml"))
            .openSession();
}

@Test
public void testUpdateEmpNameByMap() {
  EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
  Map<String, Object> paramMap = new HashMap<>();
  paramMap.put("empSalaryKey", 999.99);
  paramMap.put("empIdKey", 5);
  int result = mapper.updateEmployeeByMap(paramMap);
  log.info("result = " + result);
}

//junit5会在每一个@Test方法后执行@@AfterEach方法
@AfterEach
public void clear() {
    session.commit();
    session.close();
}

对应关系

#{}对应Map中的key

使用场景

有很多零散的参数需要传递,但是没有对应的实体类类型可以使用。使用@Param注解一个一个传入又太麻烦了。所以都封装到Map中。

数据输出

1.返回单个简单类型

int selectEmpCount();
<select id="selectEmpCount" resultType="int">
  select count(*) from t_emp
</select>

细节解释:

  •   select标签,通过resultType指定查询返回值类型!
  •   resultType = "全限定符 | 别名 | 如果是返回集合类型,写范型类型即可"

别名问题:

下面是Mybatis为常见的 Java 类型内建的类型别名。它们都是不区分大小写的,注意,为了应对原始类型的命名重复,采取了特殊的命名风格。

自定义别名设置:

类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。例如:

<typeAliases>
  <typeAlias alias="Author" type="domain.blog.Author"/>
  <typeAlias alias="Blog" type="domain.blog.Blog"/>
</typeAliases>

当这样配置时,`Blog` 可以用在任何使用 `domain.blog.Blog` 的地方。

也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,比如:

<typeAliases> <package name="domain.blog"/> </typeAliases>

每一个在包 `domain.blog` 中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。 比如 `domain.blog.Author` 的别名为 `author`;若有注解,则别名为其注解值。见下面的例子:

@Alias("author")
public class Author {
    ...
}

2.返回实体类对象

<!-- 编写具体的SQL语句,使用id属性唯一的标记一条SQL语句 -->
<!-- resultType属性:指定封装查询结果的Java实体类的全类名 -->
<select id="selectEmployee" resultType="com.atguigu.mybatis.entity.Employee">

  <!-- Mybatis负责把SQL语句中的#{}部分替换成“?”占位符 -->
  <!-- 给每一个字段设置一个别名,让别名和Java实体类中属性名一致 -->
  select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_id=#{maomi}

</select>

通过给数据库表字段加别名,让查询结果的每一列都和Java实体类中属性对应起来。

增加全局配置自动识别对应关系

在 Mybatis 全局配置文件中,做了下面的配置,select语句中可以不给字段设置别名

<!-- 在全局范围内对Mybatis进行配置 -->
<settings>

  <!-- 具体配置 -->
  <!-- 从org.apache.ibatis.session.Configuration类中可以查看能使用的配置项 -->
  <!-- 将mapUnderscoreToCamelCase属性配置为true,表示开启自动映射驼峰式命名规则 -->
  <!-- 规则要求数据库表字段命名方式:单词_单词 -->
  <!-- 规则要求Java实体类属性名命名方式:首字母小写的驼峰式命名 -->
  <setting name="mapUnderscoreToCamelCase" value="true"/>

</settings>

3.返回Map类型

<!-- Map<String,Object> selectEmpNameAndMaxSalary(); -->
<!-- 返回工资最高的员工的姓名和他的工资 -->
<select id="selectEmpNameAndMaxSalary" resultType="map">
  SELECT
    emp_name 员工姓名,
    emp_salary 员工工资,
    (SELECT AVG(emp_salary) FROM t_emp) 部门平均工资
  FROM t_emp WHERE emp_salary=(
    SELECT MAX(emp_salary) FROM t_emp
  )
</select>

4.返回List类型

resultType填相对应的泛型类型。

查询结果返回多个实体类对象,希望把多个实体类对象放在List集合中返回。此时不需要任何特殊处理,在resultType属性中还是设置实体类类型即可

<!-- List<Employee> selectAll(); -->
<select id="selectAll" resultType="com.atguigu.mybatis.entity.Employee">
  select emp_id empId,emp_name empName,emp_salary empSalary
  from t_emp
</select>

4.返回主键值

1)自增长类型主键

<!-- int insertEmployee(Employee employee); -->
<!-- useGeneratedKeys属性字面意思就是“使用生成的主键” -->
<!-- keyProperty属性可以指定主键在实体类对象中对应的属性名,Mybatis会将拿到的主键值存入这个属性 -->
<insert id="insertEmployee" useGeneratedKeys="true" keyProperty="empId">
  insert into t_emp(emp_name,emp_salary)
  values(#{empName},#{empSalary})
</insert>

注意

Mybatis是将自增主键的值设置到实体类对象中,而不是以Mapper接口方法返回值的形式返回。

2)非自增长类型主键

而对于不支持自增型主键的数据库(例如 Oracle)或者字符串类型主键,则可以使用 selectKey 子元素:selectKey 元素将会首先运行,id 会被设置,然后插入语句会被调用!

使用 `selectKey` 帮助插入UUID作为字符串类型主键示例:

<insert id="insertUser" parameterType="User">
    <selectKey keyProperty="id" resultType="java.lang.String"
        order="BEFORE">
        SELECT UUID() as id
    </selectKey>
    INSERT INTO user (id, username, password) 
    VALUES (
        #{id},
        #{username},
        #{password}
    )
</insert>

5.实体类属性和数据库字段对应关系

1)全局配置自动识别驼峰式命名规则

<!-- 使用settings对Mybatis全局进行设置 -->
<settings>

  <!-- 将xxx_xxx这样的列名自动映射到xxXxx这样驼峰式命名的属性名 -->
  <setting name="mapUnderscoreToCamelCase" value="true"/>

</settings>

2)使用resultMap


<!--
    列名和属性名不一致如何解决:
        1.起别名            select t_id tId,t_name tName from teacher where t_id = #{id}
        2.开启驼峰式映射     <setting name="mapUnderscoreToCamelCase" value="true"/>
        3.resultMap自定义映射(resultType和resultMap二选一)
            resultType按照规则自动映射,按照是否开启驼峰式映射,自己映射属性和列名,只能映射一层结构!
            深层次的对象结构无法映射,多表查询的时候结果无法映射!
            resultMap标签,自定义映射关系,可以深层次,可以单层次!!!
-->
    <!--
        声明resultMap标签,自己定义映射规则
            id标识  ->  select resultMap="标识"
            type    -> 具体的返回值类型
                <id  主键映射关系
                <property  普通列的映射关系
    -->
    <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 t_id tId,t_name tName from teacher where t_id = #{id}-->
    </select>
<!-- 专门声明一个resultMap设定column到property之间的对应关系 -->
<resultMap id="selectEmployeeByRMResultMap" type="com.atguigu.mybatis.entity.Employee">

  <!-- 使用id标签设置主键列和主键属性之间的对应关系 -->
  <!-- column属性用于指定字段名;property属性用于指定Java实体类属性名 -->
  <id column="emp_id" property="empId"/>

  <!-- 使用result标签设置普通字段和Java实体类属性之间的关系 -->
  <result column="emp_name" property="empName"/>

  <result column="emp_salary" property="empSalary"/>

</resultMap>

<!-- Employee selectEmployeeByRM(Integer empId); -->
<select id="selectEmployeeByRM" resultMap="selectEmployeeByRMResultMap">

  select emp_id,emp_name,emp_salary from t_emp where emp_id=#{empId}

</select>

  • 19
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值