• XML之MyBatis配置(1)


    1、log4j简单配置

     1 <?xml version="1.0" encoding="UTF-8" ?>
     2 <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
     3 
     4 <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
     5   <appender name="console" class="org.apache.log4j.ConsoleAppender"> 
     6     <param name="Target" value="System.out"/> 
     7     <layout class="org.apache.log4j.PatternLayout"> 
     8       <param name="ConversionPattern" value="%-5p %c{1} - %m%n"/> 
     9     </layout> 
    10   </appender> 
    11 
    12   <root> 
    13     <priority value ="debug" /> 
    14     <appender-ref ref="console" /> 
    15   </root>
    16   
    17 </log4j:configuration>

     

    2、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>
        <!--
            1、mybatis可以使用properties来引入外部properties配置文件的内容;
            resource:引入类路径下的资源
            url:引入网络路径或者磁盘路径下的资源
          -->
        <properties resource="dbconfig.properties"></properties>
        
        
        <!-- 
            2、settings包含很多重要的设置项
            setting:用来设置每一个设置项
                name:设置项名
                value:设置项取值
         -->
        <settings>
            <setting name="mapUnderscoreToCamelCase" value="true"/>
        </settings>
        
        
        <!-- 3、typeAliases:别名处理器:可以为我们的java类型起别名 
                别名不区分大小写
        -->
        <typeAliases>
            <!-- 1、typeAlias:为某个java类型起别名
                    type:指定要起别名的类型全类名;默认别名就是类名小写;employee
                    alias:指定新的别名
             -->
            <!-- <typeAlias type="com.atguigu.mybatis.bean.Employee" alias="emp"/> -->
            
            <!-- 2、package:为某个包下的所有类批量起别名 
                    name:指定包名(为当前包以及下面所有的后代包的每一个类都起一个默认别名(类名小写),)
            -->
            <package name="com.atguigu.mybatis.bean"/>
            
            <!-- 3、批量起别名的情况下,使用@Alias注解为某个类型指定新的别名 -->
        </typeAliases>
            
        <!-- 
            4、environments:环境们,mybatis可以配置多种环境 ,default指定使用某种环境。可以达到快速切换环境。
                environment:配置一个具体的环境信息;必须有两个标签;id代表当前环境的唯一标识
                    transactionManager:事务管理器;
                        type:事务管理器的类型;JDBC(JdbcTransactionFactory)|MANAGED(ManagedTransactionFactory)
                            自定义事务管理器:实现TransactionFactory接口.type指定为全类名
                    
                    dataSource:数据源;
                        type:数据源类型;UNPOOLED(UnpooledDataSourceFactory)
                                    |POOLED(PooledDataSourceFactory)
                                    |JNDI(JndiDataSourceFactory)
                        自定义数据源:实现DataSourceFactory接口,type是全类名
             -->
             
    
             
        <environments default="dev_mysql">
            <environment id="dev_mysql">
                <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="dev_oracle">
                <transactionManager type="JDBC" />
                <dataSource type="POOLED">
                    <property name="driver" value="${orcl.driver}" />
                    <property name="url" value="${orcl.url}" />
                    <property name="username" value="${orcl.username}" />
                    <property name="password" value="${orcl.password}" />
                </dataSource>
            </environment>
        </environments>
        
        
        <!-- 5、databaseIdProvider:支持多数据库厂商的;
             type="DB_VENDOR":VendorDatabaseIdProvider
                 作用就是得到数据库厂商的标识(驱动getDatabaseProductName()),mybatis就能根据数据库厂商标识来执行不同的sql;
                 MySQL,Oracle,SQL Server,xxxx
          -->
        <databaseIdProvider type="DB_VENDOR">
            <!-- 为不同的数据库厂商起别名 -->
            <property name="MySQL" value="mysql"/>
            <property name="Oracle" value="oracle"/>
            <property name="SQL Server" value="sqlserver"/>
        </databaseIdProvider>
        
        
        <!-- 将我们写好的sql映射文件(EmployeeMapper.xml)一定要注册到全局配置文件(mybatis-config.xml)中 -->
        <!-- 6、mappers:将sql映射注册到全局配置中 -->
        <mappers>
            <!-- 
                mapper:注册一个sql映射 
                    注册配置文件
                    resource:引用类路径下的sql映射文件
                        mybatis/mapper/EmployeeMapper.xml
                    url:引用网路路径或者磁盘路径下的sql映射文件
                        file:///var/mappers/AuthorMapper.xml
                        
                    注册接口
                    class:引用(注册)接口,
                        1、有sql映射文件,映射文件名必须和接口同名,并且放在与接口同一目录下;
                        2、没有sql映射文件,所有的sql都是利用注解写在接口上;
                        推荐:
                            比较重要的,复杂的Dao接口我们来写sql映射文件
                            不重要,简单的Dao接口为了开发快速可以使用注解;
            -->
            <!-- <mapper resource="mybatis/mapper/EmployeeMapper.xml"/> -->
            <!-- <mapper class="com.atguigu.mybatis.dao.EmployeeMapperAnnotation"/> -->
            
            <!-- 批量注册: -->
            <package name="com.atguigu.mybatis.dao"/>
        </mappers>
    </configuration>

    3、MyBatis参数处理

    单个参数:mybatis不会做特殊处理,
        #{参数名/任意名}:取出参数值。
        
    多个参数:mybatis会做特殊处理。
        多个参数会被封装成 一个map,
            key:param1...paramN,或者参数的索引也可以
            value:传入的参数值
        #{}就是从map中获取指定的key的值;
        
        异常:
        org.apache.ibatis.binding.BindingException: 
        Parameter 'id' not found. 
        Available parameters are [1, 0, param1, param2]
        操作:
            方法:public Employee getEmpByIdAndLastName(Integer id,String lastName);
            取值:#{id},#{lastName}
    
    【命名参数】:明确指定封装参数时map的key;@Param("id")
        多个参数会被封装成 一个map,
            key:使用@Param注解指定的值
            value:参数值
        #{指定的key}取出对应的参数值
    
    
    POJO:
    如果多个参数正好是我们业务逻辑的数据模型,我们就可以直接传入pojo;
        #{属性名}:取出传入的pojo的属性值    
    
    Map:
    如果多个参数不是业务模型中的数据,没有对应的pojo,不经常使用,为了方便,我们也可以传入map
        #{key}:取出map中对应的值
    
    TO:
    如果多个参数不是业务模型中的数据,但是经常要使用,推荐来编写一个TO(Transfer Object)数据传输对象
    Page{
        int index;
        int size;
    }
    
    ========================思考================================    
    public Employee getEmp(@Param("id")Integer id,String lastName);
        取值:id==>#{id/param1}   lastName==>#{param2}
    
    public Employee getEmp(Integer id,@Param("e")Employee emp);
        取值:id==>#{param1}    lastName===>#{param2.lastName/e.lastName}
    
    ##特别注意:如果是Collection(List、Set)类型或者是数组,
             也会特殊处理。也是把传入的list或者数组封装在map中。
                key:Collection(collection),如果是List还可以使用这个key(list)
                    数组(array)
    public Employee getEmpById(List<Integer> ids);
        取值:取出第一个id的值:   #{list[0]}
        
    ========================结合源码,mybatis怎么处理参数==========================
    总结:参数多时会封装map,为了不混乱,我们可以使用@Param来指定封装时使用的key;
    #{key}就可以取出map中的值;
    
    (@Param("id")Integer id,@Param("lastName")String lastName);
    ParamNameResolver解析参数封装map的;
    //1、names:{0=id, 1=lastName};构造器的时候就确定好了
    
        确定流程:
        1.获取每个标了param注解的参数的@Param的值:id,lastName;  赋值给name;
        2.每次解析一个参数给map中保存信息:(key:参数索引,value:name的值)
            name的值:
                标注了param注解:注解的值
                没有标注:
                    1.全局配置:useActualParamName(jdk1.8):name=参数名
                    2.name=map.size();相当于当前元素的索引
        {0=id, 1=lastName,2=2}
                    
    
    args【1,"Tom",'hello'】:
    
    public Object getNamedParams(Object[] args) {
        final int paramCount = names.size();
        //1、参数为null直接返回
        if (args == null || paramCount == 0) {
          return null;
         
        //2、如果只有一个元素,并且没有Param注解;args[0]:单个参数直接返回
        } else if (!hasParamAnnotation && paramCount == 1) {
          return args[names.firstKey()];
          
        //3、多个元素或者有Param标注
        } else {
          final Map<String, Object> param = new ParamMap<Object>();
          int i = 0;
          
          //4、遍历names集合;{0=id, 1=lastName,2=2}
          for (Map.Entry<Integer, String> entry : names.entrySet()) {
          
              //names集合的value作为key;  names集合的key又作为取值的参考args[0]:args【1,"Tom"】:
              //eg:{id=args[0]:1,lastName=args[1]:Tom,2=args[2]}
            param.put(entry.getValue(), args[entry.getKey()]);
            
            
            // add generic param names (param1, param2, ...)param
            //额外的将每一个参数也保存到map中,使用新的key:param1...paramN
            //效果:有Param注解可以#{指定的key},或者#{param1}
            final String genericParamName = GENERIC_NAME_PREFIX + String.valueOf(i + 1);
            // ensure not to overwrite parameter named with @Param
            if (!names.containsValue(genericParamName)) {
              param.put(genericParamName, args[entry.getKey()]);
            }
            i++;
          }
          return 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}
    
    #{}:更丰富的用法:
        规定参数的一些规则:
        javaType、 jdbcType、 mode(存储过程)、 numericScale、
        resultMap、 typeHandler、 jdbcTypeName、 expression(未来准备支持的功能);
    
        jdbcType通常需要在某种特定的条件下被设置:
            在我们数据为null的时候,有些数据库可能不能识别mybatis对null的默认处理。比如Oracle(报错);
            
            JdbcType OTHER:无效的类型;因为mybatis对所有的null都映射的是原生Jdbc的OTHER类型,oracle不能正确处理;
            
            由于全局配置中:jdbcTypeForNull=OTHER;oracle不支持;两种办法
            1、#{email,jdbcType=OTHER};
            2、jdbcTypeForNull=NULL
                <setting name="jdbcTypeForNull" value="NULL"/>
    

    (持续更新中......)

  • 相关阅读:
    ORA15196: invalid ASM block header
    Oracle Recovery Tools修复空闲坏块
    又一例asm disk 加入vg故障
    Oracle Recovery Tools快速解决sysaux文件不能online问题
    ORA00702一键恢复
    ORA604 ORA01558 恢复
    echo
    倒计时组件
    第五章第7节: 2020.06.15 智能互联网之弹性容器云与Service Mesh【七】 没用
    第五章第3节: 2020.05.30 智能互联网之弹性容器云与Service Mesh【三】
  • 原文地址:https://www.cnblogs.com/zz-newbie/p/13895975.html
Copyright © 2020-2023  润新知