Mybatis上

为什么学习Mybatis

Hibernate的核心是ORM,将表的记录和对象进行全自动映射,目标是消除SQL,但是对于复杂的查询,需要进行定制,我们需要精通HQL来满足要求.

Mybatis则将SQL语句写在配置文件中,实现SQL和Java分离,且SQL是可定制,由开发人员控制.

Mybait下载目录:https://github.com/mybatis/mybatis-3/releases

Mybatis- Helloworld

1.根据配置文件(全局配置文件)创建SQLSessionFactory对象,这个文件中有数据源的配置信息. myconfig.xml

  
  
  
       
           
               
                   
                   
                 
                   
                   
                   
           
   
  

2.创建SQL映射文件.eg: employee.xml

  
  
  
  
       
        select * from Blog where id = #{id}  
       
  

3.将SQL映射文件放入到全局配置文件.

   
   
   
  

4.写代码:根据配置文件获取SQLSessionFactory -> 然后获取SQLSession ,表示SQL的一次会话,然后使用SQL的唯一标志来告诉mybatis执行哪个SQL语句,->关闭session.

package com.dong.controller;  
  
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 com.dong.service.employee;  
import com.dong.service.employeeMapper;  
  
public class Mybatis {  
    public static void main(String[] args) throws IOException {  
      
    }  
      
    public void test() throws IOException {  
        String resource = "config/myconfig.xml";  
        InputStream inputStream = Resources.getResourceAsStream(resource);  
        SqlSessionFactory sqlSessionFactory =  
                new SqlSessionFactoryBuilder().build(inputStream);    
        //获取sqlSession实例,可以直接执行已经映射的sql语句  
        SqlSession openSession = null ;  
        try {  
            openSession  = sqlSessionFactory.openSession();       
            employee emp = openSession.selectOne("org.mybatis.example.employeeMapper.selectEmp", 1);  //这个时候我们的namespace是一个随便写的值,com.dong.service.employeeMapper为namespace, selectEmployee是sql标识id.  
            System.out.println(emp.toString());   
        } finally {  
            openSession.close();  
        }  
    }  
}  

问题:

在上面的SQL语句中,使用selectOne需要一个id值,但没有显示的限制传递的类型,也没有进行判断,有可能导致查询不到,eg: 传递“ad”,而不是数字,因此Mybatis使用更高级的写法:

接口的方式,更安全:

1.创建接口. employeeMapper

package com.dong.service;  
  
import java.util.Map;  
  
public interface employeeMapper {  
    public employee getEmployee(Integer id);  
}  

2.在Mapper文件中,将命名空间改为接口的全类名,然后将SQL的id改为方法名.

  
  
  
  
       
        select * from Blog where id = #{id}  
       
  

3.写代码

public void test1() throws IOException {  
        String resource = "config/myconfig.xml";  
        InputStream inputStream = Resources.getResourceAsStream(resource);  
        SqlSessionFactory sqlSessionFactory =  
                new SqlSessionFactoryBuilder().build(inputStream);    
        SqlSession openSession = null;  
        //获取sqlSession实例,可以直接执行已经映射的sql语句  
        try {  
            openSession = sqlSessionFactory.openSession();  
            employeeMapper Mapper = openSession.getMapper(employeeMapper.class);  
            employee employee = Mapper.getEmployee(1);  
            System.out.println(employee.toString());  
            openSession.commit();  
        }finally {  
            openSession.close();      
        }  
    }  

每个接口方法都对应Mapper.xml中的一个映射,

SqlSession 和 Connector是非线程安全的,每次使用我们最好创建一个新的SQLSession.

 Mapper没有接口的实现类,Mybatis会生成一个代理.

       配置文件

配置文件:全局配置文件, 包含数据库信息,事务管理,系统运行环境,注意全局配置文件可以没有,Mybatis使用默认的配置.eg: myconfig.xml

SQL映射文件:必须有,保存了每一个SQL语句的映射信息.eg:eployeeMapper.xml

Mybatis 全局配置文件

Mybatis上_第1张图片

注意:这些标签都不需包含在..中.

properteis:用来引入外部配置文件

resource:用来引入类路径下配置文件

uri:引入网络路径或者磁盘路径下的资源

  

settings:包含很多设置项,设置项直接影响mybatis的运行时行为,

settting:用于设置属性,

setting name:属性名   value 属性值.eg:开启驼峰命令识别

  
          
  

typeAliases :别名处理器, Java类型起别名,使得引用方便,注意别名不区分大小写.

typeAlis:为某个Java类型起别名,

              type:指定想要其别的全类名,默认别名是类名小写.

              alias:新的别名

  
          
  

package:为某个包下类批量其别名,

           name:当前包的所有类其别名,默认别名为类名小写.

           alias:新的别名

       在批量起别名的情况下,使用注解@Alias()在特定的类上指定别名

   
          
  

typeHandlers : 进行数据库类型和Java类型映射

plugins: 进行插件,mybatis可以进行拦截,拦截使用插件进行,

environments:进行环境配置,mybatis可以配置多种环境,default指定使用某种环境,可以快速切换环境.

environment:配置一个具体的环境信息,必须有两个标签,即dataSource ,transcationManager

environment id: 代表当前环境的唯一标识.

transcationManager:配置事务管理器,:

             type:JDBC | MANAGED,也可以自定义事务管理器,

            dataSource:数据源,

            type:UNPOOLED | POOLED | JNDI,也可以自定义数据源,

  
       
           
               
               
               
               
               
               
  

databaseIdProvider:Mybatis可执行不同的SQL语句根据不同的数据库厂商,支持多数据库厂商,eg:Oracle

       type:"DB_VENDOR",作用:得到数据库厂商的标识. MYSQL, Oracle,SQL Server,可以对不同的数据库厂商起别名.

   
          
          
          
          
    

  

       使用方式在Mapper文件中,select标签中使用 databaseId="mySQL"属性来设置使用哪个数据库厂商,值为别名.

  
        select * from Blog where id = #{id}  
  

Mappers:将SQL映射注册到全局配置中

       Mapper:注册SQL映射

              resource:引入类路径下

              url:应用网络路径|磁盘路径下

  
  
  
 

 

 package:批量注册, name: 具体包名, 需要将映射文件放在包的目录下,

  
  
  
  

class:注册接口,

1.有映射文件,需要将配置文件放到接口同一目录下,配置文件的名字与接口同名;

   
  
  

2.没有映射文件, 直接在接口上写相应的注解@Select(SQL语句),然后再Mapper中进行注册,eg:employeeMapper接口

public interface employeeMapper {   
    @Select("selct * from table_name where id = #{id} ")  
    public employee getEmployee(Integer id);  
}  

全局配置文件,config.xml(名字随意)

  
  
  

注意:全局文件编辑也是有顺序的,

   推荐比较重要的dao,写SQL映射文件,不重要的,简单的,为了快速开发,使用注解方式.

Mybatis映射文件

增删改查:

public interface employeeMapper {  
    public employee getEmployees2 (Map Map);  
    public void addEmployee(employee emp);  
    public void updateEmployee(employee emp);  
    public void deleteEmployee(employee emp);  
}  

获取自增主键

Mybatis 支持自增主键,自增主键的获取,通过statement.getGenerateKeys(),

useGeneratedKeys="true":使用自增主键获取主键值策略,

keyProperty="xxx":指定对应的主键属性,也就是mybatis获取到主键值以后,将这个值封装到JavaBean的哪个属性.

由于主键自增,所以SQL语句不需要写主键,但在构建映射bean时,需要填写主键的值,可以使用null代替.

  
    insert into tbl_employee(last_name,email,gendar) values (#{lastName},#{email},#{gendar})  
  

       Oracle:不支持自增,主键是从序列中获取,

插入时的主键是从序列中获取的,使用,进行查询主键语句, KeyProperty:将查询的主键封装到bean的哪个属性, order:"BEFROE",查主键的SQL是在前执行,"AFTER",在后执行,resultType:xxx,结果的类型.

keyProperty 也可使用AFTER,获取当前的序列值,但是之前的insert语句为:insert  into ... value( employee_seq.nextval....);

参数处理

单个参数:Mybatis不做任何处理, 使用 #{参数名},获取参数值,

多个参数:Mybatis多个参数会被封装成一个Map, key:param1 ...paramN, value:是传入的参数值,  #{} 从Map中获取指定的key,

#{param1...N} ,对于参数过多,则不好使用,使用命名参数,

    
    select * from BLog where id = #{param1} and id2 = #{param2}  
  

命名参数:明确指定封装参数时Map的key:@Param("id")

key:为使用@Param注解的值

value:为参数值

public employee getEmployees(@Param("id")Integer id,@Param("id2")Integer id2);  

  #{指定的命名值}

  
    select * from BLog where id = #{id} and id2 = #{id2}  
 

 

POJO

如果多个参数正好是Bean,则可以直接传递POJO, #{属性名} 即可获取pojo的值,

如果多个参数不是业务逻辑的模型,没有对应的POJO,则可以传入Map,

#{key} : 取出Map对应的值,

如果多个参数不是对应的Bean,但经常使用,则推荐使用一个(transfer object) 传输对象,

特别注意,如果Collection(list, Set)类型或者数组,也会特殊处理,把传入的list或者数组封装在Map中,

 Key: 为collection

如果是List,可使用key:list  eg: #{list[0]}

如果是Array,可使用key:array

  
    insert into tbl_employee(last_name,email,gendar) values (#{list[0]},#{list[1]},#{list[2]})  
   

参数值的获取

  #{}:获取Map中的值或者POJO对象属性的值,

  ${}:获取Map中的值或POJO对象属性的值,

  区别: #{}是以预编译的形式,将参数设置到SQL语句,使用占位符

              ${}取出值直接封装在SQL语句中,存在安全问题.

 大多数情况下,我们取参数的值都应该使用 # {  } ,在不支持占位符的地方我们可以使用${}方式.

 #{}更丰富的用法:

 规定参数的一些规则:

JavaType,jdbcType,mode,numericScale,resultMap,typeHandler,jdbcTypeName,expression.

jdbcType:当数据为null时,有些数据库不能识别mybatis对null的默认处理,eg:Oracle,

mybatis将 null类型映射为数据库类型的 OTHER类型,对于Oracle是不认识,而对MySQL可以识别.可以进行制定:eg: #{email,jdbcType=NULL}

由于全局配置中的jdbcTypeForNull=OTHER,oracle不支持, 所以可以在#{}中修改,也可以修改全局配置,

Select

Select: 普通的参数不做介绍,

当返回值为List时,在写映射时,resultType的类型为List中元素的类型,

当返回类型Map时,返回一条记录的Map,,key为列名,值为对应的值,在写映射时,resultType的类型为Map,

当返回类型Map时,返回多条记录封装成一个Map,Map:键是主键,值为封装后的Javabean,

写映射时,resultType的类型为集合中元素的类型,如果想要指定key使用哪个属性,则需要在方法上使用@MapKey("")

resultMap:自定义结果集映射规则,resultMap 和 resultType只能二选一,

                   type:自定义Java类型, id:唯一id,方便引用,

                  

                          id: 指定主键的封装规则,column:指定列,  property:指定对应的JavaBean属性,

                         

                          指定普通列封装的规则,

                         

                          其他不指定的列会自动封装,尽量写出所有列的对应,

                  

  
      
      
   

            然后再select中使用resultMap引用定义好的映射规则即可.

    
    select * from Blog where id = #{id}  
     

联合查询,级联属性封装结果,对于别的表的属性,则使用属性.属性即可.还可以使用:可以指定联合的JavaBean对象,eg:

            proeorty:指定哪个对象是联合属性,  JavaType:指定属性对象的类型,然后再assocaition的标签内定义映射规则,

  
      
      
  

association分步查询

select:表明当前属性是调用select指定的方法查出的结果

column:指定将哪一列的值传递给这个方法

流程:首先使用select指定方法(传入column指定的这列参数的值,)查出对象,并封装给property指定的属性,

如果想要在使用的时候才进行加载,则可以使用懒加载机制,可在setting中进行设置.

如果关联多个对象:集合

即查询部分是,将对应部分的所有员工信息也查询出来:

     collection定义关联集合类型的属性的封装,

     property:对应的属性名   ofType:指定集合列元素的类型  

    

           定义这个集合中的元素的封装规则,

           

           

            ......

    

  
      
      
      
      
      
  

注:如何在collection的 select 语句中传入多个column值,可以将多列值封装到Map中传递, column= “{key1 = column1,key2 = column2}  fetchType:设置加载,可选延迟加载,立即加载,

discriminator

resultMap中的 discriminator 鉴别器,,用来判断某列的值,然后根据某列的值改变封装行为,

JavaType:列值对应的Java类型,    column:指定判定的列名,

           
                  
                    相应的规则  
                  
                  
                    相应的规则,  
                  
              

 

 

如有异议,敬请指出,谢谢观看,与君共勉.(观看https://www.bilibili.com/video/av45816095?t=113&p=36)

你可能感兴趣的:(Mysql)