zoukankan      html  css  js  c++  java
  • 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>
    操作数据库示例
  • 相关阅读:
    python自动化_day6_面向对象_组合,继承,多态
    python自动化_day5_二分查找,模块和正则表达式
    python自动化_day4_迭代器生成器内置函数和匿名函数
    python自动化_day4_装饰器复习和装饰器进阶
    python目录
    python3的ExecJS安装使用
    python运算符^&|~>><<
    python有哪些优点跟缺点
    26-30题
    21-25题
  • 原文地址:https://www.cnblogs.com/kangxingyue-210/p/7474402.html
Copyright © 2011-2022 走看看