Mybatis 28_加载Mapper及自定义类型处理器 项目TypeConverter

发布时间:2024年01月11日

28_加载Mapper及自定义类型处理器

项目:11TypeConverter

加载Mapper的方式:

▲ 共有4种加载Mapper的方式:
1、2. 明确指定XML Mapper的位置(resource与url二者选其一)
<mapper resource|url=“被加载XML Mapper文件” …/>

	<mappers>
		<!-- mapper文件负责管理MyBatis的SQL语句 -->
		<mapper resource="org/itcheng/app/dao/NewsMapper.xml" />
	</mappers>
	<mappers>
		<!-- mapper文件负责管理MyBatis的SQL语句 -->
		<mapper url="file:///D:/mytool/javagongju/fengkuangjavajiangyi/javassmday03/10objectFactory/src/org/itcheng/app/dao/NewsMapper.xml" />
	</mappers>
  1. 明确指定Mapper的类名 <mapper class=“Mapper接口的全限定类名” …/>
	<mappers>
		<!-- mapper文件负责管理MyBatis的SQL语句 -->
		<mapper resource="org.itcheng.app.dao.NewsMapper" />
	</mappers>
  1. 指定特定包下面所有Mapper <package name=“Mapper接口所在包” …/>
	<mappers>
		<!-- 加载指定包下面所有Mapper -->
		<package name="org.itcheng.app.dao" />
	</mappers>

类型处理器:

类型处理器的作用:负责完成数据库中数据类型与Java类型之间的相互转换。
▲ MyBatis内置的数据类型
常见的Java类型与常见数据库中数据类型之间的转换,MyBatis已经提供了类型处理器。
▲ 自定义的数据类型处理器
也属于MyBatis的扩展点。
比如程序,需要完成varchar <----> Name
(1)开发自定义类型处理器
对象工厂类要实现TypeHandler接口,实际上会通过继承BaeTypeHandler实现类
根据需要重写它指定的4个方法

/*
 * java.sql.ResultSet        表示通过结果集取数据
 * java.sql.CallableStatement表示通过CallableStatement取数据
 * 
 * int columnIndex 表示根据列索引进行获取
 * String columnName 表示根据列名进行获取
 * */
// 将数据库的取出的数据类型转换Java类型
@Override
public Name getNullableResult(ResultSet rs, String columnName)  throws SQLException
?
?// 将数据库的取出的数据类型转换Java类型
@Override
public Name getNullableResult(ResultSet rs, int columnIndex)    throws SQLException
??
// 将数据库的取出的数据类型转换Java类型
@Override
public Name getNullableResult(CallableStatement cs, int columnIndex)    throws SQLException
??
// Java类型转换数据库所需的类型
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Name parameter, JdbcType jdbcType) throws SQLException

(2)配置自定义类型处理器
需要使用如下元素来配置自定义的类型处理器

<typeHandler handler="org.itcheng.app.NameTypeHandler" jdbcType="" javaType=""/>

既可在类型处理器的代码上用注解来指定它能处理哪些类型(@MappedJdbcTypes,@MappedTypes),也能在XML配置中指定(typeHandler 标签中属性jdbcType, javaType), 如果两处都指定,XML配置中指定的生效.

User类中有个引用类型Name,mybatis无法将对象Name保存到数据库具体的字段
需要提供自定义类型装换器
2个Bean类

package org.itcheng.app.domain;

public class User
{
	private Integer id;
	private Name name;
	private String password;
	//set和get方法,有参无参构造器,toString方法
}

package org.itcheng.app.domain;

public class Name
{
	private String first;
	private String last;
	//set和get方法,有参无参构造器,toString方法

自定义类型装换器

package org.itcheng.app;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.itcheng.app.domain.Name;

@MappedJdbcTypes(JdbcType.VARCHAR) // 告诉MyBatis,说明该类型转换器只处理数据库的VARCHAR类型
@MappedTypes(Name.class)           // 告诉MyBatis,说明该类型转换器只处理Java的Name类型
public class NameTypeHandler extends BaseTypeHandler<Name>
{
/*
 * java.sql.ResultSet        表示通过结果集取数据
 * java.sql.CallableStatement表示通过CallableStatement取数据
 * 
 * int columnIndex 表示根据列索引进行获取
 * String columnName 表示根据列名进行获取
 * 
 * */
	// 将数据库的取出的数据类型转换Java类型
	@Override
	public Name getNullableResult(ResultSet rs, String columnName)
		throws SQLException
	{
		// 取出实际的值
		String val = rs.getString(columnName);
		//按照"-"进行分隔
		String[] tokens = val.split("-");
		// 将值封装Name对象
		Name name = new Name(tokens[0], tokens[1]);
		return name;	
	}

	// 将数据库的取出的数据类型转换Java类型
	@Override
	public Name getNullableResult(ResultSet rs, int columnIndex)
		throws SQLException
	{
		// 取出实际的值
		String val = rs.getString(columnIndex);
		String[] tokens = val.split("-");
		// 将值封装Name对象
		Name name = new Name(tokens[0], tokens[1]);
		return name;	
	}

	// 将数据库的取出的数据类型转换Java类型
	@Override
	public Name getNullableResult(CallableStatement cs, int columnIndex)
		throws SQLException
	{
		// 取出实际的值
		String val = cs.getString(columnIndex);
		String[] tokens = val.split("-");
		// 将值封装Name对象
		Name name = new Name(tokens[0], tokens[1]);
		return name;	
	}

	// Java类型转换数据库所需的类型
	@Override
	public void setNonNullParameter(PreparedStatement ps, int i,
		Name parameter, JdbcType jdbcType) throws SQLException
	{
		ps.setString(i, parameter.getFirst() + "-" + parameter.getLast());
	}
}

主配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
	PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
	"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- configuration 配置根元素 -->	
<configuration>
    <typeAliases>
        <package name="org.itcheng.app.domain"/>
    </typeAliases>
    <!-- 配置自定义的类型处理器 -->
    <typeHandlers>
        <typeHandler handler="org.itcheng.app.NameTypeHandler"/>
    </typeHandlers>
	<!-- environments 用于配置多个数据库环境 default用于指定默认环境-->
	<environments default="mysql">
		<!-- environment 配置一个数据库环境 id数据库唯一标识-->
		<environment id="mysql">
			<!-- transactionManager 配置事务类型:JDBC或Managed,此时的JDBC等都是实现类的缩写 -->
			<transactionManager type="JDBC" />
			<!-- 配置数据库连接池,POOLED也是一个实现类的缩写  -->
			<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 -->
		<package name="org.itcheng.app.dao" />
	</mappers>
</configuration>

映射文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
	PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
	"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 根元素是mapper,该元素的namespace属性值相当于该mapper的唯一标识 -->	
<mapper namespace="org.itcheng.app.dao.UserMapper">
	<!-- SQL的id需要与Mapper接口的方法名相同  -->
	<insert id="saveUser">
		insert into user_inf values (null, #{name}, #{password})
	</insert>
	

	
	<!-- select必须指定resultType或resultMap两个属性的其中之一
	此处指定结果的每行记录应该映射成News对象
	由于News对象的三个属性分别为id、title、content
	所以此处查询出来的结果集的列别名也被定义成id、title、content
	这样才能保证MyBatis执行同名映射	
	 -->
	<select id="findUsers" resultType="user">
		select user_id id, user_name name, password from user_inf where user_id > #{id}		
	</select>
	
</mapper>

主类

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.UserMapper;
import org.itcheng.app.domain.Name;
import org.itcheng.app.domain.User;

public class UserManager
{
	// 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();
		
		// 保存消息
		saveUser(sqlSession);
		
		// 查询消息
//		selectUsers(sqlSession);				
	}
	
	public static void saveUser(SqlSession sqlSession)
	{
		User user = new User(null, new Name("己","妲"), "888888");
		
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
		
		userMapper.saveUser(user);
		
		// 4. 提交事务
		sqlSession.commit();
		// 5. 关闭资源
		sqlSession.close();	
	}

	public static void selectUsers(SqlSession sqlSession)
	{
		// 此处的NewsMapper只是一个接口
		// MyBatis会使用JDK的动态代理为Mapper接口生成实现类
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
		List<?> list = userMapper.findUsers(-1);
		list.forEach(e -> {
			Name name = ((User) e).getName();
			System.out.println(name.getFirst());
			System.out.println(name.getLast());
		});
		
		System.out.println(list);
		
		// 4. 提交事务
		sqlSession.commit();
		// 5. 关闭资源
		sqlSession.close();	
	}	
		
}

执行插入语句

DEBUG [main] org.itcheng.app.dao.UserMapper.saveUser ==>  Preparing: insert into user_inf values (null, ?, ?) 
DEBUG [main] org.itcheng.app.dao.UserMapper.saveUser ==> Parameters: 己-妲(String), 888888(String)
DEBUG [main] org.itcheng.app.dao.UserMapper.saveUser <==    Updates: 1

执行查询语句

DEBUG [main] org.itcheng.app.dao.UserMapper.findUsers ==>  Preparing: select user_id id, user_name name, password from user_inf where user_id > ? 
DEBUG [main] org.itcheng.app.dao.UserMapper.findUsers ==> Parameters: -1(Integer)
DEBUG [main] org.itcheng.app.dao.UserMapper.findUsers <==      Total: 1
己
妲
[User [id=1, name=Name [first=己, last=妲], password=888888]]
文章来源:https://blog.csdn.net/weixin_39289095/article/details/134486626
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。