#{} ,${} 的区别

  • 二者都可以获取map中的值或者pojo对象属性的值

    1. select * from tbl_employee where id=${id} and last_name=#{lastName}
    2. Preparing: select * from tbl_employee where id=2 and last_name=?
    3. 区别:
    4. #{}:是以预编译的形式,将参数设置到sql语句中;PreparedStatement;防止sql注入
    5. ${}:取出的值直接拼装在sql语句中;会有安全问题;
    6. 大多情况下,我们去参数的值都应该去使用#{};
    7. 原生jdbc不支持占位符的地方我们就可以使用${}进行取值
    8. 比如分表、排序。。。;按照年份分表拆分
    9. select * from ${year}_salary where xxx;
    10. select * from tbl_employee order by ${f_name} ${order}

    查询结果返回

    获取插入数据自增id的值

    ```java

    insert into tbl_employee (last_name,email,gender) values(#{lastName},#{email},#{gender})

测试类

@Test public void testMybatis() throws IOException { SqlSessionFactory sqlSessionFactory = getSqlSessionFactory(); // 获取到的sqlsession不会自动提交数据 SqlSession openSession = sqlSessionFactory.openSession(); try { EmployeeMapper employeeMapper = openSession.getMapper(EmployeeMapper.class); // 测试添加 Employee emp = new Employee(null, “test01”, “0”, “qq@.com”); employeeMapper.addEmp(emp); //插入到数据库中的记录的empId:6

        System.out.println("插入到数据库中的记录的empId:"+ emp.getId());
        // 测试修改

// boolean emp = employeeMapper.updateEmp(new Employee(1, “testUpdatee”, “0”, “qq@.com”)); // 测试删除 // employeeMapper.deleteEmp(2);

        // 2 手动提交
        openSession.commit();
    }finally {
        openSession.close();
    }

}
<a name="b6r0x"></a>
## 返回一个list元素集合

- 常用于 listAll
```java
<!--    返回一个list集合
    返回类型要写集合里面的元素类型  如果返回是一个人类型没需要返回集合中元素的类型

-->
    <select id="getEmpByLastNameLike" resultType="com.addicated.bean.Employee">
        select id,last_name lastName,email,gender from tbl_employee where last_name like #{lastName}

    </select>

接口定义
    // 查询返回一个list集合
    public List<Employee>  getEmpByLastNameLike(String lastName);
测试类
  @Test
    public void testMybatis03() throws IOException {
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
        // 获取到的sqlsession不会自动提交数据
        SqlSession openSession = sqlSessionFactory.openSession();
        try {
            EmployeeMapper employeeMapper = openSession.getMapper(EmployeeMapper.class);

            List<Employee> test = employeeMapper.getEmpByLastNameLike("%test%");
            System.out.println(test.toString());
            openSession.commit();
        }finally {
            openSession.close();
        }

    }

返回一个map元素集合并指定主键

接口定义
    // 多条记录封装一个map Map<Integer,Employee>: key 为主键 值是记录封装后的javaBean
    // 告诉mybatis 封装这个map的时候使用哪个属性作为主键
    @MapKey("id")
    public Map<Integer,Employee>  getEmpMapByNameLikeReturnMap(String lastName);
xml配置
    </select>

    <select id="getEmpMapByNameLikeReturnMap" resultType="com.addicated.bean.Employee">
        select id,last_name lastName,email,gender from tbl_employee where last_name like #{lastName}

    </select>
测试代码
        Map<String, Employee> map = mapper.getEmpByLastNameLikeReturnMap("%r%");
            System.out.println(map);

返回一个map元素集合

关联查询

ResultMap 重点

  • 使用场景为 当 数据库表与javaBean 出现字段出入的情况下

     <!--自定义某个javabean的封装规则
          type  自定义规则的java类型
          id 唯一id方便引用
      -->
      <resultMap id="myEmp" type="com.addicated.bean.Employee">
          <!--        指定主键列的封装规则
          id 定义主见会有底层优化
                   column : 指定表中哪一列
                   property: 指定对应的javabean属性
          -->
          <id column="id" property="id"></id>
          <!--        定义普通列封装规则-->
          <result column="last_name" property="lastName"></result>
          <!--        其他不指定的列会自动进行封装,只要写resultMap 就吧全部的映射规则写上-->
          <result column="email" property="email"></result>
          <result column="gender" property="gender"></result>
    
      </resultMap>
    
      <!--    resultMap  自定义结果集  resultType 与 resultMap 二者互斥,2选1-->
      <!--        public Employee getEmpById(Integer id); -->
      <select id="getEmpById" resultMap="myEmp">
          select id,last_name lastName,email,gender from tbl_employee where id = #{id}
    </select>
    

    使用ResultMap实现关联查询

    1 vs 1

  • 场景1

    • employee — dep 每个职员对应一个dept部门。查询职员信息的时候将dept的相关信息也关联查询出来

emp表
image.png
dept表
image.png

xml配置

 <!--
        场景1
            employee == Dep  关联查询
            一个员工有与之对应的部门信息
    -->
    <!--    联合查询  使用级联属性封装-->
    <resultMap id="empDept" type="com.addicated.bean.Employee">
        <id column="id" property="id"></id>
        <result column="last_name" property="lastName"></result>
        <result column="gender" property="gender"></result>
        <result column="did" property="dept.id"></result>
        <result column="dept_name" property="dept.deptName"></result>

    </resultMap>

    <resultMap id="empDept1" type="com.addicated.bean.Employee">
        <id column="id" property="id"></id>
        <result column="last_name" property="lastName"></result>
        <result column="gender" property="gender"></result>
        <!-- association可以指定联合的javabean对象
            property 指定哪个属性是联合的对象
            javaType 指定这个属性对象的类型 不可省略
        -->
        <association property="dept" javaType="com.addicated.bean.Dept">
            <id column="did" property="id"></id>
            <result column="dept_name" property="deptName"></result>

        </association>
    </resultMap>

    <!--        public Employee getEmpAndDept(Integer id);-->
    <select id="getEmpAndDept" resultMap="empDept1">
       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=#{id}
    </select>

association 标签

  • property 指定哪个属性是联合的对象
  • javaType 指定这个属性对象的类型

    • id 主键 ,此时的column 为sql语句返回的查询结果中的did, property为javaBean中的对应字段
    • result column 则是 一sql语句返回的查询结果中的column 与 javaBean中的字段进行映射

      实体类中的操作

  • 因为是要对emp进行操作,查询出来每个emp关联的dept,所以,我们要将dept的属性注入到emp内 ```java public class Employee {

private Integer id;


private String lastName;
private String gender;
private String email;
private Dept dept;
get/set方法省略
   又因为是1对1的查询,所以添加为单数而非集合
<a name="FQHzR"></a>
### 1 vs 多

- 视角变换一下,站在部门的角度,去查询每个部门下所有的成员,部门为1,成员为多。
<a name="gfOAO"></a>
#### 实体类准备
```java

public class Dept {


    private Integer id;

    private String deptName;

    private List<Employee> emps;
    get/set 方法省略
       当前为1对多的查询。所以添加元素依赖应当是list集合类型的emp对象

xml中配置

  <!--
        collection 嵌套结果集  使用collection标签定义关联的集合类型的属性封装规则
    -->
    <!--    dept{ id , deptName, List<Employee> emps
            查询结果
          did  dept_name  ||  eid  last_name  email   gender
    -->
    <!-- resultMap 根据查询结果进行封装映射 , 查询结果与mysql内一致-->
    <resultMap id="myDept" type="com.addicated.bean.Dept">
        <id column="did" property="id"></id>
        <result column="dept_name" property="deptName"></result>
        <!--        使用collection 来定义关联集合类型的属性封装规则
                    property   实体类中属性名  ofType 集合类面元素类型
        -->
        <collection property="emps" ofType="com.addicated.bean.Employee">
            <!--            定义集合中元素的封装规则-->
            <id column="eid" property="id"></id>
            <result column="last_name" property="lastName"></result>
            <result column="email" property="email"></result>
            <result column="gender" property="gender"></result>
        </collection>

    </resultMap>
    <!--        public Dept getDeptByidPlus(Integer id);-->
    <select id="getDeptByidPlus" resultMap="myDept">
                SELECT d.id did,d.dept_name dept_name,
                e.id eid,e.last_name last_name,e.email email,e.gender gender
        FROM tbl_dept d
        LEFT JOIN tbl_employee e
        ON d.id=e.d_id
        WHERE d.id=#{id}



    </select>

collection标签

  • property 指定多方的属性名,直接关联为实体类中注入的多方属性名
  • ofType 则是多方的javaBean全类名
  • 其余与associatetion 一致。

未完待续