mybatis

一、总体介绍:
    MyBatis实际上是Ibatis3.0版本以后的持久化层框架【也就是和数据库打交道的框架】!
    
    和数据库打交道的技术有:
    原生的JDBC技术---》Spring的JdbcTemplate技术
       
    这些工具都是提供简单的SQL语句的执行,但是和我们这里学的MyBatis框架还有些不同,
    框架是一整套的东西,例如事务控制,查询缓存,字段映射等等。
    
    我们用原生JDBC操作数据库的时候都会经过:
     编写sql---->预编译---->设置参数----->执行sql------->封装结果

   
    我们之所以不使用原生的JDBC工具,是因为这些工具:
    
      1.功能简单,sql语句编写在java代码里面【一旦修改sql,就需要将java及sql都要重新编译!】这属于硬编码高耦合的方式。
      
      2.我们希望有开发人员自己编写SQL语句,
        并且希望SQL语句与java代码分离,
        将SQL语句编写在xml配置文件中,
        实现数据表中记录到对象之间的映射!

  我们使用MyBatis框架,是因为:     
        sql和java编码分开,功能边界清晰,一个专注于业务,一个专注于数据,可以使用简单的
        XML或注解用于配置和原始映射,将接口和Java的POJO映射成数据库中的记录,完成
        业务+底层数据库的媒介!

相较于原生jdbc:
    原生jdbc中将jdbc配置,数据库连接、sql语句以及对数据库的操作放在一个java中,sql和java编码混在一起.
    
    mybatis将sql和java编码分离,数据库连接代码等内容封装到mysql jar包中,再将数据库执行等一系列代码封装到mybatis等jar包中,我们使用时将 mybatis的全局配置文件、 sql映射文件配置好,使用时只需在sql映射文件xxxmapper.xml中设置sql语句的映射信息,在mapper类中设置要执行的操作,在如测试类中执行即可。(而不用向原生中每个语句一个连接与方法)

mybatis使用流程:
1、在数据库中创建表格;
2、创建动态WEB工程,创建与表格相对应的实体类(POJO对象);
3、导入jar包;
4、如mybatis.xml全局配置文件中连接数据库,并将ql映射文件注册到全局配置文件中
(我们要执行的sql语句全在xxxmapper.xml文件中,创建映射后sql语句才可执行)
5、mapper接口类,连接xxxmapper.xml文件;
6、测试类
mybatis相比较于原生jdbc

二、

1.MyBatis历史
    原是Apache的一个开源项目iBatis,  2010年6月这 个项目由Apache Software Foundation 迁移
    到了 Google Code,随着开发团队转投Google Code 旗下, iBatis3.x正式更名为MyBatis ,代码于 2013年11月迁移到Github(下载地址见后)。

    iBatis一词来源于“internet”和“abatis”的组合,是 一个基于Java的持久层框架。
    iBatis提供的持久 层框架包括SQL  Maps和Data  Access  Objects、(DAO)

2.MyBatis简介:
    MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。
    MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。
    MyBatis可以使用简单的XML或注解用于配置和原 始映射,将接口和
       Java的POJO(Plain Old JavaObjects,普通的Java对象)映射成数据库中的记录.
       
       
3.为什么要使用MyBatis?
    MyBatis是一个半自动化的轻量级的持久化层框架。
    JDBC
        –    SQL夹在Java代码块里,耦合度高导致硬编码内伤
        –    维护不易且实际开发需求中sql是有变化,频繁修改的情况多见
    
    Hibernate和JPA
        –    长难复杂SQL,对于Hibernate而言处理也不容易
        –    内部自动生产的SQL,不容易做特殊优化。
        –    基于全映射的全自动框架,大量字段的POJO进行部分映射时比较困难。 导致数据库性能下降。
        
    对开发人员而言,核心sql还是需要自己优化,sql和java编码分开,功能边界清晰,一个专注业务、 一个专注数据。
           
       
4.去哪里找MyBatis?
    https://github.com/mybatis/mybatis-3/
    
    或者在百度直接搜索mybatis,然后找到github下的地址下载即可!

5.创建一个简单的MyBatis的HelloWorld:

1.创建数据库及数据表
        CREATE DATABASE mytabis;
        CREATE TABLE tbl_employee(
          id INT(11) PRIMARY KEY AUTO_INCREMENT,
          last_name VARCHAR(255),
          gender CHAR(1),
          email VARCHAR(255)
        )
    
       然后插入两条数据;
     
    2.创建一个动态WEB工程,然后创建与上述数据表对应的实体类:
    3.[参考mybatis官方文档]加入需要的jar包[mybatis所需要的jar包,和数据库打交道的jar包,以及看打印日志所需要的log4j的jar包]:
       
        log4j-1.2.17.jar  //当然需要注意的是:log4j的jar包是需要log4j.xml文件的
        mybatis-3.4.1.jar  
        mysql-connector-java-5.1.37-bin.jar

    
    4.创建mytabis-config.xml文件并将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>
            <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/mytabis"/>
                        <property name="username" value="root"/>
                        <property name="password" value="123456"/>
                    </dataSource>
                </environment>
            </environments>
            <!-- 将我们写好的sql映射文件一定要注册到全局配置文件中 -->
            <mappers>
                <mapper resource="EmployeeMapper.xml"/>
            </mappers>
        </configuration>
        
    5.创建测试用例,.复制mybatis官方文档代码,代码如下:
        public class MyBatisTest {
            @Test
            public void test() throws IOException {
                String resource = "mytabis-config.xml";
                InputStream inputStream = Resources.getResourceAsStream(resource);
                SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
                
                SqlSession sqlSession =null;
                try{
                    //2.获取sqlSession实例,能直接执行已经映射的SQL语句
                    sqlSession= sqlSessionFactory.openSession();
                    //需要两个参数,第一个参数是sql语句的唯一标识,
                    //第二个参数是执行sql要用的参数
                    Employee employee = sqlSession.selectOne("com.neuedu.mybatis.EmployeeMapper.selectEmp",1);
                    System.out.println(employee);
                }catch(Exception e){
                    
                }finally{
                    sqlSession.close();
                }
                
            }

        }
        
     6. 创建sql语句的映射文件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.neuedu.mybatis.EmployeeMapper">
             <!-- 
                namespace:名称空间
                id:sql语句的唯一标识
                resultType:返回值类型
                #{id}:接收参数传递过来的id值
              -->
                <select id="selectEmp" resultType="com.neuedu.mybatis.bean.Employee">
                    select id,last_name lastName,gender,email from tbl_employee where id = #{id}
                </select>
            </mapper>
     
     7.总结:
        HelloWorld简单版
            – 创建一张测试表
            –创建对应的javaBean
            –创建mybatis配置文件,sql映射文件
            – 测试
            /**
             * 1.根据xml配置文件(全局配置文件)创建一个SqlSessionFactory对象
             *   有数据源的一些运行环境信息
             * 2.sql映射文件,配置了每一个sql,以及sql的封装规则等。
             * 3.将sql映射文件注册在全局配置文件中
             * 4.写代码:
             *    1)根据全局配置文件得到SqlSessionFactory
             *    2)使用sqlSession工厂,获取到sqlSession对象使用它来执行增删改查!
             *     sqlSession就是代表和数据库的一次会话!用完要关闭!
             *    3)使用sql的唯一标识告诉MyBatis执行哪个sql。而sql都是保存
             *      在sql映射文件中的。
             */
MyBatis的基础使用

上面那种开发方式适合老版本的mybatis使用者的开发方式!而新一批的mybatis使用者都是使用接口的方式,如下所示:

HelloWorld-接口式编程
    – 创建一个xxxMapper接口
    – 修改xxxMapper.xml文件
    – 测试
    
 以前都是需要为接口写一个实现类,这是以前,但是此时,mybatis提供了接口可以与sql配置文件动态绑定!
 那如何将两者进行绑定呢?以前sql配置文件的namespace可以随便写,现在就不能随便写了,需呀指定为接口的全限定名!
 然后此时接口和sql配置文件做了绑定,然后还要将select标签的id和方法名进行绑定,
    
总结:
    1.接口式编程
                    原生:                  Dao  ==================>  DaoImpl
                    mybatis:               xxMapper ================>  xxMapper.xml
    2.SqlSession代表和数据库的一次会话,用完必须关闭。
    3.SqlSession和Connection一样,都是非线程安全的,每次使用都是应该去获取新的对象,不要将这个对象定义在类变量中使用!
    4.mapper接口没有实现类,但是mybatis这个接口生成一个代理对象
            <!--将接口与xml文件进行绑定 -->
        EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
    5.两个重要的配置文件
       mybatis的全局配置文件:包含数据库连接池信息,事务管理器信息等..系统运行环境信息。
       sql映射文件:保存了每一个sql语句的映射信息。
接口式编程

三、MyBatis-全局配置文件

MyBatis 的配置文件包含了影响 MyBatis 行为甚深的 设置(settings)和属性(properties)信息。文档的 顶层结构如下:

    configuration 配置
    properties 属性:可以加载properties配置文件的信息
    settings 设置:可以设置mybatis的全局属性
    typeAliases 类型命名
    typeHandlers 类型处理器
    objectFactory 对象工厂
    plugins 插件
    environments 环境
    environment 环境变量
    transactionManager 事务管理器
    dataSource 数据源
    databaseIdProvider 数据库厂商标识
    mappers 映射器




  1.为全局配置文件绑定dtd约束:
     1)联网会自动绑定
     2)没网的时候【/org/apache/ibatis/builder/xml/mybatis-3-config.dtd】:解压mybatis 的jar包然后在eclipse中绑定
     
  2. properties属性
      <configuration>
        <!-- 
            1.mybatis可以使用properties来引入外部properties配置文件的内容
              resource:引入类路径下的资源
              url:引入网络路径或者磁盘路径下的资源
         -->
           <properties resource="jdbc.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.user}"/>
                        <property name="password" value="${jdbc.passowrd}"/>
                    </dataSource>
                </environment>
            </environments>
            <!-- 将我们写好的sql映射文件一定要注册到全局配置文件中 -->
            <mappers>
                <mapper resource="EmployeeMapper.xml"/>
            </mappers>
        </configuration>

   3.settings包含很多重要的设置项
        setting:用来设置每一个设置
            name:设置项名
            value:设置项取值
        
        举例:驼峰式命名
           <settings>
                <setting name="mapUnderscoreToCamelCase" value="true"/>
           </settings>
        
        1).mapUnderscoreToCamelCase:自动完成数据表标准列名和持久化类标准属性名之间的映射。
           例如:last_name和lastName
        
        
   4.typeAliases:【不建议大家使用别名】
        作用:A type alias is simply a shorter name for a Java type
        
           <!-- typeAliases:别名处理器,可以为我们的java类型起别名,别名不区分大小写 -->
           <typeAliases>
           <!-- typeAlias:为某个java类型起别名
                type:指定要起别名的类型全类名;默认别名就是类名小写;
                alias:执行新的别名
            -->
                <typeAlias type="com.neuedu.mybatis.bean.Employee"/>
                <!-- 
                    package:为某个包下的所有类批量起别名
                       name:指定包名(为当前包以及下面所有的后代包的每一个类都起一个默认别名【类名小写】)
                 -->
                <package name="com.neuedu.mybatis.bean"/>
                <!-- 批量起别名的情况下,使用@Alias注解为某个类型指定新的别名 -->
           </typeAliases>
     

       虽然有这么多的别名可以使用:但是建议大家还是使用全类名,看SQL语句是怎么被封装为JAVA 对象的时候简单!
       
       
    5.typeHandlers:类型处理器
      类型处理器:负责如何将数据库的类型和java对象类型之间转换的工具类
      
    6.environments【用于配置MyBatis的开发环境】
       <!-- 
           environments:环境们,mybatis可以配置多种环境,default指定使用某种环境。可以达到快速切换环境。
             environment:配置一个具体的环境信息;必须有两个标签;id代表当前环境的唯一标识
                 transactionManager:事务管理器
            type:事务管理器的类型;type="[JDBC|MANAGED]"),这两个都是别名,在Configuration类中可以查看具体类!但是Spring对事务的控制才是最终的管理方案!
                    JDBC:这个配置就是直接使用了JDBC的提交和回滚设置,它依赖于从数据源得到的连接来管理事务。
                    MANAGED:这个配置几乎没做什么,它从来不提交和回滚一个连接。而是让容器来管理事务的整个生命周期。
                    
                     所以综上:这里如果要配置事务处理器,就配置为JDBC。表示使用本地的JDBC事务。
                     
                          当然也可以自定义事务管理器:只需要和人家一样实现TransactionFactory接口,type指定为全类名。
                 dataSource:数据源
                     type:type="[UNPOOLED|POOLED|JNDI]"
                      unpooled:无数据库连接池
                      pooled:有数据库连接池
                      JNDI:
                     自定义数据源:实现DataSourceFactory接口,type也是全类名
                 
                但是我们也说了,无论是事务管理器的配置还是数据源的配置我们都会使
                用spring来做,这里只需要了解一下即可!
                 
    -->
    <environments default="development">
        <environment id="test">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.user}"/>
                <property name="password" value="${jdbc.passowrd}"/>
            </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.user}"/>
                <property name="password" value="${jdbc.passowrd}"/>
            </dataSource>
        </environment>
    </environments>

    
    补充:这里可以了解一下如何配置第三方数据源:
    定制自己的第三方数据源,如下所示:
      要求:需要自定义一个类继承UnpooledDataSourceFactory类,然后在构造器中初始化该对应的dataSource属性,如下所示:
      
        自定义类为:
            public class C3P0DataSource  extends UnpooledDataSourceFactory{
                public C3P0DataSource() {
                    this.dataSource = new ComboPooledDataSource(); 
                }
            }
            
        MyBatis的全局配置文件为:
                        <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> -->
                            <!-- 配置使用第三方的数据源。属性需要配置为第三方数据源的属性 -->
                            <dataSource type="com.neuedu.mapper.C3P0DataSource">
                                <property name="driverClass" value="${jdbc.driver}"/>
                                <property name="jdbcUrl" value="${jdbc.url}"/>
                                <property name="user" value="${jdbc.username}"/>
                                <property name="password" value="${jdbc.password}"/>
                            </dataSource>
                        </environment>
        测试类:
            @Test
            public void test02(){
                //1.获取sqlSessionFactory对象
                SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
                //2.利用sqlSessionFactory对象创建一个SqlSession对象
                SqlSession session = sqlSessionFactory.openSession();
                System.out.println(session.getConnection());
                //提交事务
                session.commit();
            }
      当然这里需要加入c3p0的jar包;
        c3p0-0.9.2.1.jar
        mchange-commons-java-0.2.3.4.jar
        
7.MyBatis的增删改查标签:
    <select></select>
    <insert></insert>
    <update></update>
    <delete></delete>
    例如:
        <insert id="saveEmployee">
            INSERT INTO tbl_employee(user_name,email,gender) VALUES(#{userName},#{email},#{gender})
        </insert>
        
    其它类同:
    
    
    7.databaseIdProvider环境
        MyBatis is able to execute different statements depending on your database vendor. The
        ?    MyBatis 可以根据不同的数据库厂商执行不同的语句
        
        <databaseIdProvider type="DB_VENDOR">
            <property name="SQL Server" value="sqlserver"/>
            <property name="DB2" value="db2"/>
            <property name="Oracle" value="" />
            <property name="MySQL" value="" />
        </databaseIdProvider>
        
        Type: DB_VENDOR
            –使用MyBatis提供的VendorDatabaseIdProvider解析数据库 厂商标识。也可以实现DatabaseIdProvider接口来自定义。
        Property-name:数据库厂商标识
        Property-value:为标识起一个别名,方便SQL语句使用

        

        这样在执行不同数据库的时候,就会执行不同数据库的语句了!当然如上所示:当有指定
        了databaseId属性的和没有指定databaseId属性的,都有的情况下那就按着有指定databaseId属性的sql语句执行!
        所以:databaseId属性:
              1).对于不同的数据库,做不同的SQL操作时,SQL语句会有不同。例如:
                 MySQL和Oracle的分页[mysql分页为limit,而ORACLE分页我们使用rownumber]、插入主键的方式。
                    MySQL:INSERT INTO tbl_employee(user_name,email,gender) VALUES(#{userName},#{email},#{gender})
                    ORACLE:INSERT INTO employee(id,user_name,email) VALUES(test.seq.nextval,#{userName},#{email})
                所以要想使用ORACLE的自增序列还需要创建一个序列:
                如下所示:
                create sequence test_seq start with 1;
                    
       这样做的好处:在service层只需要调用一个mybatis的方法,而不需要关注底层选择使用的数据库。
        employeeDao.insert(employee);
        
        那么:mybatis如何区分使用的是哪个数据库呢?使用databaseId属性
          ①.在mybatis-config.xml文件中进行配置
                  <databaseIdProvider type="DB_VENDOR">
                    <property name="ORACLE" value="oracle"/>
                    <property name="MySQL" value="mysql"/>
                </databaseIdProvider>
            
          ②.在mybatis的映射文件中使用databaseId来区分使用的是哪一个数据库
                在mybatis的全局配置文件配置了这个之后,我们只需要在sql映射文件中通过在执行语句的标签上加一个属性databaseId即可!
                <select id="getEmployeeById" resultType="emp">
                    select * from tbl_employee where id = #{id}
                </select>
                <select id="getEmployeeById" resultType="emp" databaseId="mysql">
                    select * from tbl_employee where id = #{id}
                </select>
                <select id="getEmployeeById" resultType="emp" databaseId="oracle">
                    select * from tbl_employee where id = #{id}
                </select>

                 
            <environments default="dev_mysql">
                <environment id="dev_oracle">
                    <transactionManager type="JDBC"/>
                    <dataSource type="POOLED">
                        <property name="driver" value="${jdbc.oracle.driver}"/>
                        <property name="url" value="${jdbc.oracle.url}"/>
                        <property name="username" value="${jdbc.oracle.user}"/>
                        <property name="password" value="${jdbc.oracle.passowrd}"/>
                    </dataSource>
                </environment>
                <environment id="dev_mysql">
                    <transactionManager type="JDBC"/>
                    <dataSource type="POOLED">
                        <property name="driver" value="${jdbc.driver}"/>
                        <property name="url" value="${jdbc.url}"/>
                        <property name="username" value="${jdbc.user}"/>
                        <property name="password" value="${jdbc.passowrd}"/>
                    </dataSource>
                </environment>
            </environments>

   8.mapper映射
            <!-- mappers:将sql映射注册到全局配置中 -->
            <mappers>
            <!-- mapper:注册一个sql映射
                 注册配置文件:
                     resource:引用类路径下的sql映射文件
                         mybatis/mapper/EmployeeMapper.xml
                     url:引用网络路径下或者磁盘路径下的sql映射文件
                         url="file:///var/mappers/AuthorMapper.xml"
                
                       注册接口
                      class:引用(注册)接口
                          1.有sql映射文件,映射文件名必须和接口同名,并且放在与接口同一个目录下;
                          2.没有sql映射文件,所有的sql都是利用注解写在接口上;
                            推荐:
                                比较重要的,复杂的Dao接口我们来写sql映射文件
                                不重要,见到的Dao接口为了开发快速可以使用注解
            
            
             -->
                <mapper resource="mybatis/mapper/EmployeeMapper.xml"/>
                <mapper class="com.neuedu.mybatis.mapper.EmployeeMapperAnnotation"/>
                <!-- 批量注册:
                     1.注解版肯定是没问题的
                     2.但是对于Mapper.xml映射文件和接口分开的,就需要保证在同一个包下了,否则找不到 -->
                <package name="com.neuedu.mybatis.mapper"/>
            </mappers>
        
    9.最后就是全局配置文件中标签实际上是有顺序的!
全局配置文件:配置中方法具体说明

四、sql映射文件

<?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.neuedu.sm.mapper.EmployeeMapper">
    <!-- public Employee getEmpById(Integer id); -->
    <select id="getEmpById" resultType="com.neuedu.sm.entity.Employee">
        select * from employee where id = #{id}
    </select>
</mapper>


com.neuedu.sm.mapper.EmployeeMapper为对应的接口文件的全类名;
com.neuedu.sm.entity.Employee为数据库表的实例对象的全类名
id处为对应mapper接口类中的方法名
sql映射文件参考

五、使用MyBatis操作数据库

1、原理

  1).新建一个XxxMapper接口。通常情况下,Mapper接口和Mapper.xml文件同名,且在同一个包下;
           MyBatis在加载Mapper接口的时候也会自动的加载Mapper.xml文件。         
       2).在该接口中新建方法.
            若该方法上没有注解,则mybatis会去对应的Mapper.xml文件中查找和方法名匹配的id的节点进而执行该节点对应的SQL语句。
       3).在方法上使用MyBatis的注解2、

MyBatis有基于XML文件的方式也有基于注解的方式,如下所示:
    1.使用基于注解的MyBatis映射
       1).新建一个XxxMapper接口。通常情况下,Mapper接口和Mapper.xml文件同名,且在同一个包下;
           MyBatis在加载Mapper接口的时候也会自动的加载Mapper.xml文件。
          
       2).在该接口中新建方法.
            若该方法上没有注解,则mybatis会去对应的Mapper.xml文件中查找和方法名匹配的id的节点进
            而执行该节点对应的SQL语句。
       3).在方法上使用MyBatis的注解
       
       如下所示:代码和配置如下所示:
        Mapper接口为:
            public interface EmployeeMapper {
        
                public Employee getEmployeeById(Integer id);
                //讲到此处了!此处以下没讲
                @Update("update tbl_employee set user_name = #{userName} where id = #{id}")
                public void updateEmployee(Employee employee);
            }
        MyBatis的sql映射文件可以没有,MyBatis的全局映射文件可以只用mapper标签加载Mapper接口
            <mappers>
                <!-- resource="com/neuedu/mapper/EmployeeMapper.xml" -->
                <mapper class="com.neuedu.mapper.EmployeeMapper"/>
            </mappers>
      
      增删改操作需要提交事务:
          @Test
        public void test02(){
            //1.获取sqlSessionFactory对象
            SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
            //2.利用sqlSessionFactory对象创建一个SqlSession对象
            SqlSession session = sqlSessionFactory.openSession();
            EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
            Employee employee = new Employee(1, 1,"张三丰","tangseng@163.com");
            
            mapper.updateEmployee(employee);
            //提交事务
            session.commit();
        }

  
2.获取自增主键值【当向数据库中插入一条数据的时候,默认是拿不到主键的值的, 需要设置如下两个属性才可以拿到主键值!】
        对于mysql:
            <!--设置userGeneratedKeys属性值为true:使用自动增长的主键。使用keyProperty设置把主键值设置给哪一个属性-->
            <insert id="addEmp" parameterType="com.neuedu.mybatis.bean.Employee" 
              useGeneratedKeys="true" keyProperty="id" databaseId="mysql">
                insert into tbl_employee(last_name,email,gender) 
                values(#{lastName},#{gender},#{email})
            </insert>    
            
        对于ORACLE:
                    <insert id="addEmp" databaseId="oracle">
                 <!-- order="BEFORE" 设置selectKey中包含的语句先执行。且返回的类型为resultType指定的类型。
                      再把该值付给keyProperty指定的列 -->
                        <selectKey keyProperty="" resultType="int" order="BEFORE"></selectKey>
                        insert into tbl_employee(id,last_name,email,gender) 
                        values(#{id},#{lastName},#{gender},#{email})
                    </insert>
        
        
        
3.SQL节点:
   1).可以用于存储被重用的SQL片段
   2).在sql映射文件中,具体使用方式如下:
        <insert id="addEmp">
            insert into tbl_employee(id,
            <include refid="employeeColumns"></include>) 
            values(#{id},#{lastName},#{gender},#{email})
        </insert>    
    
      <sql id="employeeColumns">
          last_name,email,gender
      </sql>  
    
    
五:参数处理
   单个参数:mybatis不会做特殊处理
            #{参数名}: 取出参数值
        
   多个参数:mybatis会做特殊处理
         多个参数会被封装成一个map,
          key:param1...paramN,或者参数的索引也可以
          value:传入的参数值
          
      #{}就是从map中获取指定的key的值
      
          异常:
            org.apache.ibatis.binding.BingdingException:
            Parameter 'id' not found.
            Available parameters are [1,0,param1,param2]
          操作:
               方法:public Employee getEmployeeAndLastName(Integer id,String lastName);
               取值:#{id},#{lastName}
           
    命名参数:明确指定封装参数时map的key:@param("id")
           多个参数会被封装成一个map,
                key:使用@Param注解指定的值
                value:参数值
            #{指定的key}取出对应的参数值
              
                
    POJO:
      如果多个参数正好是我们业务逻辑的数据模型,我们就可以直接传入pojo;
        #{属性名}:取出传入的pojo的属性值
        
    Map:
      如果多个参数不是业务模型中的数据,没有对应的pojo,不经常使用,为了方便,我们也可以传入map
        #{key}:取出map中对应的值
    
    List、Set
       #这里面的值也会被封装到map集合中:
        key:collection
        值:对应的参数值
        
        #{collection[0]}或#{list[0]}
        
#关于参数的问题:
    ①.使用#{}来传递参数
    ②.若目标方法的参数类型为对象类型,则调用其对应的getter方法,如getEmail()
    ③.若目标方法的参数类型为Map类型,则调用其get(key)
    ④.若参数是单个的,或者列表,需要使用@param注解来进行标记
    ⑤.注意:若只有一个参数,则可以省略@param注解

    
六、参数值的获取
 #{}:可以获取map中的值或者pojo对象属性的值
 ${}: 可以获取map中的值获取pojo对象属性的值
  
  案例演示:
      select * from tbl_employee where id = ${id} and last_name = #{lastName}
      preparing:select * from tbl_employee where id = 2 and last_name = ?
      
  区别:
     #{}:是以预编译的形式,将参数设置到sql语句中,PreparedStatement;防止sql注入
     ${}:取出的值直接拼装在sql语句中,会有安全问题;
     大多情况下,我们取参数的值都应该去使用#{};
     
     原生JDBC不支持占位符的地方我们就可以使用${}进行取值,#{}只是取出参数中的值!
     
     在某些情况下,比如分表、排序;按照年份分表拆分
       select * from ${year}_salary where xxx;[表名不支持预编译]
       select * from tbl_employee order by ${f_name} ${order} :排序是不支持预编译的!
数据库操作使用帮助
MyBatis-映射文件
        映射文件指导着MyBatis如何进行数据库增删改查, 有着非常重要的意义;
    
        cache –命名空间的二级缓存配置
        cache-ref – 其他命名空间缓存配置的引用。
        resultMap  –  自定义结果集映射
        parameterMap – 已废弃!老式风格的参数映射
        sql  –抽取可重用语句块。
        insert – 映射插入语句
        update – 映射更新语句
        delete – 映射删除语句
        select – 映射查询语句
    
    1.先看增删改查标签
          接口类:
              public interface EmployeeMapper {
                public Employee getEmployeeById(Integer id);    
                public void addEmp(Employee employee);        
                public void updateEmp(Employee employee);        
                public void deleteEmp(Integer id);
                
             }
          在其对应的sql映射文件中:      
                <!-- public void addEmp(Employee employee); -->
                <!--parameterType:可以省略  ,且该sql语句最后不用写分号-->
                <insert id="addEmp" parameterType="com.neuedu.mybatis.bean.Employee">
                    insert into tbl_employee(last_name,email,gender) 
                    values(#{lastName},#{gender},#{email})
                </insert>
                <!-- public void updateEmp(Employee employee); -->
                <update id="updateEmp">
                    update tbl_employee 
                        set last_name=#{lastName},email=#{email},gender=#{gender} 
                        where id = #{id}
                </update>
                <!-- public void deleteEmp(Integer id); -->
                <delete id="deleteEmp">
                    delete from tbl_employee where id = #{id}
                </delete>
    
        编写测试单元:
            /**
             * 测试增删改
             * 1.mybatis允许增删改直接定义以下类型返回值
             *   Integer、Long、Boolean 
             *   增删改返回的是影响的多少行,只要影响0行以上就会返回true,0行以下就会返回false!
             *   直接在接口上写这些包装类或者基本类型就好,
             *   没必要在sql映射文件中写resultType,而且在sql映射文件中也没有resultType标签!
             * 2.我们需要手动提交数据
                   *sqlSessionFactory.openSession();===>手动提交
                  *sqlSessionFactory.openSession(true);===>自动提价
             */
            @Test
            public void test02() {
                String resource = "mytabis-config.xml";
                InputStream inputStream;
                SqlSession openSession = null;
                try {
                    inputStream = Resources.getResourceAsStream(resource);
                    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
                    //1.获取到的sqlSession不会自动提交数据,需要手动提交
                    openSession = sqlSessionFactory.openSession();
                    EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
                    mapper.addEmp(new Employee(null,"hah","email","1"));
                    //手动提交
                    openSession.commit();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }finally{
                    //关闭会话
                    openSession.close();
                }    
            }
    
select元素
        Select元素来定义查询操作。
        Id:唯一标识符。
            – 用来引用这条语句,需要和接口的方法名一致
        parameterType:参数类型。
            –可以不传,MyBatis会根据TypeHandler自动推断
        resultType:返回值类型。
            – 别名或者全类名,如果返回的是集合,定义集合中元素的类型。不能和resultMap同时使用  
        
        1.返回类型为一个List
            eg:public List<Employee> getEmpsByLastNameLike(String lastName);
               <!-- resultType:如果返回的是一个集合,要写集合中元素的类型 -->
             <selecct id="getEmpsByLastNameLike" resultType="com.neuedu.mybatis.bean.Employee">    
                select * from tbl_employee where lastName  like #{lastName}
             </select>
             
        2.返回单条记录为一个Map
          <!-- 返回一条记录的map:key就是列名,值就是对应的值 -->
          public Map<String,Object> getEmpByIdReturnMap(Integer id);
          
          <select id="getEmpByIdReturnMap" resultType="map">
            select * from tbl_employee where id = #{id}
          </select>
          
          
       3.返回为一个ResultMap:自定义结果集映射规则
            尤其是当数据表的列名和类的属性名不对应的时候:
              1.起别名
              2.符合下划线转驼峰式命名规范
              3.用这里的resultMap

         <!-- resultMap:自定义结果集映射规则 -->
         public  Employee getEmployeById(Integer id);
         
         <!-- 自定义某个javaBean的封装规则
            type:自定义规则的javabean类型
            id:唯一id方便引用
         -->
         <resultMap type="com.neuedu.mybatis.bean.Employee" id = "myEmp">
            <!-- 
                指定主键列的封装规则
                id定义主键列会有底层优化
                column:指定是哪一列
                property:指定对应的javaBean属性
            -->
            <id column="id" property = "id">
            <!-- 定义普通列封装规则 -->
            <result column="last_name" property="lastName"/>
            <!--其它不指定的列只要属性名和列名会自动封装,我们只要写resultMap就把全部的映射规则
                都写上,不写是因为列名和属性名是对应的 -->
            
         </resultMap>
         
         <!--只需要在映射的地方映射一下就可以了 --<select id="getEmployeById" resultMap="myEmp">
                select * from tbl_employee where id = #{}
            </select>
操作数据库示例

 

posted @ 2017-09-04 19:26  康星悦  阅读(208)  评论(0编辑  收藏  举报