properties属性
conf.xml
<dataSource type="POOLED">
<property name="driver" value="oracle.jdbc.OracleDriver" />
<property name="url"
value="jdbc:oracle:thin:@127.0.0.1:1521:test" />
<property name="username" value="system" />
<property name="password" value="sa" />
</dataSource>
为了方便查阅和维护数据的信息,可以把数据库信息单独写在一个属性文件中,需要的时候直接引用即可。在src下新建properties文件。
数据库以“key=value”的形式,写在该属性文件中。
db.properties
driver=oracle.jdbc.OracleDriver
url=jdbc:oracle:thin:@127.0.0.1:1521:test
username=system
password=sa
然后修改配置文件,将properties标签引入该属性文件,并以形如EL的方式引用属性值。
conf.xml
…
<configuration>
<!-- 引用db.properties配置文件 -->
<properties resource="db.properties"/>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<!-- 配置数据库连接信息 -->
<dataSource type="POOLED">
<!-- value属性值:引用db.properties配置文件中配置的值 -->
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>
…
</configuration>
settings全局参数配置
<configuration>
标签下有一个<settings>
子标签,可以用来设置mybatis框架的运行参数,比如设置二级缓存、延迟加载等。修改这些配置,会影响到MyBatis整体的运行行为,因此需要谨慎操作。常见的配置参数介绍如下表
参数 | 简介 | 有效值 |
---|---|---|
cacheEnabled | 在全局范围内,启用或禁用缓存 | true(默认)、false |
lazyLoadingEnabled | 在全局范围内启用或禁用延迟加载。当禁用时,所有关联的对象都将立即加载(热加载) | true(默认)、false |
aggressiveLazyLoading | 启用时,有延迟加载属性的对象,在被调用时将会完全加载所有属性(立即加载)。否则,每个属性都将桉需加载(延迟加载) | true(默认),false |
multipleReslutSetsEnabled | 允许或禁止执行一条单独的SQL语句后返回多条结果集;需要驱动程序支持 | true(默认)、默认 |
autoMappingBehaivor | 指定数据表字段和对象属性的映射方式。 NONE:禁止自动映射,只允许手工配置的映射。 PARTIAL:只会自动映射简单的、没有嵌套的结果。 FULL:自动映射任何结果(包含嵌套等)。 | NONE、PARTIAL(默认)、FULL |
defalutStatementTimeout | 设置驱动器等待数据库回应的最长时间 | 以秒为单位的,任意正整数。无默认值 |
safeRowBoundsEnabled | 允许或禁止使用嵌套的语句 | true、false(默认) |
mapUnderscoreToCamelCase | 当在数据表中遇到有下划线的字段时,自动映射到相应驼峰式形式的Java属性名。例如,会自动将数据表中的stu_no字段,映射到POJO类的stuNo属性。 | true、false(默认) |
lazyLoadTriggerMethods | 指定触发延迟加载的对象的方法 | equals、clone、hashCode、toString |
conf.xml
…
<configuration>
<properties resource="db.properties"/>
<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="defaultStatementTimeout" value="25"/>
<setting name="mapUnderscoreToCamelCase" value="false"/>
<setting name="localCacheScope" value="SESSION"/>
<setting name="lazyLoadTriggerMethods"
value="equals,clone,hashCode,toString"/>
…
</settings>
…
</configuration>
自定义别名
SQL映射文件中,parameterType或resultType为实体类的对象类型,通过全类名的形式指定(包名+类名)。
还可以在Mybatis配置文件中conf.xml为实体类设置别名,然后在SQL映射文件中使用该别名。
示例:
Mapper.xml
…
<select id="queryStudentByNo" parameterType="int"
resultType="org.lzy.entity.Student">
select * from student where stuNo=#{stuNo}
</select>
…
改为:
<configuration>
<properties resource="db.properties"/>
<settings>… </settings>
<!--为实体类,定义别名 -->
<typeAliases>
<typeAlias type="org.lzy.entity.Student" alias="student"/>
<typeAlias type="类型A" alias="别名a"/>
<typeAlias type="类型B" alias="别名b"/>
…
</typeAliases>
…
</configuration>
给“org.lzy.entity.Student”类型定义了别名“student(不分区大小写)”。以后任何“org.lzy.entity.Student”出现的地方,都可以用“student、Student、sTUdent、或STUDENT等”来替代。
批量定义别名
当要定义多个别名时,就必须配置多个<typeAlias>
。我们还可以一次性的,定义一批别名。
在给一个package的所有实体类定义别名
conf.xml
<typeAliases>
<package name="org.lzy.entity"/>
<package name="其他包"/>
</typeAliases>
将“org.lzy.entity”包中所有的实体类都自动定义了别名,别名就是其不带包名的类名(不区分大小写)。org.lzy.entity.Student类的别名定义为Student、student、sTUdent或STUDENT等
typeHandlers类型处理器
类型处理器用于java类型和jdbc类型之间的映射
Mybatis内置一些常用类型处理器,可以将parameterType中传入的类型,自动转为JDBC需要的类型。
Mybatis内置的类型处理器
类型处理器 | Java类型 | JDBC类型 |
---|---|---|
BooleanTypeHandler | Boolean,boolean | 任何兼容的布尔值 |
ByteTypeHandler | Byte,byte | 任何兼容的数字或字节类型 |
ShortTypeHandler | Short,short | 任何兼容的数字或短整型 |
IntegerTypeHandler | Integer,int | 任何兼容的数字或整型 |
LongTypeHandler | Long,long | 任何兼容的数字或长整型 |
FloatTypeHandler | Double,double | 任何兼容的数字或单精度浮点型 |
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。任何兼容的字符串类型,作为代码存储(而不是索引)。 |
自定义类型处理器
可以自定义类型处理器,来实现特定的java类型与jdbc类型之间的映射。
先给学生实体类Student.java中增加一个表示性别的属性(boolean stuSex),并给学生表增加一个性别字段(number stuSex)。由于属性stuSex是boolean类型,而字段stuSex是数字number类型,因此我们需要实现一个类型处理器,用来实现java中的boolean类型和数据库中number类型之间映射和转换。
约定:
学生实体类中的stuSex属性:true表示男,false表示女
学生表中的stuSex字段: 1表示男,0表示女。
开发并使用自定义类型处理器具体步骤如下:
一、创建自定义类型处理器
实现TypeHandler接口 或继承 BaseTypeHandler抽象类
BaseTypeHandler底层实现了TypeHandler接口,并对接口中方法做了简单处理。
例:
org.lzy.converter.BooleanAndIntConverter.java
public class BooleanAndIntConverter extends BaseTypeHandler<Boolean> {
/**
* java类型(boolean) -> JDBC类型(number)
* @param ps: 当前的PreparedStatement对象
* @param i : 当前参数的位置
* @param parameter: 当前参数值
*/
public void setNonNullParameter(PreparedStatement ps, int i, Boolean parameter, JdbcType jdbcType)
throws SQLException
{
/*
* 如果Java类型的parameter==true,则在数据库中存储jdbc类型的数字1;
* 如果Java类型的parameter==false,则在数据库中存储jdbc类型的数字0;
*/
if (parameter)
{
ps.setInt(i, 1);
}
else
{
ps.setInt(i, 0);
}
}
/**
* JDBC类型(NUMBER)-->java类型(booean)
*/
@Override
public Boolean getNullableResult(ResultSet rs, String columnName) throws SQLException
{
/*
* 通过字段名获取值
*/
int sexNum = rs.getInt(columnName);
/*
* 如果数据库中的jdbc变量sexNum == 1,则返回java类型的true; 如果数据库中的jdbc变量sexNum ==
* 0,则返回java类型的false;
*/
if (sexNum == 1)
{
return true;
}
else
{
return false;
}
}
/**
* JDBC类型(NUMBER)-->java类型(booean)
*/
@Override
public Boolean getNullableResult(ResultSet rs, int columnIndex) throws SQLException
{
/*
* 通过字段的索引获取值
*/
int sexNum = rs.getInt(columnIndex);
if (sexNum == 1)
{
return true;
}
else
{
return false;
}
}
/**
* JDBC类型(NUMBER)-->java类型(booean)
*/
@Override
public Boolean getNullableResult(CallableStatement cs, int columnIndex) throws SQLException
{
/*
* 通过调用存储过程获取值
*/
int sexNum = cs.getInt(columnIndex);
if (sexNum == 1)
{
return true;
}
else
{
return false;
}
}
}
查询时,使用自定义类型处理器(jdbc类型的NUMBER→ java类型的Boolean)
SQL映射文件:studentMapper.xml
<select id="queryStudentByStuNoWithConverter"
parameterType="int" resultMap="studentResult">
select * from student where stuNo=#{stuNo}
</select>
<resultMap id="studentResult" type="org.lzy.entity.Student">
<id property="stuNo" column="stuNo"/>
<result property="stuName" column="stuName"/>
<result property="stuSex" column="stuSex"
javaType="java.lang.Boolean" jdbcType="INTEGER"/>
</resultMap>