—cache –命名空间的二级缓存配置
—cache-ref – 其他命名空间缓存配置的引用。
—resultMap – 自定义结果集映射
—parameterMap – 已废弃!老式风格的参数映射,原本是做复杂参数映射的
—sql –抽取可重用语句块。
—insert – 映射插入语句
—update – 映射更新语句
—delete – 映射删除语句
—select – 映射查询语句
[

](https://blog.csdn.net/qq_43284469/article/details/111287911)

3.1 增删改标签

—insert – 映射插入语句
—update – 映射更新语句
—delete – 映射删除语句
id要对应实现的方法名

  1. <select id="getEmpById" resultType="com.achang.bean.Employee" >
  2. select * from t_employee where id = #{id}
  3. </select>

image.png

数据库支持主键
dao.xml

</select>
<!--让MyBatis自动的将自增的id赋值给传入的employee对象的id属性
        useGeneratedKeys属性:开启自动赋值id功能
        keyProperty属性:将刚才自增的id封装给那个属性
-->
<insert id="insertEmp" useGeneratedKeys="true" keyProperty="id">
    insert into t_employee(empname,gender,email)values(#{empName},#{gender},#{email})
</insert>

bean对象

public class Employee {

    private Integer id;
    private String empName;
    private Integer gender;
    private String email;
    private String loginAccount;
}

EmployeeDao.java

    public int insertEmployee(Employee employee);

测试

    @Test
    public void test02() {
        SqlSession openSession = sessionFactory.openSession();
        try {
            Employee employee = new Employee(null, "hahaha", "haha@qq.com", 1,"o" );
            EmployeeDao employeeDao = openSession.getMapper(EmployeeDao.class);
//            int i = employeeDao.insertEmployee(employee);
            int i = employeeDao.insertEmployee2(employee);
            System.out.println("--->" + i);
            System.out.println("刚才插入的id:" + employee.getId());
        } finally {
            openSession.commit();
            openSession.close();
        }
    }

数据库没有主键:selectKey
image.png
image.png
通过order属性设置运行顺序,keyProperty属性来设置查询后结果赋值给javabean的哪个对象
然后通过useGeneratedKeys属性设置打开获取主键,keyProperty属性设置javabean的id属性接收结果值
image.png

3.2 参数(Parameters)传递

1、单个参数
    基本类型:
        取值:#{随便写}
2、多个参数:
        取值:#{参数名}是无效的的
            0,1(参数索引)或者param1,param2(第几个参数paramN)
    原因:
        只要传入多个参数,mybatis会自动的将这些参数封装到一个map中;封装时使用的key就是参数的索引和参数的第几个标识
        @param:为参数指定封装map时的key;命名参数
        我们可以告诉mybatis,封装参数map的时候别乱来
3、传入map
        封装多个参数为map,直接传递
4、传入bean
        取值:#{bean属性名}
public Employee getEmpByIdAndEmployee(@Param("id")Integer id,@Param("empname")String empName);

image.png
image.png
image.png

3.3 设置参数规则

image.png
image.png
image.png

#{}和¥{}的区别

•实际上通常被设置的是:
可能为空的列名指定 jdbcType
#{key}:获取参数的值,预编译到SQL中。安全。
${key}:获取参数的值,拼接到SQL中。有SQL注入问题。ORDER BY ${name}

image.png

3.4 查询返回List

EmployeeDao:

public interface EmployeeDao {
    public List<Employee> getAllEmps();
}

dao.xml

<!--resultType:如果返回的是集合,写的是集合里面元素的类型-->
<select id="getAllEmps" resultType="com.achang.bean.Employee">
    select * from t_employee
</select>

test

@Test
public void test3(){
    SqlSession sqlSession = factory.openSession();
    EmployeeDao mapper = sqlSession.getMapper(EmployeeDao.class);
    List<Employee> allEmps = mapper.getAllEmps();
    for (Employee employee:allEmps){
        System.out.println(employee);
    }

3.5 查询返回Map

1、单条记录返回Map

dao

public interface EmployeeDao {
    /****
     *  列名为Key,值为value
     */
    public Map<String,Object> getEmpByIdReturnMap(Integer id);
}

dao.xml
resultType属性中的map已经被mybatis自动写入别名为map了

<select id="getEmpByIdReturnMap" resultType="map">
    select * from t_employee where id = #{id}
</select>

test

@Test
public void test4(){
    SqlSession sqlSession = factory.openSession();
    EmployeeDao mapper = sqlSession.getMapper(EmployeeDao.class);
    Map<String, Object> empByIdReturnMap = mapper.getEmpByIdReturnMap(3);
    System.out.println(empByIdReturnMap);//{empname=欧尼, gender=1, id=3, login_account=b, email=achang@qq.com}
}

2、多条记录返回Map

通过@MapKey()注解来告诉mybatis数据库中哪个字段作为key主键来,封装value
dao

public interface EmployeeDao {
    //key是记录的主键,value就是记录封装好的对象
    //@MapKey根据数据库里面的哪个字段作为key来查询封装value
    @MapKey("id")
    public Map<Integer,Employee> getEmpsByIdReturnMap();
}

dao.xml

<!--查询多个的情况下,resultType属性写value封装的元素类型-->
<select id="getEmpsByIdReturnMap" resultType="com.achang.bean.Employee">
    select * from t_employee
</select>

test

@Test
public void test5(){
    SqlSession sqlSession = factory.openSession();
    EmployeeDao mapper = sqlSession.getMapper(EmployeeDao.class);
    Map<Integer, Employee> empsByIdReturnMap = mapper.getEmpsByIdReturnMap();
    System.out.println(empsByIdReturnMap);
}

3.6 自定义封装规则resultMap

reesultMap标签自定义封装
    type属性:指定引入哪个javabaen与数据库封装对应
    id属性:指定这个自定义封装的id,便于其他引用
        id标签:指定主键
        result标签:指定其他封装对象
            property属性:指定javabean属性名
            column属性:指定数据库字段名

image.png
通过resultMap属性引用那个自定义封装规则的id
image.png
image.png
image.png

3.7 联合查询

1、级联查询

  • sql语句 ``xml SELECT k.id,k.keyname,k.lockId,l.idlid,l.lockNameFROM t_key k LEFT JOIN t_lock l ON k.lockId=l.idWHERE k.id`=1
![image.png](https://cdn.nlark.com/yuque/0/2021/png/2963105/1630847234584-bf783721-428f-45f5-a194-56f9078b7b3e.png#clientId=u20aa6144-6710-4&from=paste&height=91&id=u1c484e42&margin=%5Bobject%20Object%5D&name=image.png&originHeight=91&originWidth=525&originalType=binary&ratio=1&size=4670&status=done&style=none&taskId=u015cf15b-949e-49fa-99ae-2bc15a2e442&width=525)

- bean对象
```java
public class Lock {
    private Integer id;//锁编号
    private String LockName;//锁名
    //省略get/set/toString/构造器
}
public class Key {
    private Integer id;//钥匙编号
    private String keyName;//钥匙名
    private Lock lock;//当前钥匙能开哪把锁
    //省略get/set/toString/构造器
}
  • keyDao ```java public interface keyDao { //将钥匙和锁信息一起查出 public Key getKeyById(Integer id); }

- mybatis_config.xml
```xml
<mappers>
    <mapper resource="keyDao.xml"/>
    <mapper resource="EmployeeDao.xml"/>
</mappers>
  • keyDao.xml ```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">
    

- test
```java
public class EmployeeDaoTest {
    SqlSessionFactory factory;
    @Before
    public void initSqlSessionFactory() throws IOException {
        String resource = "mybatis_config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        factory = new SqlSessionFactoryBuilder().build(inputStream);
    }

    //keyDao测试
    @Test
    public void test6(){
        SqlSession sqlSession = factory.openSession();
        keyDao mapper = sqlSession.getMapper(keyDao.class);
        Key keyById = mapper.getKeyById(2);
        System.out.println(keyById);
        //Key{id=1, keyName='1号钥匙', lock=Lock{id=1, LockName='null'}}
    }
}

2、联合查询association

下面的其他配置同上
用来自定义封装规则中,再次套娃封装bean对象属性里面的对象,若属性里面对象的属性还是对象可继续套娃封装
简单来说就是在一个javabean里面有一个属性是自定义javabean就推荐用

  • keyDao.xml ```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">
    

- test
```java
public class EmployeeDaoTest {
    SqlSessionFactory factory;
    @Before
    public void initSqlSessionFactory() throws IOException {
        String resource = "mybatis_config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        factory = new SqlSessionFactoryBuilder().build(inputStream);
    }

    //keyDao测试
    @Test
    public void test6(){
        SqlSession sqlSession = factory.openSession();
        keyDao mapper = sqlSession.getMapper(keyDao.class);
        Key keyById = mapper.getKeyById(2);
        System.out.println(keyById);
        //Key{id=1, keyName='1号钥匙', lock=Lock{id=1, LockName='1号锁'}}
    }
}

3、Collection查询

在一个javabean有集合属性就推荐用

  • sql ``xml SELECT k.id,k.keyname,k.lockId,l.idlid,l.lockNameFROM t_key k LEFT JOIN t_lock l ON k.lockId=l.idWHERE k.id`=3
![image.png](https://cdn.nlark.com/yuque/0/2021/png/2963105/1630847668306-c984c5db-dae5-4c2c-967a-9e654fafe320.png#clientId=u20aa6144-6710-4&from=paste&height=168&id=u557a080e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=168&originWidth=675&originalType=binary&ratio=1&size=69686&status=done&style=none&taskId=u42369c58-6842-4980-b24b-58f276d851e&width=675)

- bean对象
```java
public class Lock {
    private Integer id;//锁编号
    private String LockName;//锁名
    private List<Key> keys//很多把钥匙可以开这把锁
    //省略get/set/toString/构造器
}
public class Key {
    private Integer id;//钥匙编号
    private String keyName;//钥匙名
    private Lock lock;//当前钥匙能开哪把锁
    //省略get/set/toString/构造器
}
  • LockDao.xml ```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">
    


- test
```java
public class EmployeeDaoTest {
    SqlSessionFactory factory;
    @Before
    public void initSqlSessionFactory() throws IOException {
        String resource = "mybatis_config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        factory = new SqlSessionFactoryBuilder().build(inputStream);
    }

    //LockDao测试
    @Test
    public void test7(){
        SqlSession sqlSession = factory.openSession();
        keyDao mapper = sqlSession.getMapper(keyDao.class);
        Lock lockById = mapper.getLockById(3);
        System.out.println(keyById);
        //lock对象为null是因为没自定义配置association;需要则可以在resultMap中继续配置association来继续套娃
        //Key{id=3, keyName='303号钥匙1', lock=null}
       // Key{id=4, keyName='303号钥匙2', lock=null}
       // Key{id=5, keyName='303号钥匙3', lock=null}
    }
}

3.8 分步查询【不推荐】

虽然sql简单,但是会有大量性能浪费,虽然可以用过设置来减少性能浪费,但还是不推荐使用!!!

1、association-分段查询

image.png
image.png
image.png
image.png

select:调用目标的方法查询当前属性的值【方法全类名】,即额外使用一条查询语句查询该属性
column:传入select调用的方法需要的参数,t_key表里面带有lockid

2、association-分段查询&延迟加载

开启延迟加载和属性按需加载
image.png
例如:只查钥匙则不会执行查锁子的查询语句
image.png

lazy为设置延迟加载,eager则相反
image.png
image.png

  • 旧版本的MyBatis需要额外的支持包

–asm-3.3.1.jar
–cglib-2.2.2.jar

3、Collection-集合类型&嵌套结果集

image.png

image.png

4、Collection-分步查询&延迟加载

image.png