MyBatis源码分析(二)

MyBatis的xml配置(核心配置)

configuration(配置)
   properties(属性)
   settings(设置)  
   typeAliases(类型别名)
   typeHandlers(类型处理器)
   objectFactory(对象工厂)
   plugins(插件)
   environments(环境配置)
        environment(环境变量)
            transactionManager(事务管理器)
            dataSource(数据源)
  databaseIdProvider(数据库厂商标识)
  mappers(映射器)                

MyBatis的Mapper映射

Mapper映射文件只有几个顶级元素(按照应被定义的顺序如下):
cache – 对给定命名空间的缓存配置。
cache-ref – 对其他命名空间缓存配置的引用。
resultMap – 是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加载对象。
sql – 可被其他语句引用的可重用语句块。
insert – 映射插入语句
update – 映射更新语句
delete – 映射删除语句
select – 映射查询语句

MyBatis也可以使用注解开发

生成代码时候,配置:
<javaClientGenerator type="ANNOTATEDMAPPER"...
生成注解代码,不生成xml代码了

MyBatis开发使用注解还是xml?

方式 优点 缺点
Xml Xml与接口分离,方便管理,复杂的SQL不影响代码的可读性 过多的Xml配置文件
Annotation 接口就能看到SQL语句,可读性强,不需要去找xml文件,方便 代码和SQL混杂,复杂一点过于混乱

MyBatis批量插入

1 普通for循环(此种方式对于数据库的I/O过于频繁,不适合大数据量的操作)

for (int i = 0; i < 500; i++) {
    user = new User();
    user.setId("id" + i);
    user.setName("name" + i);
    userMapper.insert(user);
}

2 ExeutorType.BATCH(设置批量模式),把SQL语句发个数据库,数据库预编译好,然后数据库等待需要运行的参数,接收到参数一次性运行

session = sqlSessionFactory.openSession(ExecutorType.BATCH, true);
for (int i=0; i<500; i++) {
    UUserInfo userInfo = new UUserInfo();
    userInfo.setPhone("1346262122" + i);
    userInfo.setUserName("张" + i);
    uUserInfoMapper.insert(userInfo);
}

3 传入一个数组或集合,标签插入

 
            #{item}
  
方式 性能 说明
For循环 性能低,IO高
ExeutorType.BATCH 性能居中
标签拼SQL 性能最高 有SQL长度限制,mysql默认接收SQl的长度为10486576(1M),该方式若超过1M
会抛出异常

MyBatis联合查询

一对一关系

在一对一关系中,A表中的一行最多只能匹配B表的一行,反之亦然.这种关系并不常见,因为一般来说,这种关系的信息会保存在一张表中,当然也可以利用一对一关系来保存,比如分割具有多列的表.(如:一个人只有一个身份证)




标签


  
  
  
  
  
    
    
    
    
  

一对多关系

一对多是最普通的一种关系,在这种关系中,A表的一行可以匹配B表中的多行,但是B表中的一行只能匹配A表中的一行.举例:(一个部门可以有多个员工)
标签


        
        
        
        
            
            
            
            
            
        
    

多对多关系

在多对多的关系中,A表的一行可以匹配B表的多行.反之亦然.要创建这种关系,需要定义第三张表,也可以称之为结合表或者关系表.它的主键是由A表和B表的外部键组成.举例(一个用户有多个角色,一个角色可以对应多个用户)
标签

MyBatis插入并返回主键

方式一:(数据库要设置主键自增长)





useGeneratedKeys="true"表示使用主键自增  keyProperty="id"表示将主键自增后的主键值赋值给实体类中的id属性
parameterType="com.test.mybatis.model.UUserInfo" 实体类,自增后的主键值将会赋值给该实体类的id属性

方式二:(一般用在标签里面)


  SELECT LAST_INSERT_ID()

 SELECT LAST_INSERT_ID()表示查询出刚刚插入的的记录自增长id  order='AFTER' 表示先执行插入语句,之后再执行查询语句

MyBatis的SQL注入攻击
  注入攻击的危害
  1:数据库被拖库(把数据从数据库拉取出来,造成数据泄露)
  2.重要信息被泄露
注入的本质是把用户输入的数据当做有效代码执行.
Mybatis的预编译机制可以有效防止SQL注入攻击.
  '#{}' 和 '${}'的区别:
'#{}':MyBaits会首先对其进行预编译,将#{user_ids}替换成?占位符,然后在执行时替换成实际传入的user_id值,**并在两边加上单引号,以字符串方式处理。
'${}':简单的字符串拼接
栗子:
uUserInfoMapper.selectByIn("select user_name from u_user_info");
where user_name in (${userName})
可使用MyBatis自带循环标签解决SQL语句动态拼接的问题:
select * from news where id in

  #{item} 


MyBatis的自定义类型转换器(实现数据类型和数据库数据类型的映射关系 如:String和VARCHAR的对应关系)  需求:实现对数据库身份证存储的加密
1、定义自己的HandlerType实现TypeHandler接口或者继承BaseTypeHandler类
2、覆盖其四个方法;
3、在核心配置文件mybatis-config.xml中配置标签或者在映射文件的增、改、查位置单独配置;


    





  #{userIdCard, jdbcType=VARCHAR, typeHandler=com.test.mybatis.typehandler.CryptTypeHandler},

系统自带的类型转换器StringTypeHandler 
public class StringTypeHandler extends BaseTypeHandler {

  @Override
  public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType)
      throws SQLException {
    ps.setString(i, parameter);
  }

  @Override
  public String getNullableResult(ResultSet rs, String columnName)
      throws SQLException {
    return rs.getString(columnName);
  }

  @Override
  public String getNullableResult(ResultSet rs, int columnIndex)
      throws SQLException {
    return rs.getString(columnIndex);
  }

  @Override
  public String getNullableResult(CallableStatement cs, int columnIndex)
      throws SQLException {
    return cs.getString(columnIndex);
  }
}
MyBatis的动态SQL

i f
 
–判断标签

choose (when, otherwise)–多项选择 , 与页面的
jstl 标签非常类似

trim (where, set)–修剪、格式化,添加前后缀的一个标签

f oreach
 
–循环


    select * from news where 1 = 1 
    
        
            and title = #{title}
        
        
            and content = #{content}
        
        
            and owner = "zhangsan"
        
    

MyBatis的SQL片段使用

  
    id, name
  
 
        select
        
        from user
        where id = #{id,jdbcType=INTEGER}
    

MyBatis的一级.二级缓存

一级缓存是sqlSession级别,默认开启

二级缓存是mapper级别,默认关闭,缓存命中率低

MyBatis的事务管理:


      

如果你正在使用
Spring + MyBatis,则没有必要配置事务管理器, 因为 Spring 模块会使用自带的管理器来覆盖前面的配置.