Mybatis 27_类型别名和自定义对象工厂 项目settingsTest 项目aliasl 项目aliasl2 项目objectFactory

27_类型别名和自定义对象工厂

  • 项目:7settingsTest
    • 设置配置:
  • 项目:8aliasl
    • 为类型配置别名
  • 项目:9aliasl2
    • 为指定包下所有的类起了别名
    • 在此基础上用@Alias注解为特定类型指定别名
  • 项目10objectFactory
    • 对象工厂:

项目:7settingsTest

设置配置:

它用于设置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

项目:8aliasl

为类型配置别名

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?)"。

项目:9aliasl2

为指定包下所有的类起了别名

默认规则是:别名为类名的首字母小写
为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注解为特定类型指定别名

你可以显式用@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>

项目10objectFactory

对象工厂:

结果集映射时,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}]]

你可能感兴趣的:(mybatis,java,eclipse,mysql)