Mybatis返回单个实体或者返回List的实现

更新时间:2023-05-16 04:38:16 阅读: 评论:0

Mybatis返回单个实体或者返回List的实现
Mybatis 的强⼤之处之⼀体现在映射语句上,让我们可以使⽤简单的配置,就可以实现对参数和返回结果的映射。
实体
st.Ur
public class Ur{
private String urId;
private String urName;
private String urPassword;
private Date createTime;
...
}
DAO
public interface UrMapper{
Ur getUrById(String urId); //返回单个实体
福清瑞云塔List<Ur> getUrByName(String urName); //返回List
Map<String,Object> getUrInfoById(String urId);
List<Map<String,Object>> getUrInfoByName(String urName);
}
数据库
create table ur{
USER_ID varchar(40),
USER_NAME varchar(200),
USER_PASSWORD varchar(100),
CREATE_TIME datetime,
....
}
1.返回某个实体
mybatis映射⽂件
<lect id="getUrById" parameterType="string" resultType="st.Ur">
lect * from ur where id = #{urId}
</lect>
id :identification:语句的标识,在同⼀个mapper映射⽂件下id需要唯⼀
parameterType: 参数类型,可以不写。因为 MyBatis 可以推断出传⼊语句的具体参数
resultType: 全限定类名或者是类型别名.
当使⽤resultType来映射结果时,需要数据库表的列名或列别名和类的属性名相同,这样才能进⾏字段的匹配(USER_ID 和urId 就不能匹配)。但是如果在Mybatis配置⽂件中设置了
<ttings>
<tting name="mapUnderscoreToCamelCa" value="true"/> <!--开启⾃动驼峰命名规则(camel ca)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。--> </ttings>
此时,表列名的下划线标记⽅式可以映射到驼峰标记的形式。(USER_ID -> urId)。mybatis进⾏映射时会将实体类属性和数据库列名(别名)都转化为⼤写来⽐较,所以USER_ID 和 UrId,urID等都可以匹配。
TooManyResultsException
返回单个实体时,调⽤⽅法getUrById,但是如果是因为数据错误导致实际查询结果存在多个时,则会抛出异常。
Ur getUrById(String urId); //返回单个实体
当实际返回值有多个时则抛出异常。
org.ptions.TooManyResultsException: Expected one result (or null) to be returned by lectOne(), but found: 2
租房广告
除⾮可以确定最多只能查询到⼀条结果,否则的话不建议这么写.可以尝试返回集合的⽅式。
2.返回List<entityName>
<lect id="getUrByName" resultType="st.Ur">
唯美爱情句子
lect * from ur where ur_name = #{urName}
初中材料作文</lect>
返回List<T> 集合时,resultType设置为集合元素的类型即T。然后使⽤返回⼏何数据的Mapper⽅法即可。
List<Ur> getUrByName(String urName); //返回List
从上⾯可以看到,返回单个实体与返回集合的resultType指定类型是⼀样的,不⼀样的地⽅在Mapper接⼝或者sqlSession中定义的返回结果类型。实际上mybatis执⾏查询的时候也都是使⽤sqlSession.lectList()来进⾏查询的。
使⽤Mapper 接⼝的⽅式的查询结果时,Mybatis会⽣成该接⼝的代理类(MapperProxy),然后根据Method的getReturnType()⽅法,拿到返回类型,来确定返回的是列表还是单个实体。最后也是调⽤sqlSession的⼀些⽅法。
使⽤SqlSession时,提供了lectOne() 或者lectList()来返回单个实体或者集合。lectOne 实际会调⽤lectList获取结果。
推荐使⽤返回List的⽅式来查询结果
//查询单条结果
List<Ur> urList= UrByName(urName);
if(urList.isEmpty() || urList.size() >1)//期望获得⼀条结果
//业务处理,⼀般是抛出异常或者直接返回错误结果
//return xx;
//throw xxx
Ur ur = (0);
扩展
为什么查询单条和查询多条使⽤的是相同的resultType,⽽返回的结果不同呢。
这是因为Mybatis 在内部进⾏数据查询的时,⽆论查询单条还是多条都是通过lectList实现的,不同的是查询单条Mybatis会获取第⼀条,并且如果结果中存在多条时抛出异常TooManyResultsException。
查询单数据
@Override
public <T> T lectOne(String statement, Object parameter) {
// Popular vote was to return null on 0 results and throw exception on too many.
List<T> list = this.<T>lectList(statement, parameter);
if (list.size() == 1) {
(0);
} el if (list.size() > 1) {房子的房怎么写
throw new TooManyResultsException("Expected one result (or null) to be returned by lectOne(), but found: " + list.size());
} el {
return null;
}
}
查询列表
private <E> Object executeForMany(SqlSession sqlSession, Object[] args) {
List<E> result;
Object param = vertArgsToSqlCommandParam(args);
if (method.hasRowBounds()) {
RowBounds rowBounds = actRowBounds(args);
result = sqlSession.<E>Name(), param, rowBounds);
} el {
result = sqlSession.<E>Name(), param);
}
// issue #510 Collections & arrays support
if (!ReturnType().Class())) {
if (ReturnType().isArray()) {
return convertToArray(result);
} el {
return Configuration(), result);
}
无花果花
}
return result;
}
自古真情留不住
那么Mybatis怎么知道是查询的单条数据还是列表呢?
如果直接使⽤ SqlSession,这个需要⾃⼰控制是调⽤lectOne还是lectList
如果使⽤ Mapper 接⼝,Mybatis会解析Mapper接⼝中的⽅法,会根据⽅法的返回值,判断该⽅法属于那种类型
解析⽅法中的参数、返回值
public MethodSignature(Configuration configuration, Class<?> mapperInterface, Method method) {
Type resolvedReturnType = solveReturnType(method, mapperInterface);
if (resolvedReturnType instanceof Class<?>) {
} el if (resolvedReturnType instanceof ParameterizedType) {
} el {
}
文章结构
this.mapKey = getMapKey(method);
this.paramNameResolver = new ParamNameResolver(configuration, method);
}
method对象就是 Mapper中的⽅法
// lect 查询操作
ca SELECT:
// ⽅法中没有定义返回结果,并且⽅法存在结果处理器
if (urnsVoid() && method.hasResultHandler()) {
executeWithResultHandler(sqlSession, args);
result = null;
} el if (urnsMany()) {
// 返回列表
result = executeForMany(sqlSession, args);
} el if (urnsMap()) {
// 返回Map
result = executeForMap(sqlSession, args);
} el if (urnsCursor()) {
// 返回游标
result = executeForCursor(sqlSession, args);
} el {
// 返回单条数据
Object param = vertArgsToSqlCommandParam(args);
result = sqlSession.Name(), param);
}
break;
3.返回Map
返回map 本质上也是返回⼀个实体。
<lect id="getUrInfoById" resultType="map">
lect * from ur where id=#{urId}
</lect>
如果想要返回单个Map<key,value>集合,只需要设置resultType="map"就可以了,此时返回的实例类型是HashMap。
Map的key就是数据表的列名或者列别名, value 就是查询的数据库中的结果。如果需要返回LinkedHashMap,需要使⽤全限定类
名resultType="java.util.LinkedHashMap"。
注意:返回列对应的结果为null,则不显⽰该 key - value 键值对(只针对该⾏数据对应的Map)
<lect id="getUrInfoById" resultType="map">
lect * from ur where id=#{urId}
</lect>
在Oracle环境下:
最终返回Map:
{"name ":"全部"}
// code 不是显⽰
如果使⽤map接受则不会该map不存在数据. 因为Mybatis默认情况下,不会进⾏赋值,此时该key-value缺失
如果需要改变该⾏为可以在mybatis配置⽂件中设置
<tting name="callSettersOnNulls" value="true"/>
callSettersOnNulls指定当返回结果为null 的时候是否调⽤映射对象的 tter(map 对象时为 put)⽅法,注意基本类型(int、boolean等)是不能设置成 null 的。
配置之后的返回结果:
{"code":null,"name":"全部"}
4.返回List<Map>
<lect id="" parameterType="" resultType="map">
sql_calu
</lect>
resultType设置为map,跟上⾯⼀样resultType设置为List集合中元素的类型。
关于mybatis传递多个参数,可以参考
注意:
偶然发现Mybatis 会⾃动对重名的列做去重。
⽐如我有⼀组数据,使⽤Map接受
SELECT l1.*,l2.*,l3.* FROM ITEM_CAT l1 LEFT JOIN ITEM_CAT l2 ON l1.Id=L2.PARENT_ID LEFT JOIN ITEM_CAT l3
ON l2.Id=L3.PARENT_ID WHERE L1.PARENT_ID='0';
实际返回结果,会发现 name1,name2 都没有映射到Map中
[
{"parent_id":0,"name":"图书","id":1},
{"parent_id":0,"name":"图书","id":1},
{"parent_id":0,"name":"图书","id":1},
{"parent_id":0,"name":"图书","id":1}
......
]
稍微修改⼀下字段名称。
SELECT l1.*,l2.*,l3.*,'test' as name1 FROM ITEM_CAT l1 LEFT JOIN ITEM_CAT l2 ON l1.Id=L2.PARENT_ID LEFT JOIN ITEM_CAT l3
ON l2.Id=L3.PARENT_ID WHERE L1.PARENT_ID='0';
[
{"parent_id":0,"name":"图书","id":1,"name1":"test"},
{"parent_id":0,"name":"图书","id":1,"name1":"test"},
{"parent_id":0,"name":"图书","id":1,"name1":"test"},
{"parent_id":0,"name":"图书","id":1,"name1":"test"}
......
]
可以看到新增的⾃定义列名 “name1”,可以正常显⽰。这是因为使⽤sql 查询出的同名的列名⾃动追加数字做区分,⽽实际保存在元数据信息中的列名还是原来的。就如同Excel 的单元格⼀样,不管单元格内容以什么样式显⽰都不会修改实际值。
⼩结:
返回集合与返回单个实体对象在映射⽂件的写法是⼀致的,不同的地⽅在于Mapper的返回类型不同。
如果不确定返回值是否是唯⼀的,尽量使⽤集合的返回⽅式。然乎使⽤get(0)的⽅式获取实体。
如果返回实体,⼀般情况会使⽤ resultMap来映射返回结果。这样更清晰,直观,⽽且还可以使⽤typeHandler对数据类型做进⼀步处理
返回结果Mapper xml
实体T getT()returnType=“T”
集合List<T> getTList()returnType=“T”
到此这篇关于Mybatis返回单个实体或者返回List的实现的⽂章就介绍到这了,更多相关Mybatis返回实体或者返回List内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!

本文发布于:2023-05-16 04:38:16,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/649675.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:返回   结果   查询   映射   实体   类型   集合
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图