详细说明几个比较重要的mybatis配置项
2.1、使用properties配置属性在日常工作中,我们可能需要将一些配置信息写在一个单独的properties配置文件中便于管理,mybatis对此进行了很好的支持
2.1.1、引入外部properties文件或在properties标签内定义属性- 创建db.properties文件
url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true driverClass=com.mysql.cj.jdbc.Driver username=root pwd=Test#123345
- 在mybatis主配置文件导入db.properties
2.1.1.1、如果一个属性在不只一个地方进行了配置,加载顺序(官方解释)如下:
-
首先读取在 properties 元素体内指定的属性。
-
然后根据 properties 元素中的 resource 属性读取类路径下属性文件,或根据 url 属性指定的路径读取属性文件,并覆盖之前读取过的同名属性。
-
最后读取作为方法参数传递的属性,并覆盖之前读取过的同名属性。
总结:如果存在同名属性,resource指向的文件中的属性值将会覆盖元素体内指定的属性值。2.2、类型别名(typeAliases) 2.2.1、对象别名
- 类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。例如:
在指定了别名之后,就可以在mapper的xml文件中使用别名而不用写全路径的限定名称了:
2.2.2、指定包名,自动生成别名select * from user
- typeAliases也可以指定一个包名,例如:
在指定了一个包名之后,会使用类名的首字母小写的非限定类名来作为它的别名,例如:
//这里的话就会用user来作为别名
public class User {
private int id;
private String name;
private String pwd;
}
也可以使用注解结合typeAliases指定报名来实现定义别名。例如:
//使用注解指定别名
@Alias("user")
public class User {
private int id;
private String name;
private String pwd;
}
2.2.3内置的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 | Integer |
| double | Double |
| float | Float |
| boolean | Boolean |
| date | Date |
| decimal | BigDecimal |
| bigdecimal | BigDecimal |
| object | Object |
| map | Map |
| hashmap | HashMap |
| list | List |
| arraylist | ArrayList |
| collection | Collection |
- 官方解释:
MyBatis 在设置预处理语句(PreparedStatement)中的参数或从结果集中取出一个值时, 都会用类型处理器将获取到的值以合适的方式转换成 Java 类型。下表描述了一些默认的类型处理器。
- 来个冗长的类型处理器对应的表吧:
| 类处理器名称 | Java类型 | jdbc类型 |
|---|---|---|
| BooleanTypeHandler | java.lang.Boolean, boolean | 数据库兼容的 BOOLEAN |
| ByteTypeHandler | java.lang.Byte, byte | 数据库兼容的 NUMERIC 或 BYTE |
| ShortTypeHandler | java.lang.Short, short | 数据库兼容的 NUMERIC 或 SMALLINT |
| IntegerTypeHandler | java.lang.Integer, int | 数据库兼容的 NUMERIC 或 INTEGER |
| LongTypeHandler | java.lang.Long, long | 数据库兼容的 NUMERIC 或 BIGINT |
| FloatTypeHandler | java.lang.Float, float | 数据库兼容的 NUMERIC 或 FLOAT |
| DoubleTypeHandler | java.lang.Double, double | 数据库兼容的 NUMERIC 或 DOUBLE |
| BigDecimalTypeHandler | java.math.BigDecimal | 数据库兼容的 NUMERIC 或 DECIMAL |
| StringTypeHandler | java.lang.String | CHAR, VARCHAR |
| ClobReaderTypeHandler | java.io.Reader | - |
| ClobTypeHandler | java.lang.String | CLOB, LONGVARCHAR |
| NStringTypeHandler | java.lang.String | NVARCHAR, NCHAR |
| NClobTypeHandler | java.lang.String | NCLOB |
| BlobInputStreamTypeHandler | java.io.InputStream | - |
| ByteArrayTypeHandler | byte[] | 数据库兼容的字节流类型 |
| BlobTypeHandler | byte[] | BLOB, LONGVARBINARY |
| DateTypeHandler | java.util.Date | TIMESTAMP |
| DateOnlyTypeHandler | java.util.Date | DATE |
| TimeOnlyTypeHandler | java.util.Date | TIME |
| SqlTimestampTypeHandler | java.sql.Timestamp | TIMESTAMP |
| SqlDateTypeHandler | java.sql.Date | DATE |
| SqlTimeTypeHandler | java.sql.Time | TIME |
| ObjectTypeHandler | Any | OTHER 或未指定类型 |
| EnumTypeHandler | Enumeration Type | VARCHAR 或任何兼容的字符串类型,用来存储枚举的名称(而不是索引序数值) |
| EnumOrdinalTypeHandler | Enumeration Type | 任何兼容的 NUMERIC 或 DOUBLE 类型,用来存储枚举的序数值(而不是名称)。 |
| SqlxmlTypeHandler | java.lang.String | SQLXML |
| InstantTypeHandler | java.time.Instant | TIMESTAMP |
| LocalDateTimeTypeHandler | java.time.LocalDateTime | TIMESTAMP |
| LocalDateTypeHandler | java.time.LocalDate | DATE |
| LocalTimeTypeHandler | java.time.LocalTime | TIME |
| OffsetDateTimeTypeHandler | java.time.OffsetDateTime | TIMESTAMP |
| OffsetTimeTypeHandler | java.time.OffsetTime | TIME |
| ZonedDateTimeTypeHandler | java.time.ZonedDateTime | TIMESTAMP |
| YearTypeHandler | java.time.Year | INTEGER |
| MonthTypeHandler | java.time.Month | INTEGER |
| YearMonthTypeHandler | java.time.YearMonth | VARCHAR 或 LONGVARCHAR |
自定义类型处理器,将getNullableResult获取结果返回值写一个固定的值测试是否生效
package com.szm.handler; import org.apache.ibatis.type.baseTypeHandler; import org.apache.ibatis.type.JdbcType; import org.apache.ibatis.type.MappedJdbcTypes; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; @MappedJdbcTypes(JdbcType.VARCHAR) public class MyTypeHandler 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 "myTypeHandlerString-getNullableResult(ResultSet rs, String columnName)"; //return rs.getString(columnName); } @Override public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException { return "myTypeHandlerString-getNullableResult(ResultSet rs, int columnIndex)"; // return rs.getString(columnIndex); } @Override public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { return "myTypeHandlerString-getNullableResult(CallableStatement cs, int columnIndex)"; // return cs.getString(columnIndex); } }
xml配置此类型处理器:
测试代码:
@Test
public void test() throws IOException {
String resource = "mybatis.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List users = mapper.selectUserLike("user");
users.stream().forEach((e)->{
System.out.println(e);
});
sqlSession.close();
}
结果可以看到所有的String类型参数结果都是我们定义的固定返回值:
User(id=1, name=myTypeHandlerString-getNullableResult(ResultSet rs, String columnName), pwd=myTypeHandlerString-getNullableResult(ResultSet rs, String columnName)) User(id=2, name=myTypeHandlerString-getNullableResult(ResultSet rs, String columnName), pwd=myTypeHandlerString-getNullableResult(ResultSet rs, String columnName)) User(id=3, name=myTypeHandlerString-getNullableResult(ResultSet rs, String columnName), pwd=myTypeHandlerString-getNullableResult(ResultSet rs, String columnName))2.4、对象工厂(objectFactory) 2.4.1、官方解释
2.4.2、代码实现每次 MyBatis 创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成实例化工作。 默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认无参构造方法,要么通过存在的参数映射来调用带有参数的构造方法。 如果想覆盖对象工厂的默认行为,可以通过创建自己的对象工厂来实现。
-
在User对象中新增一个数据库中没有的扩展字段
package com.szm.pojo; import lombok.AllArgsConstructor; import lombok.Data; @Data public class User { private int id; private String name; private String pwd; //查询结果没有这个字段 private String extendField; } -
自定义对象工厂
package com.szm.factory;
import com.szm.pojo.User;
import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
import java.util.List;
import java.util.UUID;
public class MyObjectFactory extends DefaultObjectFactory {
@Override
public T create(Class type, List> constructorArgTypes, List
- 配置自定义对象工厂
- 测试
@Test
public void test() throws IOException {
String resource = "mybatis.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List users = mapper.selectUserLike("user");
users.stream().forEach((e)->{
System.out.println(e);
});
sqlSession.close();
}
- 结果
User(id=1, name=user1, pwd=pwd1, nickname=123) User(id=2, name=user2, pwd=pwd2, nickname=123) User(id=3, name=user3, pwd=pwd3, nickname=123)2.5、映射器(mappers) 2.5.1、xml配置映射器
- 配置文件在java包路径下
- 当前文件系统下的任意一个位置
- 直接指定mapper接口位置(这种方式你必须在接口使用注解方式定义好要执行的sql语句)



