MyBatis框架(二)之使用详解

##概述

MyBatis是java项目持久层框架中比较优秀的一个,几乎满足项目中的一切需求。

MyBatis的核心是Mapper文件,Mapper文件中接收java对象参数,写sql语句,返回Java对象结果,所以下面讲解的知识都是在Mapper文件中的操作。

主要内容有:

  1. 基本使用说明。
  2. 传递参数。
  3. 返回值。
  4. insert时返回主键。
  5. jdbcType属性的使用。
  6. resultMap的使用。
  7. sql片段的使用。
  8. mapper.xml文件中特殊字符的处理。

 

##基本使用说明

在MyBatis的基本使用中,根据id查找对象的xml片段是:

    

说明:

  1. select:select是xml标签,表示查询。插入对应insert,更新对应update,删除对应delete.
  2. id:id是该xml片段的唯一标识,在同一个mapper文件中id不能重复。java程序根据该id找到对应的sql语句。
  3. parameterType:参数数据类型,参数类型需要写全类名或者写别名,int是框架自定义的别名。
  4. resultType:返回值数据类型,此与参数数据类型使用方法项目。
  5. sql语句:select标签中是sql语句。注意接收参数的形式:#{id}。

 

##传递参数

传递参数需要注意两点,一是设置参数类型,二是怎么接收参数。

一,设置参数类型

参数类型使用parameterType属性指定,参数类型需要写全类名或者写别名。

如果参数类型是int,全类名的写法如下:

parameterType="java.lang.Integer"

框架定义了常用类型的别名,java.lang.Integer的别名是int,所以int数据可以可以直接这么写:

parameterType="int" 

##框架中定义的别名有:

8个基本数据类型,string,map。

注意:java.util.List不是默认别名,需要写全类名。

二,自定义别名

如果参数是我们自定义的类,比如:com.honor.mybatis.model.StudentModel写法如下:

parameterType="com.honor.mybatis.model.StudentModel" 

这种写法比较麻烦,且此时是字符串,容易出错。所以此时需要自定义别名,然后使用别名即可。

MyBatis框架定义别名写在全局配置文件中(SqlMapConfig.xml)即可,如下:

    
        
    

此时在Mapper文件中使用别名即可,如下:

parameterType="studentModel"

 

三,传递基本数据参数

接收int参数示例如下:

    

说明:

  1. parameterType指定数据类型为int。
  2. 在sql中使用#{id}接收参数,此时id是行参,可以自定义,即可以是任意变量。

三,对象参数

接收com.honor.mybatis.model.StudentModel参数示例如下:

    

说明:

  1. parameterType指定数据类型为com.honor.mybatis.model.StudentModel。如果定义了别名此时也可以使用别名。。
  2. 在sql中使用#{name}和#{age}接收参数,此时name和age必须与StudentModel的字段名对应,不能自定义。

四,List参数

1,接收List参数示例如下:

    

说明:

  1. 此时是根据id集合查询student对象,所以要传递list参数。
  2. parameterType指定数据类型为java.util.List。
  3. foreach表示遍历,item表示集合中的元素。遍历后的结果相当于:(1,2,3,)。
  4. 取值使用#{item},此时的item与foreach标签的item属性值保持一致。

2,接收List参数示例如下:

    

说明:

  1. 此时parameterType仍然是java.util.List。
  2. 取值使用#{item.id},此时的item与foreach标签的item属性值保持一致,表示集合中的元素,即student对象,id表示student的id字段。

五,Map参数

Map参数示例如下:

    

说明:

  1. 此时parameterType是map。
  2. 在sql中使用#{name}和#{age}接收参数,此时name和age必须与map的键对应,不能自定义。

当Map的value是Student时示例如下:

    

说明:

  1. 此时parameterType是map。
  2. 在sql中使用#{student.name}和#{student.age}接收参数,此时student必须与map的键对应,name和age是Student的字段名。

 

##返回值

一,返回基本数据类型

查询数据条数的sql返回值都是int,示例如下:

    

说明:

  1. 使用resultType定义返回值类型,此时使用int。
  2. 查询到的数量只有一个值,会自动返回。

返回string类型的数据。示例如下:

    

二,返回对象

返回对象的标准写法如下:

    

说明:

  1. 使用resultType定义返回值类型,此时是studentModel类。
  2. sql语句中as前的name是数据库的字段,as后的name是StudentModel类的字段。

如果数据库表字段名和类的字段名相同,则可以简写:

    

三,返回List集合

返回List结合和返回单个对象在Mapper文件中的写法完全一样,返回值仍然写List中元素的类型,sql完全不变,只是sqlsession对象调用的方法不同。sqlsession的调用如下:

List studentModelList = sqlSession.selectList("student.queryList", student);

四,返回Map对象

返回map对象示例如下:

    

注:此时返回的map对象的键分别是name和age,即与表字段名保持一直。

自定义map的key的写法如下:

    

##insert时返回主键

在开发中很多情况下需要插入数据时返回主键,MyBatis中提供了该方法。但MySql和oracle数据库返回主键的方法不同。

一,MySql数据库insert时返回主键

具体如下:

    
        insert into student (name,age)
        values(#{name},#{age})
    

说明:

  1. useGeneratedKeys表示自动生成主键,keyProperty表示主键的字段。
  2. 返回的主键并不是在方法返回值中,而是在参数studentModel中。

sqlsession的代码如下:

            //row为影响的条数
            int row = sqlSession.insert("student.insert", student);
            //id为返回的主键id
            int id = student.getId();

二,Oracle数据库insert时返回主键

具体如下:

    
        
            Select 序列名.nextval from dual
        
        insert into user(id,student,age)
        values(#{id},#{student},#{age})
    

注:因为roacle的主键id不是自增长的,所以一个表要关联一个序列号,获取下一个序列号的值当作表的主键。

 

##jdbcType属性的使用

一,jdbcType的使用

在上面的示例中sql语句都不是严格的写法,严格应该如下:

    
        insert into student (name,age)
        values(#{name,jdbcType=VARCHAR},#{age,jdbcType=INTEGER})
    

严格的写法要在获取数据时指定数据类型,jdbcType即是指定数据类型。

二,为什么要使用jdbcType

相信很多人在使用Mybatis时遇到过下面问题:

org.springframework.jdbc.UncategorizedSQLException: Error setting null parameter.  
        Most JDBC drivers require that the JdbcType must be specified for all nullable parameters.
    Caused by: java.sql.SQLException: 无效的列类型: 1111
        at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:70)
        ......

产生这个异常的原因是:当某个参数为null时,系统不知道该参数是什么数据类型,此时就会报错。

但是,我有一个大大的❓,为什么大部分时候都不报错,只有个别情况下报错。希望看到此处的大神给予留言帮助,感激不尽!

解决上面问题的方式就是使用jdbcType指定数据类型。

三,常用的jdbcType与java数据类型的对应关系

常用的对应关系如下:

VARCHAR             String 
NUMERIC             java.math.BigDecimal   
INTEGER             int  
BIGINT              long   
DOUBLE              double  
DATE                java.sql.Date  
TIME                java.sql.Time  
TIMESTAMP           java.sql.Timestamp  

##resultMap的使用

一,定义resultMap

在mapper.xml文件中定义resultMap的方式如下:

    
        
        
        
        
    

说明:

  1. resultMap标签有两个属性,id是该resultMap的标识,type指定数据类型。
  2. 一个result标签对应数据库表中的字段,且对应Model类中的字段。column为数据库表中的字段,property为model类的字段。jdbcType为数据类型。

注:此时jdbyType的数据类型与上面讲的jdbcType的类型一致,但此时使用双引号,上面不需要双引号。

二,resultMap的使用

使用示例如下:

    

说明:

  1. 这是一个查询语句,此时查询的结果封装到resultMap中,此时resultMap属性的值即为定义resultMap时的id。
  2. 此时select name时不需要写as name,会根据resultMap中定义的对应关系对应Model类中的字段。
  3. 在java代码中直接使用resultMap中定义的Model类数据接收即可。

三,resultMap的作用

resultMap有两大作用:

  1. 指定数据库表中的字段与Model类中的字段的对应关系。
  2. 可以复用。

 

##sql片段的使用

在mapper.xml文件中可以定义sql片段,然后被其他地方使用。具体如下:

一,sql片段的定义

    
        id, name, age
    

说明:

  1. 定义sql片段使用sql标签,id属性为该sql片段的标识。
  2. 在sql片段中可以是任意sql中的一段。

二,sql片段的使用

    

说明:

  1. 使用include引用sql片段,refid对应sql片段的ID。
  2. 引用sql片段等效于把该段sql写到引用处。

三,sql片段的作用

sql片段的最大作用就是复用,类似于java代码中的字符串常量,也便于修改维护。

 

##mapper.xml文件中特殊字符的处理

mapper.xml文件是一个xml文件,一些字符被作为xml的定义符号,当sql语句中使用这些特殊符号时需要做特殊处理。处理方式有两种,一种是使用转译字符,另外一种使用

一,使用转译字符

常见的需要转译的字符如下:

原符号        <        <=        >        >=         &           '                "

替换符号    <    <=     >    >=    &    '      "

例如:sql如下:

create_date_time >= #{startTime} and  create_date_time <= #{endTime}

二,使用

写在“”里面的字符不会被mybatis解析,直接拼接到sql语句中。如下:

大于等于

= ]]>

小于等于

例如:sql如下:

create_date_time = ]]> #{startTime} and  create_date_time #{endTime}

 

##总结

MyBatis是一个非常优秀的框架,不仅将sql与代码分离,而且提供了很好的数据交互方式。

 

 

 

你可能感兴趣的:(我的Java之路)