Java MyBatis传出参数resultType和resultMap解读
作者:MinggeQingchun
MyBatis输出参数 resultType 和 resultMap
我们需要在 mybatis-config.xml 文件中加如下配置
<!--定义别名--> <typeAliases> <!-- 第一种方式: 指定一个类型一个自定义别名 type:自定义类型的全限定名称 alias:别名 --> <typeAlias type="com.mycompany.domain.User" alias="user" /> <typeAlias type="com.mycompany.vo.ViewUser" alias="vUser" /> <!-- 第二种方式 <package> name是包名, 这个包中的所有类,类名就是别名(类名不区分大小写) --> <package name="com.mycompany.domain" /> <package name="com.mycompany.vo" /> </typeAliases>
文件完全内容如下
<?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"> <!-- mybatis的主配置文件:主要定义了数据库的配置信息,SQL映射文件的位置 1、约束文件 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> mybatis-3-config.dtd:约束文件名称 2、configuration:根标签 --> <configuration> <!-- settings:mybatis全局行为 --> <settings> <!-- 设置mybatis输出日志 --> <setting name="logImpl" value="STDOUT_LOGGING" /> </settings> <!--定义别名--> <typeAliases> <!-- 第一种方式: 指定一个类型一个自定义别名 type:自定义类型的全限定名称 alias:别名 --> <typeAlias type="com.mycompany.domain.User" alias="user" /> <typeAlias type="com.mycompany.vo.ViewUser" alias="vUser" /> <!-- 第二种方式 <package> name是包名, 这个包中的所有类,类名就是别名(类名不区分大小写) --> <package name="com.mycompany.domain" /> <package name="com.mycompany.vo" /> </typeAliases> <!-- 环境配置:数据库的连接信息 default:必须和某个environment的id值一样 告诉mybatis使用哪个数据库的连接信息(访问哪个数据库) --> <environments default="development"> <!-- environment:一个数据库的配置,环境 id:一个唯一值(可自定义,表示环境的名称) --> <environment id="development"> <!-- transactionManaer:mybatis的事务类型 type:JDBC(表示使用JDBC中的Connection对象的commit,rollback做事务处理) --> <transactionManager type="JDBC"/> <!-- dataSource:表示数据源,连接数据库的 type:表述数据源的类型,POOLED表示使用连接池 --> <dataSource type="POOLED"> <!-- driver, user, username, password 是固定的,不能自定义。 --> <!-- 数据库驱动类名 --> <property name="driver" value="com.mysql.jdbc.Driver"/> <!-- 连接数据库的URL字符串 --> <property name="url" value="jdbc:mysql://localhost:3306/ssm"/> <!-- 访问数据库的用户名 --> <property name="username" value="root"/> <!-- 访问数据库的密码 --> <property name="password" value="123456"/> </dataSource> </environment> <!--表示线上的数据库,是项目真实使用的库--> <environment id="online"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/onlinedb"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <!-- sql mapper(SQL映射文件)的位置 --> <mappers> <!-- 一个mapper标签指定一个文件的位置 从类路径开始的路径信息(target/classes)类路径 --> <mapper resource="com/mycompany/dao/UserDao.xml"/> </mappers> </configuration>
一、resultType
执行 sql 得到 ResultSet 转换的类型,使用类型的完全限定名或别名
1、简单类型
UserDao接口文件
public User selectUserByUserId(@Param("userId") Integer id); List<User> selectMultiParam(@Param("username") String userName, @Param("userage") Integer age);
UserDao.xml文件
<!-- resultType: 表示结果类型,SQL语句执行后得到ResultSet结果集,遍历这个结果集得到的Java对象类型 值写Java对象的全限定名称 1、resultType="vUser" mybatis-config.xml文件中第一种方式 指定一个类型一个自定义别名 type:自定义类型的全限定名称 alias:别名 2、resultType="ViewUser" mybatis-config.xml文件中第二种方式: <package> name是包名, 这个包中的所有类,类名就是别名(类名不区分大小写) 注: resultType="User" 如果一个项目中有多个User类文件,会报错 Could not resolve type alias 'User'. Cause: java.lang.ClassNotFoundException: Cannot find class: User --> <select id="selectUserByUserId" resultType="User"> select user_id,user_name,email,age from user where user_id = #{userId} </select> <!--多个参数,使用@Param命名--> <select id="selectMultiParam" resultType="com.mycompany.domain.User" > select user_id,user_name,email,age from user where user_name = #{username} or age = #{userage} </select>
TestMyBatis测试类
@Test public void testSelectUserByUserId(){ try { SqlSession sqlSession = MyBatisUtil.getSqlSession(); UserDao userDao = sqlSession.getMapper(UserDao.class); User user = userDao.selectUserByUserId(1); System.out.println("user="+user); sqlSession.close(); } catch (IOException e) { e.printStackTrace(); } } @Test public void testSelectMultiParam(){ try { SqlSession sqlSession = MyBatisUtil.getSqlSession(); UserDao userDao = sqlSession.getMapper(UserDao.class); List<User> userList = userDao.selectMultiParam("zhangsan",20); for(User user: userList){ System.out.println("用户="+user); } sqlSession.close(); } catch (IOException e) { e.printStackTrace(); } }
2、Map类型
UserDao接口文件
//定义方法返回Map Map<Object,Object> selectMapById(Integer id); UserDao.xml文件 <select id="selectMapById" resultType="java.util.HashMap"> select user_id,user_name,email,age from user where user_id=#{userId} </select>
TestMyBatis测试类
@Test public void testSelectMapById(){ try { SqlSession sqlSession = MyBatisUtil.getSqlSession(); UserDao userDao = sqlSession.getMapper(UserDao.class); Map<Object,Object> map = userDao.selectMapById(1); System.out.println("map=="+map); sqlSession.close(); } catch (IOException e) { e.printStackTrace(); } }
3、对象类型
UserDao接口文件
ViewUser selectUserReturnViewUser(@Param("userId") Integer id);
UserDao.xml文件
<!-- 1、resultType="vUser" mybatis-config.xml文件中第一种方式 指定一个类型一个自定义别名 type:自定义类型的全限定名称 alias:别名 2、resultType="ViewUser" mybatis-config.xml文件中第二种方式: <package> name是包名, 这个包中的所有类,类名就是别名(类名不区分大小写) --> <select id="selectUserReturnViewUser" resultType="ViewUser"> select user_id,user_name from user where user_id = #{userId} </select>
TestMyBatis测试类
@Test public void testSelectUserReturnViewUser(){ try { SqlSession sqlSession = MyBatisUtil.getSqlSession(); UserDao userDao = sqlSession.getMapper(UserDao.class); ViewUser user = userDao.selectUserReturnViewUser(1); System.out.println("ViewUser="+user); sqlSession.close(); } catch (IOException e) { e.printStackTrace(); } }
注:
(1)如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身
(2)resultType 和 resultMap,不能同时使用
(3)resultType="User" 如果一个项目中有多个User类文件,会报错
Could not resolve type alias 'User'. Cause: java.lang.
ClassNotFoundException: Cannot find class: User
此时最好指定全限定名称
二、resultMap
resultMap 可以自定义 sql 的结果和 java 对象属性的映射关系;更灵活的把列值赋值给指定属性
常用在列名和 java 对象属性名不一样的情况
使用方式:
(1)先定义 resultMap,指定列名和属性的对应关系
(2)在<select>中把 resultType 替换为 resultMap
列名和Java对象属性名不一样时,有两种处理方式
(1)使用resultMap映射
(2)resultType的默认原则是 同名的列值赋值给同名的属性, 使用列别名(java对象的属性名)
如下Java类属性
public class User { private int userId; private String userName; private String email; private int age; } public class MyUser { private int myUserId; private String myUserName; private String myUserEmail; private int myUserAge; }
UserDao接口文件
/* 使用resultMap定义映射关系 */ List<User> selectAllUsers(); List<MyUser> selectMyUser(); List<MyUser> selectDiffColProperty();
UserDao.xml文件
<!--使用resultMap (1)先定义resultMap (2)在select标签,使用resultMap来引用定义 id:自定义名称,表示定义的这个resultMap type:java类型的全限定名称 --> <resultMap id="userMap" type="com.mycompany.domain.User"> <!--列名和java属性的关系 注解列,使用id标签 column :列名(数据库表字段列名) property:java类型的属性名 --> <!-- 主键列使用 id 标签--> <id column="user_id" property="userId" /> <!-- 非主键列使用 result 标签--> <result column="user_name" property="userName" /> <result column="email" property="email" /> <result column="age" property="age" /> </resultMap> <select id="selectAllUsers" resultMap="userMap"> select user_id,user_name,email,age from user where user_id=#{userId} </select> <resultMap id="myUserMap" type="com.mycompany.domain.MyUser"> <id column="user_id" property="myUserId" /> <result column="user_name" property="myUserName" /> <result column="email" property="myUserEmail" /> <result column="age" property="myUserAge" /> </resultMap> <!--列名和属性名不一样:第一种方式 使用resultMap映射 --> <select id="selectMyUser" resultMap="myUserMap"> select user_id,user_name,email,age from user </select> <!--列名和属性名不一样:第二种方式 resultType的默认原则是 同名的列值赋值给同名的属性, 使用列别名(java对象的属性名) --> <select id="selectDiffColProperty" resultType="com.mycompany.domain.MyUser"> select user_id as myUserId ,user_name as myUserName, email as myUserEmail , age myUserAge from user </select>
TestMyBatis测试类
@Test public void testSelectAllUsers(){ try { SqlSession sqlSession = MyBatisUtil.getSqlSession(); UserDao userDao = sqlSession.getMapper(UserDao.class); List<User> userList = userDao.selectAllUsers(); for(User user: userList){ System.out.println("用户="+user); } sqlSession.close(); } catch (IOException e) { e.printStackTrace(); } } @Test public void testSelectMyUser(){ try { SqlSession sqlSession = MyBatisUtil.getSqlSession(); UserDao userDao = sqlSession.getMapper(UserDao.class); List<MyUser> userList = userDao.selectMyUser(); for(MyUser user: userList){ System.out.println("MyUser用户="+user); } sqlSession.close(); } catch (IOException e) { e.printStackTrace(); } } @Test public void testSelectDiffColProperty(){ try { SqlSession sqlSession = MyBatisUtil.getSqlSession(); UserDao userDao = sqlSession.getMapper(UserDao.class); List<MyUser> userList = userDao.selectDiffColProperty(); for(MyUser user: userList){ System.out.println("MyUser用户="+user); } sqlSession.close(); } catch (IOException e) { e.printStackTrace(); } }
三、模糊 like
模糊查询的实现有两种方式, 一是 java 代码中给查询数据加上“%” ; 二是在 mapper 文件 sql 语句的条件位置加上“%”
UserDao接口文件
/*第一种模糊查询, 在java代码指定 like的内容*/ List<User> selectLikeOne(String name); /*name就是李值, 在mapper中拼接 like "%" li "%" */ List<User> selectLikeTwo(String name);
UserDao.xml文件
<!--第一种 like ,java代码指定 like的内容--> <select id="selectLikeOne" resultType="com.mycompany.domain.User"> select user_id, user_name, email, age from user where user_name like #{user_name} </select> <!--第二种方式:在mapper文件中拼接 like的内容--> <select id="selectLikeTwo" resultType="com.mycompany.domain.User"> select user_id, user_name, email, age from user where user_name like "%" #{user_name} "%" </select>
TestMyBatis测试类
@Test public void testSelectLikeOne(){ try { SqlSession sqlSession = MyBatisUtil.getSqlSession(); UserDao userDao = sqlSession.getMapper(UserDao.class); //like的内容 String name = "%li%"; List<User> userList = userDao.selectLikeOne(name); for(User user: userList){ System.out.println("User用户="+user); } sqlSession.close(); } catch (IOException e) { e.printStackTrace(); } } @Test public void testSelectLikeTwo(){ try { SqlSession sqlSession = MyBatisUtil.getSqlSession(); UserDao userDao = sqlSession.getMapper(UserDao.class); //like的内容 String name = "li"; List<User> userList = userDao.selectLikeTwo(name); for(User user: userList){ System.out.println("User用户="+user); } sqlSession.close(); } catch (IOException e) { e.printStackTrace(); } }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。