它用于设置MyBatis的一些全局信息。
可通过MyBatis获取可配置的信息
更改主配置文件
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="logImpl" value="LOG4J2"/>
settings>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://192.168.8.131:3306/mybatis?serverTimezone=UTC" />
<property name="username" value="root" />
<property name="password" value="1234" />
dataSource>
environment>
environments>
<mappers>
<mapper resource="org/itcheng/app/dao/NewsMapper.xml" />
mappers>
configuration>
如果设置的value值在项目中没有对应的日志实现包,那么会报错
<settings>
<setting name="logImpl" value="SLF4J"/>
settings>
报错如下
Caused by:java.lang.NoClassDefFoundError:org/slf4j/LoggerFactory
MyBatis支持为类指定一个简短的别名。
为单个类指定别名:
<typeAlias type="org.itcheng.app.domain.News" alias="news"/>
清晰明了、但很繁琐!
更改主配置文件
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<typeAlias type="org.itcheng.app.domain.News" alias="news"/>
typeAliases>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC" />
<property name="username" value="root" />
<property name="password" value="root" />
dataSource>
environment>
environments>
<mappers>
<mapper resource="org/itcheng/app/dao/NewsMapper.xml" />
mappers>
configuration>
更改mapper配置文件
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.itcheng.app.dao.NewsMapper">
<select id="findNews" resultType="news">
select news_id id, news_title title, news_content content from news_inf where news_id > #{id}
select>
mapper>
注意:typeAlias 标签位置有要求要在settings标签之后environments标签之前,否则报如下错误
Exception in thread "main" org.apache.ibatis.exceptions.PersistenceException:
Error building SqlSession.
Cause: org.apache.ibatis.builder.BuilderException: Error creating document instance. Cause: org.xml.sax.SAXParseException; lineNumber: 32; columnNumber: 17; 元素类型为 "configuration" 的内容必须匹配 "(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?)"。
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:80)
at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:64)
at lee.NewsManager.main(NewsManager.java:23)
Caused by: org.apache.ibatis.builder.BuilderException: Error creating document instance. Cause: org.xml.sax.SAXParseException; lineNumber: 32; columnNumber: 17; 元素类型为 "configuration" 的内容必须匹配 "(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?)"。
at org.apache.ibatis.parsing.XPathParser.createDocument(XPathParser.java:263)
at org.apache.ibatis.parsing.XPathParser.(XPathParser.java:127)
at org.apache.ibatis.builder.xml.XMLConfigBuilder.(XMLConfigBuilder.java:81)
at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:77)
... 2 more
Caused by: org.xml.sax.SAXParseException; lineNumber: 32; columnNumber: 17; 元素类型为 "configuration" 的内容必须匹配 "(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?)"。
默认规则是:别名为类名的首字母小写
为org.itcheng.app.domain包下所有的类起了别名,均为小写.
更改主配置文件
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<package name="org.itcheng.app.domain"/>
typeAliases>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://192.168.8.131:3306/mybatis?serverTimezone=UTC" />
<property name="username" value="root" />
<property name="password" value="1234" />
dataSource>
environment>
environments>
<mappers>
<mapper resource="org/itcheng/app/dao/NewsMapper.xml" />
mappers>
configuration>
更改Mapper配置文件
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.itcheng.app.dao.NewsMapper">
<select id="findNews" resultType="news">
select news_id id, news_title title, news_content content from news_inf where news_id > #{id}
select>
mapper>
你可以显式用@Alias注解为特定类型指定别名.
package org.itcheng.app.domain;
import org.apache.ibatis.type.Alias;
//此处指定该News类的别名为nw
@Alias("nw")
public class News {
private Integer id;
private String title;
private String content;
//set和get方法,有参无参构造器
}
更改配置文件
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.itcheng.app.dao.NewsMapper">
<select id="findNews" resultType="nw">
select news_id id, news_title title, news_content content from news_inf where news_id > #{id}
select>
mapper>
结果集映射时,MyBatis需要为结果集的每行都创建一个对象 —— 这个创建过程由对象工厂来完成。
▲ MyBatis的扩展点:
开发者可以自定义自己的对象工厂。
假如业务需求:每次从数据中查询到New对象时,都为之添加一些额外的meta属性。
▲ 自定义对象工厂:
(1)开发自定义对象工厂实现类
对象工厂类要实现ObjectFactory接口,实际上会通过继承DefaultObjectFactory实现类
根据需要重写它指定的方法
方法1<T> T create(Class<T> type)
Creates a new object with default constructor.
方法2<T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs)
Creates a new object with the specified constructor and params.
方法3<T> boolean isCollection(Class<T> type)
Returns true if this object can have a set of other objects.
方法4protected Class<?> resolveInterface(Class<?> type)
(2)配置对象工厂
主配置文件添加objectFactory标签type属性值为自定对象工厂,子标签property用于为对象工厂设置属性。在自定义工厂对象中可以通过setProperties方法进行设置。
=具体代码更改如下=
创建自定义对象工厂继承DefaultObjectFactory实现类
package org.itcheng.app;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
import org.itcheng.app.domain.News;
public class FkObjectFactory extends DefaultObjectFactory
{
private static final long serialVersionUID = 1L;
private String author;
// MyBatis使用无参数的构造器创建对象时,调用该方法
@Override
public Object create(Class type)
{
// 调用父类的方法先创建对象
Object ob = super.create(type);
// 通过调用 processObject方法对创建出来的对象进行额外的处理
return processObject(ob);
}
// MyBatis使用有参数的构造器创建对象时,调用该方法
@Override
public <T> T create(Class<T> type, List<java.lang.Class<?>> constructorArgTypes,
List<Object> constructorArgs)
{
// 调用父类的方法先创建对象
T ob = super.create(type, constructorArgTypes, constructorArgs);
// 通过调用 processObject方法对创建出来的对象进行额外的处理
return (T) processObject(ob);
}
// 该方法用于接收对象的配置信息,从主配置文件的objectFactory标签的子标签property获取值
public void setProperties(Properties props)
{
super.setProperties(props);
System.out.println("-------为对象工厂设置属性------" + props);
this.author = props.getProperty("author");
}
public Object processObject(Object ob)
{
if (ob instanceof News)
{
News target = (News) ob;
target.getMeta().put("author", author);
target.getMeta().put("viewDate", new Date());
return target;
}
else
{
return ob;
}
}
}
更改对象类
package org.itcheng.app.domain;
import java.util.HashMap;
import java.util.Map;
public class News {
private Integer id;
private String title;
private String content;
private Map<String , Object> meta = new HashMap<>();
//set和get方法,有参和无参构造器
}
更改主配置文件
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<objectFactory type="org.itcheng.app.FkObjectFactory">
<property name="abc" value="aaaaa"/>
<property name="xyz" value="nono"/>
<property name="author" value="itcheng"/>
objectFactory>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://192.168.8.131:3306/mybatis?serverTimezone=UTC" />
<property name="username" value="root" />
<property name="password" value="1234" />
dataSource>
environment>
environments>
<mappers>
<mapper resource="org/itcheng/app/dao/NewsMapper.xml" />
mappers>
configuration>
更改测试主类
package lee;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
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 org.itcheng.app.dao.NewsMapper;
import org.itcheng.app.domain.News;
public class NewsManager
{
// SqlSessionFactory应该是应用级别
private static SqlSessionFactory sqlSessionFactory;
public static void main(String[] args) throws IOException
{
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
// 1. 创建SqlSessionFactory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 2. 打开SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 查询消息
selectNews(sqlSession);
}
public static void selectNews(SqlSession sqlSession)
{
// 此处的NewsMapper只是一个接口
// MyBatis会使用JDK的动态代理为Mapper接口生成实现类
NewsMapper newsMapper = sqlSession.getMapper(NewsMapper.class);
System.out.println(newsMapper.getClass());
List<?> list = newsMapper.findNews(-1);
list.forEach(e -> {
System.out.println(((News) e).getMeta().get("author"));
System.out.println(((News) e).getMeta().get("viewDate"));
});
System.out.println(list);
// 4. 提交事务
sqlSession.commit();
// 5. 关闭资源
sqlSession.close();
}
}
结果如下
-------为对象工厂设置属性------{abc=aaaaa, author=itcheng, xyz=nono}
class com.sun.proxy.$Proxy17
DEBUG [main] org.itcheng.app.dao.NewsMapper.findNews ==> Preparing: select news_id id, news_title title, news_content content from news_inf where news_id > ?
DEBUG [main] org.itcheng.app.dao.NewsMapper.findNews ==> Parameters: -1(Integer)
DEBUG [main] org.itcheng.app.dao.NewsMapper.findNews <== Total: 1
itcheng
Sun Nov 19 00:15:35 CST 2023
[News [id=1, title=测试标题, content=测试内容, meta={author=itcheng, viewDate=Sun Nov 19 00:15:35 CST 2023}]]