Mybatis快速入门--映射文件(一)(优化版)

108 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第23天,点击查看活动详情

MyBatis-映射文件

MyBatis 的真正强大在于它的语句映射,这是它的魔力所在

映射文件指导着Mybatis如何进行数据库CRUD,有着非常重要的意义

cache-命名空间的二级缓存配置

cache-ref-其他命名空间缓存配置的引用

resultMap-自定义结果集映射

sql抽取可重用语句块

insert -映射插入语句

update-映射更新语句

delete -映射删除语句

select-映射查询语句

SQL映射文件一般命名为接口名+Mapper

如EmployeeMapper、EmployeeMapperpro、EmployeeMapperpromax

下面我们来分别介绍sql映射文件中的这些元素~

增删改查元素

这里值得一提的是,获取到的openSession不会自动提交

因为openSession不会自动提交事务,对数据库进行修改操作后,要手动提交事务

==sqlSession.commit();==

1、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>
    <!--读取外部properties配置文件-->
    <properties resource="jdbc.properties"></properties>

<!--    <settings>-->
<!--        <setting name="logImpl" value="LOG4J"/>-->
<!--    </settings>-->

    <!--数据源-->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}" />
                <property name="url" value="${jdbc.url}" />
                <property name="username" value="${jdbc.username}" />
                <property name="password" value="${jdbc.password}" />
            </dataSource>
        </environment>
    </environments>

    <!--映射文件扫描包路径-->
    <mappers>
        <package name="com.caq.study.mapper"></package>
    </mappers>
</configuration>

2、jdbc配置文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/heima_ssm?useSSL=false
jdbc.username=root
jdbc.password=root

3、mapper接口

package com.caq.study.mapper;


import com.caq.study.entity.Account;

public interface AccountMapper {
//    查询
    Account selectById(Integer id);
//    增加
    boolean save(Account account);

    boolean updateById(Account account);

    boolean deleteById(Integer id);

}

4、mapper映射文件

useGeneratedKeys="true",使用自增主键获取主键值策略 keyProperty,指定对应的生键属性,也就是mybatis获取到主键值以后,将这个值封装给javaBean的对应字段

<?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.caq.study.mapper.AccountMapper">
    <insert id="save" parameterType="com.caq.study.entity.Account" useGeneratedKeys="true" keyProperty="id">
        insert into account(name, money)
        values (#{name}, #{money})
    </insert>

    <update id="updateById">
        update account
        set name=#{name},
            money=#{money}
        where id = #{id}
    </update>

    <delete id="deleteById">
        delete from `account` where id = #{id}
    </delete>

    <select id="selectById" resultType="com.caq.study.entity.Account">
        select *
        from account
        where id = #{id}
    </select>

</mapper>

5、测试

public class demo {

    public static SqlSessionFactory getSqlSessionFactory() throws IOException {
        // 1. 创建SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        // 2. 加载SqlMapConfig.xml配置文件
        InputStream inputStream = Resources.getResourceAsStream("MybatisConfig.xml");
        // 3. 创建SqlSessionFactory对象
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
        return sqlSessionFactory;
    }


    @Test
    public void testSave() throws IOException {
        //这里获取的sqlsession不会自动提交
        SqlSession sqlSession = getSqlSessionFactory().openSession(true);

        AccountMapper accountMapper = sqlSession.getMapper(AccountMapper.class);

        Account account = new Account();
        account.setName("test1");
        account.setMoney("5000");

        boolean save = accountMapper.save(account);
        System.out.println(save);

        sqlSession.commit();
        sqlSession.close();
    }

    @Test
    public void testSelect() throws IOException {
        SqlSession sqlSession = getSqlSessionFactory().openSession();

        AccountMapper accountMapper = sqlSession.getMapper(AccountMapper.class);

        Account account = accountMapper.selectById(1);
        System.out.println(account);

        sqlSession.close();
    }

    @Test
    public void testDelete() throws IOException {
        SqlSession sqlSession = getSqlSessionFactory().openSession();

        AccountMapper accountMapper = sqlSession.getMapper(AccountMapper.class);

        boolean account = accountMapper.deleteById(8);
        System.out.println(account);

        sqlSession.commit();
        sqlSession.close();
    }

    @Test
    public void testUpdate() throws IOException {
        SqlSession sqlSession = getSqlSessionFactory().openSession();

        AccountMapper accountMapper = sqlSession.getMapper(AccountMapper.class);

        Account account = new Account();
        account.setId(9);
        account.setName("test1");
        account.setMoney("7000");

        accountMapper.updateById(account);
        System.out.println(account);

        sqlSession.commit();
        sqlSession.close();
    }
}

参数处理

参数位置支持的属性

javaType、jdbcType、mode、numericScale、resultMap、typeHandler、jdbcTypeName

实际上通常被设置的是∶

​ 可能为空的列名指定jdbcType

#{key}:获取参数的值,预编译到SQL中。安全。

key:获取参数的值,拼接到SQL中。有SQL注入问题。ORDERBY{key}:获取参数的值,拼接到SQL中。有SQL注入问题。ORDER BY {name}

大多数情况选择#{key}的方式来获取参数的值

联合查询:级联属型封装结果集

<resultMap id="MyEmpPlus" type="com.caq.mybatis.bean.Employee">
    <id column="id" property="id"/>
    <result column="last_name" property="lastName"/>
    <result column="gender" property="gender"/>
    <result column="did" property="dept.id"/>
    <result column="dept_name" property="dept.departmentName"/>
</resultMap>

<select id="getEmpAndDept" resultMap="MyEmpPlus">
    SELECT e.id id,e.last_name last_name,e.gender gender,e.d_id d_id,d.id did,d.dept_name dept_name
    FROM tbl_employee e,tbl_dept d
    where e.d_id = d.id
    and e.id = 1
</select>

上述方式的确可以解决这个问题

但是你看它是不是写的太麻烦了啊,那有没有简单的方法查询呢?

association可以指定联合的javaBean对象 指定哪个属型是联合的对象 javaType指定属型对象的类型【不能省略】 使用association定义关联的单个对象的封装规则

<resultMap id="MyEmpByStep" type="com.caq.mybatis.bean.Employee">
    <!--        先按照员工id查询员工信息-->
    <!--        根据查询员工信息中的d_id值去查部门查处部门信息--> 
    <!--        部门设置到员工中-->  
    <id column="id" property="id"/>  
    <result column="last_name" property="lastName"/> 
    <result column="email" property="email"/>  
    <result column="gender" property="gender"/> 
    <!--        association来定义关联对象的封装规则            select表明当前属性是调用sekect指定的方法查出的结果            流程:使用select指定的方法(传入column指定的这列参数的值)查出对象,并封装给property指定的属性--> 
    <association property="dept"select="com.caq.mybatis.dao.DepartmentMapper.getDeptById" column="d_id"> 
    </association>
</resultMap>
<select id="getEmpByIdStep" resultMap="MyEmpByStep"> 
    select * from tbl_employee where id = #{id}
</select>