2019-04-17 MyBatis框架学习(一)

1.MyBatis下载

2013年之后MyBatis迁徙到了github,地址:https://github.com/mybatis/mybatis-3

image.png

(一)mybatis helloword

***************************mybatis-config.xml**********************************
<?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">
  
 <!-- Building SqlSessionFactory from XML -->
<configuration>
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
        <property name="username" value="root"/>
        <property name="password" value="bzq18107155240"/>
      </dataSource>
    </environment>
  </environments>
  
  <!-- j将我们写好的sql(EmployeeMapper.xml)映射到全局配置文件(mybatis-config.xml)当中 -->
  <mappers>
    <!--mapper是用来绑定接口的实现类(dao的实现mapper.xml)的-->
    <mapper resource="EmployeeMapper.xml"/>
  </mappers>
</configuration>
**************************EmployeeMapper.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">
  
<mapper namespace="com.neusoft.mybatis.EmployeeMapper">

<!-- 
    namespace:名称空间,可以随便起
    #{id}:从传过来的参数当中获取id
    查询出来的数据被封装到了com.neusoft.mybatis.Employee当中
    注意只有当名字和数据库当中一模一样的时候,才会赋值成功,否则赋值为bull,故可以其别名来设置
    这里和JDBC的ResultSet一样
 -->
  <select id="selectEmp" resultType="com.neusoft.mybatis.Employee">
    <!-- select * from tbl_employee where id = #{id} -->
    select id,last_name,email,gender age from tbl_employee where id = #{id}
  </select>
</mapper>
*************************Employee******************
package com.neusoft.mybatis;

public class Employee {

    /**
     * 注意在映射的时候,只有当名字一模一样的时候才可以映射成功
     */
    private Integer id;
    
    private String last_name;
    
    private String age;
    
    private String email;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getlastName() {
        return getlastName();
    }

    public void setlast_name(String name) {
        this.last_name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "Employee [id=" + id + ", name=" + last_name + ", age=" + age + ", email=" + email + "]";
    }
    
    
}
**********************testMybatis************************
package com.neusoft.mybatis;

import static org.junit.jupiter.api.Assertions.*;

import java.io.IOException;
import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.jupiter.api.Test;

class MybatisTest {

    /**
     * 1.根据xml配置文件(全局配置文件)创建一个sqlSessionFactory对象,其中有数据源和一些环境信息
     * 2.sql映射文件,配置了每一个SQL以及SQL的封装规则
     * 3.将SQL映射文件注册在全局配置文件当中
     * 4.写代码:
     *      1.)根据全局配置文件得到SqlSessionFanctory
     *      2.)根据sqlSessionFactory得到sqlSession对象,使用对象来执行增删改查
     *          一个sqlSession就代表和数据库的一次会话,用完要关闭
     *      3.)使用SQL的唯一标示来告诉Mybatis执行哪个sql。SQL都是保存在SQL映射文件当中的
     * @throws IOException
     */
    @Test
    void testMybatis() throws IOException {
        
        //1.根据xml配置文件(全局配置文件)创建一个sqlSessionFactory对象
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory =new SqlSessionFactoryBuilder().build(inputStream);
        
        //2.获取sqlSession实例,能执行已经映射的SQL语句
        SqlSession openSession=sqlSessionFactory.openSession();
        
        try {
            /**
             * 第一个参数:sql语句的唯一表示,即xml文件当中select语句的id
             * 第二个参数:要传入SQL语句的参数
             */
            Employee employee=openSession.selectOne("com.neusoft.mybatis.EmployeeMapper.selectEmp", 1);
            System.out.println(employee);
            
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            
            openSession.close();

        }
        
    }

}

(二)MyBatis接口式编程

mybatis通过xml文件为接口创建了一个代理对象,我们也可以使用hibernate,jdbc来做

    /**
     * 1.接口是编程
     *      原生: Dao====>DaoImpl
     *  mybatis:  Mapper====>xxxMapper.xml
     * 
     * 2.SqlSession代表和数据库的一次会话,我们每次要执行增删改查,不管是掉sqlSession的原生API:openSession.selectOne("com.neusoft.mybatis.EmployeeMapper.selectEmp", 1),
     * 还是获取到接口的实现类:EmployeeMapper employeeMapper=openSession.getMapper(EmployeeMapper.class);
     * 都是采用的sqlsession,所有和数据库有关的资源都是十分珍贵的,用完要关闭
     * 
     * 3.SqlSession和Connection一样都是非线程安全的,每次使用都应该获取新的对象,不要放在成员变量当中,
     * 否则会发生一个线程关闭了SqlSession,另一个还在使用,就出错了。
     * 
     * 4.mapper接口没有实现类,但是mybatis会为这个接口生成一个代理对象
     *      (将接口和XML文件绑定在一起)
     * EmployeeMapper employeeMapper=openSession.getMapper(EmployeeMapper.class);
     * 
     * 5.两个重要的配置文件
     *      mybatis的全局配置文件,包含数据库连接池信息,事物管理信息...系统运行环境。
     *      sql映射文件,保存了每一个SQL语句的映射信息
     */
package com.neusoft.mybatis;

public interface EmployeeMapper {

    public Employee getEmpById(Integer id);
}
*******************************************************************
<?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.neusoft.mybatis.EmployeeMapper">

<!-- 
    namespace:名称空间,可以随便起,自从有了面向接口编程,就使用接口的全类名
    #{id}:从传过来的参数当中获取id
    查询出来的数据被封装到了com.neusoft.mybatis.Employee当中
    注意只有当名字和数据库当中一模一样的时候,才会赋值成功,否则赋值为bull,故可以其别名来设置
    这里和JDBC的ResultSet一样
 -->
 
 
 <!-- 注意接口当中有一个方法是按照ID查员工的方法,xml文件当中下面的select标签的功能也是按照ID查员工的方法
        可以把该标签的ID改为方法public Employee getEmpById(Integer id);
        
        意思是这个select标签是com.neusoft.mybatis.EmployeeMapper接口下getEmpById方法的实现
  -->
  <select id="getEmpById" resultType="com.neusoft.mybatis.Employee">
    <!-- select * from tbl_employee where id = #{id} -->
    select id,last_name,email,gender age from tbl_employee where id = #{id}
  </select>
</mapper>
******************************************************************************
public  void test01() throws IOException {
        //1.根据xml配置文件(全局配置文件)创建一个sqlSessionFactory对象
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory =new SqlSessionFactoryBuilder().build(inputStream);
        
        //2.获取sqlSession实例,能执行已经映射的SQL语句
        SqlSession openSession=sqlSessionFactory.openSession();
        
        try {
            /**
             * 3.调用openSession的增删改查API
             * 有了接口是编程就不用这样做了
             * 获得接口的实现类对象
             * ***************************************
             * 只要将接口和xml文件进行动态绑定,mybatis就会自动为接口创建一个代理对象,然后由代理对象去执行增删改查
             * ***************************************
             */
            EmployeeMapper employeeMapper=openSession.getMapper(EmployeeMapper.class);
            Employee employee=employeeMapper.getEmpById(1);
            System.out.println(employeeMapper.getClass());
            System.out.println(employee);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            openSession.close();
        }
        
    }

2.Mybatis全局配置文件

(一)properties属性

引入属性文件,获取jdbc属性值

<?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">
  
  
 <!-- Building SqlSessionFactory from XML -->
<configuration>

  <!--
     1.mybatis可以使用properties标签引入外部properties配饰文件的内容
        resource:引入类路径下的内容
        URL:引入网络路径下的文件或者磁盘路径下的文件
  -->
  <properties resource="db.properties"></properties>
  <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>
  
  
  <!-- j将我们写好的sql(EmployeeMapper.xml)映射到全局配置文件(mybatis-config.xml)当中 -->
  <mappers>
    <!--mapper是用来绑定接口的实现类(dao的实现mapper.xml)的-->
    <mapper resource="EmployeeMapper.xml"/>
  </mappers>
</configuration>
**********************************************************************
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=bzq18107155240

(二)settings属性

mybatis当中极为重要的调整设置,它将会改变mybatis的运行是行为

2.settings包含很多重要的设置
        setting:用来是指每一个设置项
            name:设置项名,mapUnderscoreToCameLCaseEnables,数据库a_count,实体aCount,不会赋值失败,会直接解析为a_count,然后赋值
            value:设置项值
<?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">
  
  
 <!-- Building SqlSessionFactory from XML -->
<configuration>

  <!--
     1.mybatis可以使用properties标签引入外部properties配饰文件的内容
        resource:引入类路径下的内容
        URL:引入网络路径下的文件或者磁盘路径下的文件
  -->
  <properties resource="db.properties"></properties>
  <!-- 
     2.settings包含很多重要的设置
        setting:用来是指每一个设置项
            name:设置项名,mapUnderscoreToCameLCaseEnables,数据库a_count,实体aCount,不会赋值失败,会直接解析为a_count,然后赋值
            value:设置项值      
   -->
   <settings>
        <setting name="mapUnderscoreToCameLCaseEnables" value=""/>
   </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>
  
  
  <!-- j将我们写好的sql(EmployeeMapper.xml)映射到全局配置文件(mybatis-config.xml)当中 -->
  <mappers>
    <!--mapper是用来绑定接口的实现类(dao的实现mapper.xml)的-->
    <mapper resource="EmployeeMapper.xml"/>
  </mappers>
</configuration>

(三)typeAliases别名处理标签

typeAliases:别名处理器,可以为我们的java类型起别名,注意别名不区分大小写。

<?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">
  
  
 <!-- Building SqlSessionFactory from XML -->
<configuration>

  <!--
     1.mybatis可以使用properties标签引入外部properties配饰文件的内容
        resource:引入类路径下的内容
        URL:引入网络路径下的文件或者磁盘路径下的文件
  -->
  <properties resource="db.properties"></properties>
  <!-- 
     2.settings包含很多重要的设置
        setting:用来是指每一个设置项
            name:设置项名,mapUnderscoreToCameLCaseEnables,数据库a_count,实体aCount,不会赋值失败,会直接解析为a_count,然后赋值
            value:设置项值      
   -->
   <!-- 
   <settings>
        <setting name="mapUnderscoreToCamelCaseEnables" value="false"/>
   </settings>
    -->
   <!-- 
    3.typeAliases:别名处理器,可以为java类型起别名,别名不区分大小写   
    -->
   <typeAliases>
        <!-- 
            1.typeAlias:为某个java类型起别名
                type:指定起别名的类型全路径,默认名就是类名的小写
                alias:指定新的别名
         -->
        <!-- <typeAlias type="com.neusoft.mybatis.Employee"/> -->
        
        <!-- 
            2.package:为某个包及子包下的类批量起别名
                name:指定报名(为当前包及子包下所有的包的每一个类起一个别名),默认是类名的小写
                注意:在批量其别名的过程当中,可以在类上面使用@Alias注解为某个类型的java类其别名,不区分大小写
         -->
        <package name="com.neusoft.mybatis"/> 
   </typeAliases>
   
  <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>
  
  
  <!-- j将我们写好的sql(EmployeeMapper.xml)映射到全局配置文件(mybatis-config.xml)当中 -->
  <mappers>
    <mapper resource="EmployeeMapper.xml"/>
  </mappers>
</configuration>

(四)environments环境配置标签

environments:环境们,mybatis可以配置多种环境,可以通过default标签来指定使用哪种环境,可以达到快速切换环境
            environment:配置一个具体的环境信息,必须有2个标签transactionManager,dataSource
                transactionManager:事物管理器
                    type:事物管理器的类型,JDBC/MANAGED
                dataSource:数据源
                    type:unpooled,pooled,jndi
                    自定义数据源:实现DataSourceFactory接口,type是类的全类名
<?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">
  
  
 <!-- Building SqlSessionFactory from XML -->
<configuration>

  <!--
     1.mybatis可以使用properties标签引入外部properties配饰文件的内容
        resource:引入类路径下的内容
        URL:引入网络路径下的文件或者磁盘路径下的文件
  -->
  <properties resource="db.properties"></properties>
  <!-- 
     2.settings包含很多重要的设置
        setting:用来是指每一个设置项
            name:设置项名,mapUnderscoreToCameLCaseEnables,数据库a_count,实体aCount,不会赋值失败,会直接解析为a_count,然后赋值
            value:设置项值      
   -->
   <!-- 
   <settings>
        <setting name="mapUnderscoreToCamelCaseEnables" value="false"/>
   </settings>
    -->
   <!-- 
    3.typeAliases:别名处理器,可以为java类型起别名,别名不区分大小写   
    -->
   <typeAliases>
        <!-- 
            1.typeAlias:为某个java类型起别名
                type:指定起别名的类型全路径,默认名就是类名的小写
                alias:指定新的别名
         -->
        <!-- <typeAlias type="com.neusoft.mybatis.Employee"/> -->
        
        <!-- 
            2.package:为某个包及子包下的类批量起别名
                name:指定报名(为当前包及子包下所有的包的每一个类起一个别名),默认是类名的小写
                注意:在批量其别名的过程当中,可以在类上面使用@Alias注解为某个类型的java类其别名,不区分大小写
         -->
        <package name="com.neusoft.mybatis"/> 
   </typeAliases>
   
   <!-- 
        environments:环境们,mybatis可以配置多种环境,可以通过default标签来指定使用哪种环境,可以达到快速切换环境
            environment:配置一个具体的环境信息,必须有2个标签transactionManager,dataSource
                transactionManager:事物管理器
                    type:事物管理器的类型,JDBC/MANAGED
                dataSource:数据源
                    type:unpooled,pooled,jndi
                    自定义数据源:实现DataSourceFactory接口,type是类的全类名
    -->
  <environments default="development">
    <environment id="test">
        <transactionManager type="JDBC"></transactionManager>
        <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>
    
    <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>
  
  
  <!-- j将我们写好的sql(EmployeeMapper.xml)映射到全局配置文件(mybatis-config.xml)当中 -->
  <mappers>
    <mapper resource="EmployeeMapper.xml"/>
  </mappers>
</configuration>

(五)databaseldProvider

可以将我们写的SQL语句转换为指定的数据库厂商的SQL语句
databaseIdProvider:支持多数据库厂商
type="DB_VENDOR":作用是得到数据库厂商的标识(驱动自带的),mybatis就可以根据数据库厂商标识来执行不同的sql.

<?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">
  
  
 <!-- Building SqlSessionFactory from XML -->
<configuration>

  <!--
     1.mybatis可以使用properties标签引入外部properties配饰文件的内容
        resource:引入类路径下的内容
        URL:引入网络路径下的文件或者磁盘路径下的文件
  -->
  <properties resource="db.properties"></properties>
  <!-- 
     2.settings包含很多重要的设置
        setting:用来是指每一个设置项
            name:设置项名,mapUnderscoreToCameLCaseEnables,数据库a_count,实体aCount,不会赋值失败,会直接解析为a_count,然后赋值
            value:设置项值      
   -->
   <!-- 
   <settings>
        <setting name="mapUnderscoreToCamelCaseEnables" value="false"/>
   </settings>
    -->
   <!-- 
    3.typeAliases:别名处理器,可以为java类型起别名,别名不区分大小写   
    -->
   <typeAliases>
        <!-- 
            1.typeAlias:为某个java类型起别名
                type:指定起别名的类型全路径,默认名就是类名的小写
                alias:指定新的别名
         -->
        <!-- <typeAlias type="com.neusoft.mybatis.Employee"/> -->
        
        <!-- 
            2.package:为某个包及子包下的类批量起别名
                name:指定报名(为当前包及子包下所有的包的每一个类起一个别名),默认是类名的小写
                注意:在批量其别名的过程当中,可以在类上面使用@Alias注解为某个类型的java类其别名,不区分大小写
         -->
        <package name="com.neusoft.mybatis"/> 
   </typeAliases>
   
   <!-- 
        environments:环境们,mybatis可以配置多种环境,可以通过default标签来指定使用哪种环境,可以达到快速切换环境
            environment:配置一个具体的环境信息,必须有2个标签transactionManager,dataSource
                transactionManager:事物管理器
                    type:事物管理器的类型,JDBC/MANAGED
                dataSource:数据源
                    type:unpooled,pooled,jndi
                    自定义数据源:实现DataSourceFactory接口,type是类的全类名
    -->
  <environments default="development">
    <environment id="test">
        <transactionManager type="JDBC"></transactionManager>
        <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>
    
    <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>
  
  <!-- 
        5.databaseIdProvider:支持多数据库厂商
        type="DB_VENDOR":作用是得到数据库厂商的标识(驱动自带的),mybatis就可以根据数据库厂商标识来执行不同的sql
   -->
  <databaseIdProvider type="DB_VENDOR">
    <!-- 为不同的数据库厂商起别名 -->
    <property name="MySQL" value="mysql"/>
    <property name="Oracle" value="oracle"/>
    <property name="SQL Server" value="sqlserver"/>
  </databaseIdProvider>
  
  <!-- j将我们写好的sql(EmployeeMapper.xml)映射到全局配置文件(mybatis-config.xml)当中 -->
  <mappers>
    <mapper resource="EmployeeMapper.xml"/>
  </mappers>
</configuration>
***************************************************************************
<?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.neusoft.mybatis.EmployeeMapper">


  <select id="getEmpById" resultType="EMP" databaseId="mysql">
    <!-- select * from tbl_employee where id = #{id} -->
    select id,last_name,email, gender age from tbl_employee where id = #{id}
  </select>
  <select id="getEmpById" resultType="EMP" databaseId="oracle">
    select id,last_name,email, gender age from tbl_employee where id = #{id}
  </select>
</mapper>

(六)mappers标签

mapper标签是全局配置文件用来绑定接口实现类(dao层接口的实现类的mapper.xml)的,当mapper使用class属性时,要求dao和map.xml在同一路径下同名,就可以看作是绑定接口的实现类mapper.xml了,当mapper使用其他属性时,直接绑定mapp.xml即可,更加主观。

<!-- 6.将我们写好的sql(EmployeeMapper.xml)映射到全局配置文件(mybatis-config.xml)当中-->
  <mappers>
    <!-- mapper;注册一个SQL映射
            注册配置文件
                resource:类路径下的SQL映射文件
                url:网络或者磁盘路径下的SQL映射文件的路径
             注册接口
                class:引用(注册)接口
                1.有SQL映射文件,映射文件名和接口必须同名,并且映射文件和接口在同一路径下,之所以要这么做是因为:mapper是全局配置文件用来绑定接口实现类(dao层接口的实现类的mapper.xml)的,当在同一路径下同名时,就可以看作是绑定接口的实现类mapper.xml了
                2.没有SQL映射文件,所有的SQL都是利用注解写在接口上
                推荐使用SQL映射文件的方式来注册
     -->
    <!-- <mapper resource="mybatis/mapper/EmployeeMapper.xml"/> -->
    <!-- <mapper class="com.neusoft.mybatis.dao.EmployeeMapper"/> -->
    <mapper class="com.neusoft.mybatis.dao.EmployeeMapperAnnotation"/>
    
    <!-- 
        批量注册
        注意映射文件要和接口同一包下,而且文件名和接口名相同
        此时其他的方式不可使用,即只使用其一即可
     -->
    <package name="com.neusoft.mybatis.dao"/>
  </mappers>
***********************EmployeeMapperAnnotation***************************
package com.neusoft.mybatis.dao;

import org.apache.ibatis.annotations.Select;

import com.neusoft.mybatis.bean.Employee;

public interface EmployeeMapperAnnotation {

    @Select("select * from tbl_employee where id = #{id} ")
    public Employee getEmpById(Integer id);

}

3.mybatis的SQL映射文件

(一)映射文件指导Mybatis如何进行增删改查,

******************************EmployeeMapper.java*****************************
package com.neusoft.mybatis.dao;

import com.neusoft.mybatis.bean.Employee;

public interface EmployeeMapper {

    public Employee getEmployee(Integer id);
    
    public Long addEmployee(Employee employee);
    
    public Long updateEmployee(Employee employee);
    
    public Boolean deleteEmployee(Integer id);
}

**************************EmployeeMapper.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">
  
<mapper namespace="com.neusoft.mybatis.dao.EmployeeMapper">


    <select id="getEmployee"  resultType="com.neusoft.mybatis.bean.Employee">
        select id,last_name lastName,first_name firstName,age,gender from employee where id=#{id};
    </select>
    <!-- 参数类型:paramerType可以省 -->
    
    <insert id="addEmployee" parameterType="com.neusoft.mybatis.bean.Employee">
        insert into employee(last_name,first_name,age,gender) values (#{lastName},#{firstName},#{age},#{gender});
    </insert>  
    
    <update id="updateEmployee">
        update employee set last_name=#{lastName},first_name=#{firstName},age=#{age},gender=#{gender} where id=#{id}
    </update>
    
    <delete id="deleteEmployee">
        delete from employee where id=#{id}
    </delete>
</mapper>
***********************mybatis-config.xml************************************
<?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 resource="db.properties"></properties>
    <!-- 
    <settings>
        <setting name="mapUnderscoreToCameLCaseEnables" value="true"/>
    </settings>
     -->
    <environments default="develepment">
        <environment id="develepment">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="pooled">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${user}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
  
  
  <!-- 加载SQL映射文件 -->
  <mappers>
    <mapper resource="EmployeeMapper.xml"/>
  </mappers>
  
  </configuration>
**************************mybatisTest*********************************
package com.neusoft.mybatis.test;

import static org.junit.jupiter.api.Assertions.*;

import java.io.IOException;
import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.jupiter.api.Test;

import com.neusoft.mybatis.bean.Employee;
import com.neusoft.mybatis.dao.EmployeeMapper;

class TestMybatis {
    
    public SqlSessionFactory getSqlSessionFactory() throws IOException {
        
        InputStream inputStream=Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
        return sqlSessionFactory;
    }
    /**
     * mybatis允许增删改直接定义以下类型的返回值:
     * Integer,Long,Boolean
     * @throws IOException
     */
    @Test
    public void testMybatis3() throws IOException {
        //1.通过加载全局配置文件获得sqlsessionfanctory
        SqlSessionFactory sqlSessionFactory=getSqlSessionFactory();
        
        //2.获得selSession对象,此时获取的sqlSession不会自动提交 
        SqlSession sqlSession=sqlSessionFactory.openSession();
        
        try {
            //3.通过sqlSession实例执行SQL映射文件当中的SQL语句
            EmployeeMapper employeeMapper=sqlSession.getMapper(EmployeeMapper.class);
            /**
             * 此处的流程是:将以下的几个值设置给employee对象,然后将employee对象传给SQL语句
             * mapper当中获取到employee对象当中的属性值
             * 传过去的employee当中id=null,mapper获取到的id也是null
             */
            Employee addemp=new Employee(null,"罗宾","知识",32,"女");
            //employeeMapper.addEmployee(addemp);
            
            Employee updateemp=new Employee(1,"阿昂萨斯","冰雪王子",34,"男");
            //employeeMapper.updateEmployee(updateemp);
            
            Boolean result=employeeMapper.deleteEmployee(1);
            System.out.println(result);
            //注意除了查询不用提交外,其他的都要提交
            sqlSession.commit();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            sqlSession.close();
        }
    }
}
********************************Employee.java************************************
.......

(二)获取自增主键

<!-- 
        mybatis支持自增主键,自增主键值的获取,mybatis也是采用statement.getGeneratedKeys()获得 
        useGeneratedKeys="true":使用自增主键获取主键值策略
        keyProperty:指定对应的主键属性,也就是mybatis获取到主键值以后,将这个值分装给javaBean的哪个属性
        在本句当中,useGeneratedKeys="true"获取主键的值,然后赋值给ID,keyProperty=“id”
    -->
    <insert id="addEmployee" parameterType="com.neusoft.mybatis.bean.Employee" useGeneratedKeys="true" keyProperty="id">
        insert into employee(last_name,first_name,age,gender) values (#{lastName},#{firstName},#{age},#{gender});
    </insert>  
************************************************************************
@Test
    public void testMybatis3() throws IOException {
        //1.通过加载全局配置文件获得sqlsessionfanctory
        SqlSessionFactory sqlSessionFactory=getSqlSessionFactory();
        
        //2.获得selSession对象,此时获取的sqlSession不会自动提交 
        SqlSession sqlSession=sqlSessionFactory.openSession();
        
        try {
            //3.通过sqlSession实例执行SQL映射文件当中的SQL语句
            EmployeeMapper employeeMapper=sqlSession.getMapper(EmployeeMapper.class);
            /**
             * 此处的流程是:将以下的几个值设置给employee对象,然后将employee对象传给SQL语句
             * mapper当中获取到employee对象当中的属性值
             * 传过去的employee当中id=null,mapper获取到的id也是null
             */
            Employee addemp=new Employee(null,"古踏仙","天符大帝",10000,"男");
            employeeMapper.addEmployee(addemp);
            System.out.println(addemp.getId());
            //Employee updateemp=new Employee(1,"阿昂萨斯","冰雪王子",34,"男");
            //employeeMapper.updateEmployee(updateemp);
            
//          Boolean result=employeeMapper.deleteEmployee(1);
//          System.out.println(result);
            //注意除了查询不用提交外,其他的都要提交
            sqlSession.commit();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            sqlSession.close();
        }
    }

3.mybatis参数处理

如果传入单个参数,Mybatis不会处理,如果传入多个参数,Mybatis会将多个参数封装到map集合当中

单个参数:mybatis不会做特殊处理
    #{参数名}:取出参数值,此时参数名可以随便写,没有要求


    
多个参数:mybatis会做特殊处理
    多个参数会被封装为一个map,
        key:param1,param2.....paramN,或者参数的索引(从0开始)
        value:传入的参数值
    #{}就是从map当中获得指定的key值
    
    异常:org.apache.ibatis.exceptions.PersistenceException: 
    ### Error querying database.  Cause: org.apache.ibatis.binding.BindingException: Parameter 'id' not found. Available parameters are [arg1, arg0, param1, param2]
    ### Cause: org.apache.ibatis.binding.BindingException: Parameter 'id' not found. Available parameters are [arg1, arg0, param1, param2]
    操作:
        方法:public Employee getEmpByIdAndLastName(Integer id,String lastName);
        取值:#{id},#{lastName}
    
    
        
命名空间:明确指定分装参数时map的key
    可以通过在接口的方法当中使用@Param("")注解在明确的指定key
    public Employee getEmpByIdAndLastName(@Param("id") Integer id,@Param("lastName") String lastName);
        key:使用@Param("")注解指定的值
        value:参数值
     #{指定的key/param...}:取出参数值

     
POJO:    
如果多个参数正好是我们业务逻辑的数据模型,我们就可以直接传入pojo
    #{属性名}:取出传入放入pojo的属性值

Map:
如果多个参数不是业务模型当中的数据,没有对应的pojo,我们也可以传入map,
    #{key}:取出map当中对应的值

TO:
如果多个参数不是业务模型当中的数据,但是经常要使用,推荐来编写一个To(Transfer object)数据传输对象
page{
    int index;
    int size;
}

***************************EmployeeMapper.java******************************

package com.neusoft.mybatis.dao;

import java.util.Map;

import org.apache.ibatis.annotations.Param;

import com.neusoft.mybatis.bean.Employee;

public interface EmployeeMapper {
    
    public Employee getEmpByMap(Map<String,Object> map);
    
    public Employee getEmpByIdAndLastName(@Param("id") Integer id,@Param("lastName") String lastName);

    public Employee getEmployee(Integer id);
    
    public Long addEmployee(Employee employee);
    
    public Long updateEmployee(Employee employee);
    
    public Boolean deleteEmployee(Integer id);
}
*************************EmployeeMapper.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">
  
<mapper namespace="com.neusoft.mybatis.dao.EmployeeMapper">

    <select id="getEmpByMap" resultType="com.neusoft.mybatis.bean.Employee">
                select id,last_name lastName,first_name firstName,age,gender from employee where id=#{id1} and last_name=#{lastName1}
    </select>
    <select id="getEmpByIdAndLastName"  resultType="com.neusoft.mybatis.bean.Employee">
        select id,last_name lastName,first_name firstName,age,gender from employee where id=#{id} and last_name=#{lastName}
    </select>
    <select id="getEmployee"  resultType="com.neusoft.mybatis.bean.Employee">
        select id,last_name lastName,first_name firstName,age,gender from employee where id=#{id1232} ;
    </select>
    
    <!-- 参数类型:paramerType可以省 -->
    <!-- 
        mybatis支持自增主键,自增主键值的获取,mybatis也是采用statement.getGeneratedKeys()获得 
        useGeneratedKeys="true":使用自增主键获取主键值策略
        keyProperty:指定对应的主键属性,也就是mybatis获取到主键值以后,将这个值分装给javaBean的哪个属性
        在本句当中,useGeneratedKeys="true"获取主键的值,然后赋值给ID,keyProperty=“id”
    -->
    <insert id="addEmployee" parameterType="com.neusoft.mybatis.bean.Employee" useGeneratedKeys="true" keyProperty="id">
        insert into employee(last_name,first_name,age,gender) values (#{lastName},#{firstName},#{age},#{gender});
    </insert>
    <!-- 
        oracle不支持自增:Oracle使用序列来模拟自增
        每次插入的数据的主键都是从序列当中拿到的值,下面讲述如何获得这个值
        order="BEFORE":当前SQL在插入之前允许
        resultType:查处的属性返回值类型
     -->  
     <insert id="addemp" databaseId="oracleId" >
        <selectKey keyProperty="id" order="BEFORE" resultType="Integer">
            select ENPLOYEES_SEQ.nextval from dual
        </selectKey>
        insert into employee(EMPOYEE_ID,Last_name,email) values(#{id},#{lastName},#{email})
     </insert>
    
    <update id="updateEmployee" >
        update employee set last_name=#{lastName},first_name=#{firstName},age=#{age},gender=#{gender} where id=#{id}
    </update>
    
    <delete id="deleteEmployee">
        delete from employee where id=#{id}
    </delete>
</mapper>
*************************TestMybatis********************************
    @Test
    public void testMybatis2() throws IOException {
        
        //1.通过加载全局配置文件获得sqlsessionfanctory
        SqlSessionFactory sqlSessionFactory=getSqlSessionFactory();
        //2.获得selSession对象
        SqlSession sqlSession=sqlSessionFactory.openSession();
        
        try {
            //3.通过sqlSession实例执行SQL映射文件当中的SQL语句
            EmployeeMapper employeeMapper=sqlSession.getMapper(EmployeeMapper.class);
            //Employee employee=employeeMapper.getEmployee(2);
            //Employee employee=employeeMapper.getEmpByIdAndLastName(3, "知识");
            Map<String,Object> map=new HashMap<>();
            map.put("id1", 3);
            map.put("lastName1", "知识");
            Employee employee=employeeMapper.getEmpByMap(map);
            System.out.println(employee);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            sqlSession.close();
        }
    }

4.mybatis取值

===========================参数值的获取======================
#{}:可以获取map当中的值,或者pojo对象属性的值
${}:可以获取map当中的值,后者pojo对象的属性值
    区别:
        #{}:是以预编译的形式,将参数设置到sql语句当中,PrepareStatement,防止SQL注入
        ${}:取出的值直接拼装在SQL语句当中,会有安全问题
        大多数情况下,我们取参数的值都要采用#{}
        
        原生的JDBC不支持占位符的地方我们可以使用${}进行取值
        比如分表/排序:按照年份拆分
            select * from ${year}_salary where xxx;
            select * from tbl_employee order by ${f_name};
    
#{}:更丰富的用法,
    规定参数的一些规则:
        javaType,jdbcType,mode(存储过程),numericScale,resultMap,typeHandler
            ,jdbcTypeName,expression(未来打算支持的功能)
        jdbcType:通常需要在某种特定的条件下被设置,在我们的数据为null的时候,有些数据库可能不能识别mybatis
            对null的默认处理,比如Oracle(报错)
            JdbcType other:无效的类型,因为mybatis对所有的null都映射的是原生的JDBC的other类型,oracle不能正确处理
            1.#{email,jdbcType=OTHER};
            2.全局配置<setting name="jdbcTypeForNull" value="Null">

<select id="gettableById" resultType="com.neusoft.mybatis.bean.Employee">
        select * from ${tableName} where id=#{id} 
    </select>

5.select查询

如果想要将查出来的记录封装成什么,那么resultType就是什么。查询出来的结果通过调用pojo的set方法将结果封装起来,所以resultType用来封装查询出来的结果,resultType可以把查询结果封装到pojo类型中,但必须pojo类的属性名和查询到的数据库表的字段名一致

select元素用来定义查询操作:
id:唯一标识符
parameterType:传入参数的类型,可以不写,mybatis会根据TypeHandler自动判断
resultType:返回值类型,别名或者全类名,如果返回的是集合,定义集合当中的元素类型,不能和resultMap同时使用

    /**
     * 多条记录封装一个map,Map<Integer,Employee>,键是这条记录的主键,值是这条记录封装后的javabean
     * 使用如下的注解告诉mybatis封装这个map的时候使用哪个属性作为map的key
     * 即在查询出来的map集合当中,key是注解所指定的属性(javaBean)
     * *******************************************************
     * *    <select id="getEmpByLastNameLikeRetuenMap" resultType="com.neusoft.mybatis.bean.Employee">
     * *        select * from employee where last_name like #{}
     * *    </select>
     * ********************************************************
     * *    Map<String, Employee> map2=employeeMapper.getEmpByLastNameLikeRetuenMap("%帝%");
     * *    System.out.println(map2);
     * *    {天符大帝=Employee [id=6, firstName=古踏仙, lastName=天符大帝, age=10000, gender=男], 龙符大帝=Employee [id=5, firstName=古淋砂, lastName=龙符大帝, age=10000, gender=男]}
     * *
     * ********************************************************
     */
    @MapKey("lastName")
    public Map<String,Employee> getEmpByLastNameLikeRetuenMap(String lastName);
    /**
     * 返回一条记录的map,key就是列名,值就是对应的值
     * ******************************************
     * *    <!-- 如果想要让查询出来的值封装在map里面,可以让resultType="map" -->
     * *    <select id="getEmpByReturnMap" resultType="map">
     * *        select * from employee where id=#{id}
     * *    </select>
     * ******************************************
     * *    Map<String,Object> map1=employeeMapper.getEmpByReturnMap(3);
     * *    System.out.println(map1);
     * *    {gender=女, last_name=知识, id=3, first_name=罗宾, age=32}
     * ************************************************************
     */
    public Map<String,Object> getEmpByReturnMap(Integer id);
    
    public List<Employee> getEmpsByLastName(String lastName);
    
    public Employee gettableById(@Param("id")Integer id,@Param("tableName")String tableName);
    
    public Employee getEmp(Integer id,Employee emloyee);
    
    public Integer getEmpCount();
    
    public Employee getEmpByMap(Map<String,Object> map);
    
    public Employee getEmpByIdAndLastName(@Param("id") Integer id,@Param("lastName") String lastName);

    public Employee getEmployee(Integer id);
    
    public Long addEmployee(Employee employee);
    
    public Long updateEmployee(Employee employee);
    
    public Boolean deleteEmployee(Integer id);
}

6.自定义resultMap实现高级结果集映射

resultType将查询出来的结果和实体类当中的属性做映射,resultMap可以对查询出来的记过进行新操作,resultMap以自定义某个JavaBean的封装规则。
如果sql查询到的字段与pojo的属性名不一致,则需要使用resultMap将字段名和属性名对应起来,进行手动配置封装,将结果映射到pojo中

(一)resultMap自定义结果集映射规则

*****************************Employee.java*****************************
package com.neusoft.mybatis.bean;

public class Employee {
    
    private Integer id;
    
    private String firstName;
    
    private String lastName;
    
    private Integer age;
    
    private String gender;
    
    private Department dept;

    public Department getDept() {
        return dept;
    }

    public void setDept(Department dept) {
        this.dept = dept;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    
    public Employee() {
        super();
    }

    public Employee(Integer id,String firstName, String lastName, Integer age, String gender) {
        super();
        this.id=id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Employee [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", age=" + age
                + ", gender=" + gender + "]";
    }
    
}
*****************************EmployeeMapperPlus.java***************************
package com.neusoft.mybatis.dao;

import com.neusoft.mybatis.bean.Employee;

public interface EmployeeMapperPlus {

    public Employee getEmpById(Integer id);
    
    public Employee getEmpAndDept(Integer id);
    
    public Employee getEmpAndDept1(Integer id);

}
*****************************EmployeeMapperPlus.xml***************************
<!-- 
        自定义某个JavaBean的封装规则
        type:自定义java的类型
        id:唯一 ID方便引用
    -->
    <resultMap type="com.neusoft.mybatis.bean.Employee" id="MySimpleEmp">
        <!-- 
            指定主键列的封装规则:
                id定义主键底层会有优化
                column:指定哪一列
                property:指定对应javaBean属性
              此时调用的是pojo对象的set方法进行设置
         -->
        <id column="id" property="id"/>
        <!-- 其他不指定的列会自动封装:我们只要写resultMap就会把全部的映射规则都写上 -->
        <result column="last_name" property="lastName"/>
        <result column="first_name" property="firstName"/>
        <result column="age" property="age"/>
        <result column="gender" property="gender"/>
    </resultMap>
      <!--当然也可以直接使用构造器进行设置,当使用构造器进行设置的时候注意字段要的顺序要对应上-->
    <!-- resultMap:自定义结果集映射规则 -->
    <select id="getEmpById" resultMap="MySimpleEmp">
        select * from employee where id=#{id}
    </select>

(二)resultMap级联属性

<!-- 联合查询:级联属性封装结果集,方式一 -->
    <resultMap type="com.neusoft.mybatis.bean.Employee" id="MyDiEmp">
        <id column="id" property="id"/>
        <result column="last_name" property="lastName"/>
        <result column="first_name" property="firstName"/>
        <result column="gender" property="gender"/>
        <result column="age" property="age"/>
        <result column="dept_name" property="dept.deptName"/>
        <result column="dept_id" property="dept.id"/>
    </resultMap>
<!-- 
        场景一:查询Employee的同时查询员工对应的部门
     -->
    <select id="getEmpAndDept1" resultMap="MyDiEmp">
        select e.id,last_name,first_name,age,gender,d.id d_id ,dept_name,dept_id from  employee e,department d where e.id=d.dept_id and e.id=#{id}; 
    </select>
*********************************************************************
Employee employee=employeeMapperPlus.getEmpAndDept(3);
System.out.println(employee);
System.out.println(employee.getDept());
//Employee [id=3, firstName=罗宾, lastName=知识, age=32, gender=女]
//Department [id=3, deptName=销售]

(三)resultMap级联属性之association

<!-- 使用association可以指定单个对象的封装规则 -->
    <!-- 联合查询:级联属性封装结果集,方式二 -->
    <resultMap type="com.neusoft.mybatis.bean.Employee" id="MyDiEmp1">
        <id column="id" property="id"/>
        <result column="last_name" property="lastName"/>
        <result column="first_name" property="firstName"/>
        
        <!-- 
            associaation可以指定联合的javaBean对象
            property:指定哪个属性是联合的对象
            javaType:指定这个属性对象的类型(不可少)
        -->
        <association property="dept" javaType="com.neusoft.mybatis.bean.Department">
            <id column="d_id" property="id"/>
            <result column="dept_name" property="deptName"/>
        </association>
    </resultMap>
    <!-- 
        场景一:查询Employee的同时查询员工对应的部门
     -->
    <select id="getEmpAndDept1" resultMap="MyDiEmp1">
        select e.id,last_name,first_name,age,gender,d.id d_id ,dept_name,dept_id from  employee e,department d where e.id=d.dept_id and e.id=#{id}; 
    </select>

(四)使用association进行分步查询

使用association进行分步查询:
        1.先根据员工的ID查询出员工信息
        2.根据查询出得员工的dept_id,查询出部门的信息
        3.将查询出的部门信息存放在员工当中
<!-- 
        使用association进行分步查询:
        1.先根据员工的ID查询出员工信息
        2.根据查询出得员工的dept_id,查询出部门的信息
        3.将查询出的部门信息存放在员工当中
     -->
    <resultMap type="com.neusoft.mybatis.bean.Employee" id="MyEmpStep">
        <id column="id" property="id"/>
        <result column="last_name" property="lastName"/>
        <result column="first_name" property="firstName"/>
        <result column="age" property="age"/>
        <result column="gender" property="gender"/>
        <!-- 
            association定义关联对象的封装规则 
            select:表名当前属性是调用select指定的方法查出的结果
            column:指定将哪一列的值传递给这个方法,在此处是将dept_id传递给getDeptById方法
        -->
        <association property="dept" select="com.neusoft.mybatis.bean.DepartmentMapper.getDeptById"
                column="detp_id">
        </association>
    </resultMap>
    <select id="getEmpByIdStep" resultMap="MyEmpStep">
        select id dept_id,last_name,first_name from employee where id=#{id}
    </select>
****************************************************************************************
<mapper namespace="com.neusoft.mybatis.dao.DepartmentMapper">
    
    <select id="getDeptById" resultType="com.neusoft.mybatis.bean.Department">
        select * from department where dept_id=#{dept_id}
    </select>
</mapper>

(五)延迟加载

<!-- 
        可以使用延迟加载:
        我们每次查询Employee对象的时候,都会一起将dept查询出来
        部门信息在我们使用的时候再去查询
        分段查询的基础之上加上2个配置
        <settings>
            <setting name="lazyLoadingEnabled" value="true"/>
            <setting name="aggressiveLazyLoading" value="false"/>
        </settings>
 -->

7.collection定义关联集合封装规则

(一)collection嵌套结果集查询

<?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.neusoft.mybatis.dao.DepartmentMapper">
    
    <!-- collection嵌套结果集的方式,定义关联的集合元素的封装规则 -->
    <resultMap type="com.neusoft.mybatis.bean.Department" id="MyDept">
        <id column="did" property="id"/>
        <result column="dept_name" property="deptName"/>
        <!-- 
            Collection:定义关联的集合类型的属性的封装规则 
            ofType:定义集合里面元素的类型
        -->
        <collection property="emps" ofType="com.neusoft.mybatis.bean.Employee">
            <!-- 定义集合当中元素的封装规则 -->
            <id column="id" property="id"/>
            <result column="last_name" property="lastName"/>
            <result column="first_name" property="firstName"/>
            <result column="age" property="age"/>
            <result column="gender" property="gender"/>
            
        </collection>
    </resultMap>
    <select id="getDeptByIdPlus" resultMap="MyDept">
        SELECT
            d.id did,
            d.dept_name,
            e.id,
            e.last_name,
            e.first_name,
            e.age,
            e.gender 
        FROM
            department d
            LEFT JOIN employee e ON d.dept_id = e.id 
        WHERE
            d.id = #{id};
    </select>
</mapper>
**************************************************************************************
package com.neusoft.mybatis.dao;

import com.neusoft.mybatis.bean.Department;

public interface DepartmentMapper {

    public Department getDeptById(Integer id);
    
    public Department getDeptByIdPlus(Integer id);
}
**************************************************************************************
public class Department {

    private Integer id;
    
    private String deptName;
    
    private List<Employee> emps;
    .........
} 

(二)扩展:多列的值传递过去

<!-- 扩展:多列的值传递过去
        将多列的值封装map传递
        column="{key1=column1,key2=column2}"
     -->
    <resultMap type="com.neusoft.mybatis.dao.DepartmentMapper" id="MyDeptStep">
        <id column="id" property="id"/>
        <result column="dept_name" property="deptName"/>
        <collection property="emps" select="com.neusoft.mybatis.dao.EmployeeMapperPlus.getEmpsByDeptId"
            column="id">
            <!-- column="{dept_id=id}" -->
        </collection>
    </resultMap>
    <select id="getDeptByIdStep" resultMap="MyDeptStep">
        select id,dept_id,dept_name from department where id=#{id}
    </select>

(三)鉴别器

<!--
        场景二:查询部门的时候,将部门对应的所有的员工查询出来 
     -->
    <select id="getEmpsByDeptId" resultType="com.neusoft.mybatis.bean.Employee">
        select * from employee where id=#{id}
    </select>
    
    <!-- 鉴别器:mybatis可以使用discriminator判断某列的值,然后根据某列的值改变封装行为
            封装Employee
                如果查询出的是女生,就把部门的信息查询出来,否则不查询
                如果是男士,把last_name赋值给first_name
     -->
     <resultMap type="com.neusoft.mybatis.bean.Employee" id="MyEmpDis">
        <id column="id" property="id"/>
        <result column="last_name" property="lastName"/>
        <result column="first_name" property="firstName"/>
        <!-- column:指定判断的列名,javaType:列值对应的java类型 -->
        <discriminator javaType="string" column="gender">
            <!-- 女生 ,指定封装的结果类型-->
            <case value="0" resultType="com.neusoft.mybatis.bean.Employee">
                <association property="dept" javaType="com.neusoft.mybatis.bean.Department">
                    <id column="d_id" property="id"/>
                    <result column="dept_name" property="deptName"/>
                </association>
            </case>
            <!-- 男士 -->
            <case value="1" resultType="com.neusoft.mybatis.bean.Employee">
                <id column="id" property="id"/>
                <result column="last_name" property="FirstName"/>
                <result column="first_name" property="firstName"/>
            </case>
        </discriminator>
        
     
     </resultMap>
     
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,607评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,239评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,960评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,750评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,764评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,604评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,347评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,253评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,702评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,893评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,015评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,734评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,352评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,934评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,052评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,216评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,969评论 2 355

推荐阅读更多精彩内容

  • 我的思维方式 1.逆向思维。查理芒格常说,“如果我知道我要死在哪里,我就永远不会去那个地方”,”反过来想,你总是要...
    独角神兽阅读 194评论 0 0
  • 很多东西,不是从理论开始的,先有个大致印象,然后就慢慢从错误中积累,然后再去印证理论
    逐鹿不顾兔208阅读 139评论 0 0
  • 蚕宝宝特别特别的小,要仔细的观察才能够看得清楚,每天吃完午饭,孩子们都会去观察蚕宝宝,给它喂食桑叶,有的孩子还用画...
    黄璐高实幼阅读 297评论 0 0
  • 我在最没有能力的年纪,碰见了最想照顾一生的人。 —网易云音乐@有梦才能活 评论老狼《同桌的你》 “你还记得她吗?”...
    城居笔记阅读 588评论 0 4