1.设置别名
当文件全类名很长时,可以对其设置一个别名,这样,当下次需要用到时,就可以用别名代替全类。定义别名后,大小写不敏感,类似数据库sql语句中大小写不敏感。
1.1 设置单个别名
在conf.xml中添加 < typeAliases> 标签
type里面是文件的全类名,alias后面是自己定义的别名
<typeAliases>
<!--
设置单个别名,定义别名可以把某处全类名较长的名称改成方便书写的名称,
以后出现长名称的地方都可以用自己定义的名称代替,定义别名后,大小写不敏感
-->
<typeAlias type="one.StudentMapper" alias="stuMapper"/>
<typeAlias type="one.Student" alias="stu"/>
</typeAliases>
1.2 批量设置别名
同样在conf.xml文件中进行
<typeAliases>
<package name="one"/>
<!--直接写包名,该包内所有类的别名就是该类名本身(不用再写包名)-->
</typeAliases>
1.3 除了自定义的别名外,mybatis中还自带一些类的别名,可参考mybatis官网上的文档。
下面是一些常见的 Java 类型内建的类型别名。它们都是不区分大小写的,注意,为了应对原始类型的命名重复,采取了特殊的命名风格。
别名 | 映射的类型 |
---|---|
_byte | byte |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | String |
byte | Byte |
long | Long |
short | Short |
int | Integer |
integer | Double |
float | Float |
boolean | Boolean |
date | Date |
decimal | BigDecimal |
bigdecimal | BigDecimal |
object | Object |
map | Map |
hashmap | HashMap |
list | List |
arraylist | ArrayList |
collection | Collection |
iterator | Iterator |
2. 类型转换器
Mybatis将数据库和java建立映射,如果java中的成员和数据库中对应的列名属性对应,或者可以用Mybatis自带的类型处理器识别,如java中的String和jdbc中的varchar,则不需要类型转换器。
否则需要使用类型转换器。
Mybatis有很多自带的类型处理器,我们也可以自定义类型处理器。
2.1 Mybatis自带的类型处理器
Mybatis内置的类型处理器如表所示
类型处理器 | Java类型 | JDBC类型 |
---|---|---|
BooleanTypeHandler | Boolean,boolean | 任何兼容的布尔值 |
ByteTypeHandler | Byte,byte | 任何兼容的数字或字节类型 |
ShortTypeHandler | Short,short | 任何兼容的数字或短整型 |
IntegerTypeHandler | Integer,int | 任何兼容的数字和整型 |
LongTypeHandler | Long,long | 任何兼容的数字或长整型 |
FloatTypeHandler | Float,float | 任何兼容的数字或单精度浮点型 |
DoubleTypeHandler | Double,double | 任何兼容的数字或双精度浮点型 |
BigDecimalTypeHandler | BigDecimal | 任何兼容的数字或十进制小数类型 |
StringTypeHandler | String | CHAR和VARCHAR类型 |
ClobTypeHandler | String | CLOB和LONGVARCHAR类型 |
NStringTypeHandler | String | NVARCHAR和NCHAR类型 |
NClobTypeHandler | String | NCLOB类型 |
ByteArrayTypeHandler | byte[] | 任何兼容的字节流类型 |
BlobTypeHandler | byte[] | BLOB和LONGVARBINARY类型 |
DateTypeHandler | Date(java.util) | TIMESTAMP类型 |
DateOnlyTypeHandler | Date(java.util) | DATE类型 |
TimeOnlyTypeHandler | Date(java.util) | TIME类型 |
SqlTimestampTypeHandler | Timestamp(java.sql) | TIMESTAMP类型 |
SqlDateTypeHandler | Date(java.sql) | DATE类型 |
SqlTimeTypeHandler | Time(java.sql) | TIME类型 |
ObjectTypeHandler | 任意 | 其他或未指定类型 |
EnumTypeHandler | Enumeration类型 | VARCHAR。任何兼容的字符串类型,作为代码存储(而不是索引)。 |
2.2 自定义类型转换器
2.2.1 继承BaseTypeHandler接口
实现自定义类型转换器有两种方法,
1 实现TypeHandler接口
2 继承BaseTypeHandler接口
方法二更简单,我们用 2 来写一个自定义类型转换器。
我们在数据库中student表里加一列,列名为sex,类型为int,其中1代表男生,0代表女生,
在Student类中加一个成员 sex,类型为boolean
建立一个可以识别jdbc中的int和java中的boolean的类型处理器
我定义了一个converter1类
package one;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class converter1 extends BaseTypeHandler<Boolean> {//<>里写自己需要转换的java类型
public converter1(){
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Boolean aBoolean, JdbcType jdbcType) throws SQLException {
if(aBoolean){
//设为1
ps.setInt(i,1);//位置为i,设置为1
}else{
ps.setInt(i,0);
}
}
// set 即是将java(举例boolean)类型转换为jdbc类型(举例integer)
//PreparedStatement ps 指示操作的对象,和以前用到的statement用法相同
// int i,i是下标,表明是第几次操作,aBoolean是java输入的boolean值,比如此时输入为true,则o为true,jdbctype是数据库对应的值
@Override
public Boolean getNullableResult(ResultSet rs, int i) throws SQLException {
rs.getInt(i); //得到i的值
// if(i==1){
// return true;
// }
// else return false;
return i == 1;//如果i==1 return true ,否则return false
}//通过下标拿值
//get --> jdbc(INTEGER)->java(boolean)
@Override
public Boolean getNullableResult(ResultSet res, String s) throws SQLException {
int sex=res.getInt(s); //与上一种方法相似,得到s的值
return sex==1;
}//通过列名拿值
@Override
public Boolean getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
int sex=callableStatement.getInt(i);
return sex==1;
}//通过存储过程拿值
}
这里面的四个方法都是重写的BaseTypeHandler中的方法。
converter1中写一个空的方法很重要,不写的话就会报错。
2.2.2 在conf.xml中配置类型转换器
<!--配置类型转换器-->
<typeHandlers>
<typeHandler javaType="boolean" jdbcType="INTEGER"
handler="one.converter1"></typeHandler>
<package name = "one" />
</typeHandlers>
注意这些标签是有顺序的,typehandler标签应该写在别名typeAliases标签之后,写在environment标签之前。
2.2.3 在相应mapper文件中使用类型转换器
<!--使用了类型转换器 ,把resultType改为resultMap
如果类和表中的字段可以合理识别,则不需要使用类型转换器
-->
<select id ="selectOneStudent" parameterType="int" resultMap="studentResult">
select * from student where id = #{id}
</select>
<resultMap id="studentResult" type="one.Student">
<!-- 分为主键id和非主键result-->
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="gname" column="gname"/>
<result property="sex" column="sex" javaType="boolean" jdbcType="INTEGER"
typeHandler="one.converter1"/>
</resultMap>
这里我是把前一节动态代理方式执行crud的一个方法给改了一下,select的id值没变,只需要把原来的resultType改为resultMap
然后再写一个resultMap, id值和上面的select标签里的resultMap双引号里的内容对应,表明是这个sql语句对应的resultMap
在需要进行类型转换的列的那一个标签里需要写上jdbcType和javaType,最好把typeHandler也写上
别的就跟以前的一样了,至此,就可以去test方法里测试了。
补充一个,如果mapper文件里的sql语句里原来没有resultType,那么就不能改成resultMap,这时候怎么写呢
<insert id="addStudentWithConverter" parameterType="one.Student">
insert into student(id,name,gname,sex) values(#{id},#{name},#{gname},#{sex,javaType=boolean,jdbcType=INTEGER})
</insert>
3. resultMap
如果类中的字段名和表中的列名不能合理识别(id-no),使用resultMap,可以合理识别(id-Id),使用resultType
resultMap和上面的2.2.3用法相同
通过这节,可以知道resultMap作用:
- 类型转换
- 建立类中字段和表中的列的映射