xml属性注解笔记
xml属性注解笔记
Select
1. id
作用 :这条 SQL 的“身份证号”,在同一个房间里(命名空间内)必须唯一。
例子 :就像你去银行办业务,每个窗口都有一个编号(比如“3号窗口”),你告诉工作人员“我要去3号窗口”,他们就知道该找谁。
2. parameterType
作用
:告诉 MyBatis 这条 SQL 要用的参数是什么类型(比如一个
User
对象)。
例子 :你点奶茶时说“我要一杯大杯的”,店员就知道用大杯装。但如果你不说,店员也能从你的手势猜出来(MyBatis 会自己猜类型)。
3. parameterMap(已废弃)
作用 :以前用来描述参数怎么和 SQL 对应,但现在大家都直接用“#{属性名}”写在 SQL 里,更方便。
例子 :就像以前写信要贴邮票,现在直接用微信扫码支付,没人再用邮票了。
4. resultType
作用
:告诉 MyBatis 这条 SQL 返回的数据要转成什么类型(比如
User
对象)。
细节
:如果返回的是一个列表(比如
List<User>
),这里填的是
User
,不是
List
。
例子 :你网购一箱苹果,快递单上写的是“苹果”(单个类型),而不是“一箱苹果”。
5. resultMap
作用 :如果结果很复杂(比如数据要拆成多个对象),用这个指向一个提前写好的“映射说明书”。
例子 :就像组装乐高时,说明书会告诉你哪块积木放哪里,而不是让你自己瞎猜。
6. flushCache
作用
:设为
true
时,执行这条 SQL 后会清空缓存(下次查询重新查数据库)。
默认
:
false
(不清空)。
场景 :适合增删改操作,比如你删了商品,下次查询不想看到缓存里的旧数据。
7. useCache
作用
:设为
true
时,这条 SQL 的结果会被缓存(下次同样查询直接拿缓存)。
默认
:对查询语句(select)是
true
,其他语句(如 insert)无效。
场景 :比如你查天气,一天内同样的查询直接用缓存,不用每次都问气象局。
8. timeout
作用 :设置数据库执行的超时时间(比如 10 秒没结果就报错)。
默认 :数据库自己决定。
例子 :就像你打电话客服,等了 5 分钟还没人接,你直接挂断。
9. fetchSize
作用 :建议数据库一次批量返回多少条数据(比如一次拿 100 条)。
例子 :快递小哥送快递,一次搬一箱(100 件)比一件件拿更快。
10. statementType
作用 :选择执行 SQL 的工具,默认用预编译(防 SQL 注入)。
选项 :
STATEMENT
:直接执行(像手写纸条)。PREPARED
(默认):预编译(像用模板盖章)。CALLABLE
:调用存储过程(像打电话让后台处理)。
11. resultSetType
作用 :控制结果集的遍历方式(比如只能向前翻,或自由滚动)。
默认 :数据库驱动决定。
例子 :看书时,有的书只能一页页翻,有的可以随便翻到任意页。
12. databaseId
作用 :根据数据库类型(比如 MySQL 或 Oracle)选择执行不同的 SQL。
例子 :同样一道菜,四川人吃辣,广东人吃清淡,厨子会根据顾客口味调整。
13. resultOrdered
作用
:处理大量嵌套数据时,避免内存爆炸。设为
true
会优化内存。
默认
:
false
。
场景 :像整理行李箱,如果衣服一件套一件,不整理的话会塞不下。
14. resultSets
作用 :用于存储过程返回多个结果集时,给每个结果集起名字。
例子 :像吃套餐,服务员端上来“主菜、配菜、汤”,你可以分别指定名字。
insert, update 和 delete
1. id
作用 :这条 SQL 的“唯一名字”,在同一个 XML 文件里不能重复。
例子 :就像微信好友列表里每个人的昵称必须唯一,否则你@人的时候会分不清谁是谁。
2. parameterType
作用
:告诉 MyBatis 参数是什么类型(比如
User
类)。
细节 :可省略,MyBatis 能自己猜类型。
例子 :你点外卖时说“要一杯奶茶”,即使不说“大杯”,店员默认也会给你大杯(如果系统有默认值)。
3. parameterMap(已废弃)
作用
:以前用来描述参数和 SQL 的映射关系,现在直接用
#{属性名}
更简单。
现状 :别用它,像过时的翻盖手机,现在都用智能手机(行内参数映射)。
4. flushCache
作用
:设为
true
时,执行这条 SQL 后会清空缓存(默认 insert/update/delete 会清空)。
默认值
:对增删改操作是
true
(比如你删了数据,下次查肯定要重新读数据库)。
场景 :你修改了密码,肯定不希望别人用旧密码的缓存登录。
5. timeout
作用 :设置 SQL 执行的超时时间(比如 10 秒没结果就报错)。
默认 :数据库驱动自己决定。
例子 :等电梯超过 2 分钟还没来,你可能直接走楼梯(超时报错)。
6. statementType
作用 :选择执行 SQL 的工具类型。
选项 :
STATEMENT
:直接执行(像手写纸条传给数据库,容易被 SQL 注入攻击)。PREPARED
(默认):预编译(像用模板盖章,安全高效)。CALLABLE
:调用存储过程(像打电话让数据库后台处理)。 例子 :发邮件时,用模板(
PREPARED
)比每次手写(STATEMENT
)更省事。
7. useGeneratedKeys
作用 :(仅 insert/update 用)告诉 MyBatis 去拿数据库自动生成的主键(比如 MySQL 的自增 ID)。
默认
:
false
(不拿)。
场景
:你存钱到银行,柜台给你一张存单号(自增 ID),
useGeneratedKeys
就是让你能拿到这个号码。
8. keyProperty
作用
:(配合
useGeneratedKeys
)把生成的主键值塞到参数的哪个属性里。
例子
:你存钱后拿到存单号,银行系统会自动把这个号码填到你的账户记录里(比如
user.id
)。
9. keyColumn
作用 :数据库表中生成主键的列名(如果主键列不是第一列,某些数据库需要指定)。
场景 :比如 PostgreSQL 的主键列可能在第二列,这时候必须告诉 MyBatis 列名。
例子 :快递单号可能在快递单的第二行,你得明确告诉快递员“看第二行的编号”。
10. databaseId
作用 :根据数据库类型(MySQL、Oracle 等)选择执行不同的 SQL。
例子 :就像同一款 App,iOS 和 Android 的安装包不同,MyBatis 会根据当前数据库加载对应的 SQL。
总结
写操作(insert/update/delete)重点关注 :
flushCache
(默认清缓存)useGeneratedKeys
+keyProperty
(拿自增 ID)keyColumn
(适配非常规主键列)
防踩坑提示 :
- 别用
parameterMap
(已废弃)。 - 如果主键不是自增的,不要开
useGeneratedKeys
。 - 超时时间(
timeout
)设太短可能导致正常请求报错。
- 别用
selectKey 元素的属性
1. keyProperty
作用 :告诉 MyBatis:“把生成的主键值,存到我对象的哪个属性里”。
场景 :
单主键:比如插入用户后,数据库自动生成的
id
,要存到对象的user.id
属性。多主键:如果主键是复合的(比如订单号+地区码),用逗号分隔多个属性名,比如
keyProperty="orderId, areaCode"
。 例子 :你去银行开户,柜台生成一个账号,系统会自动把这个账号填到你的存折上(
keyProperty
就是告诉系统“存到存折的账号栏里”)。
2. keyColumn
作用 :告诉 MyBatis:“数据库里生成主键的列名是什么”。
场景 :
当主键列名和对象属性名不一致时(比如数据库列叫
user_id
,对象属性叫id
)。如果数据库返回多个生成列(比如同时生成订单号和流水号),用逗号分隔,比如
keyColumn="order_no, serial_no"
。 例子 :快递单上有一栏叫“运单号”(数据库列),但你的订单对象里叫
trackingNumber
(对象属性),keyColumn
就是告诉系统“去快递单的运单号栏找”。
3. resultType
作用
:声明
selectKey
中 SQL 返回的主键类型。
细节 :
简单类型:比如
Integer
(自增ID)、String
(UUID)。多主键:返回
Map
或Object
(比如同时返回订单号和地区码)。 例子 :你取快递报手机号,快递员查到的取件码可能是数字(
Integer
)或字母+数字组合(String
),resultType
就是告诉系统“取件码的类型是什么”。
4. order
作用 :决定“取主键”和“插入数据”谁先谁后。
选项 :
BEFORE
:先拿主键,再插入数据(适用于数据库需要提前生成主键,比如 Oracle 的序列)。AFTER
:先插入数据,再拿主键(适用于数据库插入后生成主键,比如 MySQL 自增ID)。 例子 :
BEFORE :像电影院选座,先选好座位号(主键),再出票。
AFTER :像餐馆排队,先点菜(插入数据),等叫号(主键)后再入座。
5. statementType
作用 :和之前一样,决定执行 SQL 的工具类型(普通语句、预编译、存储过程)。
细节 :
selectKey
里默认用PREPARED
(预编译防注入)。除非特殊需求(比如调用存储过程生成主键),否则不用改。
例子 :写重要文件时,用模板(
PREPARED
)比手写(STATEMENT
)更安全可靠。
MyBatis 映射相关的属性
1. column
作用 :数据库表的列名或别名,告诉 MyBatis 从哪一列取数据。
场景 :
当数据库列名和对象属性名不一致时(比如数据库列叫
user_name
,对象属性叫name
)。 例子 :快递单上的“收件人电话”列(column),对应你填写的“手机号”(对象属性)。
2. javaType
作用
:指定 Java 对象的类型(比如
String
、
Integer
或自定义类)。
细节 :
MyBatis 通常能自动推断类型(比如从
User
对象的name
属性推断为String
)。但如果你用
HashMap
接收数据,必须明确指定javaType
,否则可能类型混乱。 例子 :你网购时,快递员默认知道包裹是“电子产品”(自动推断类型),但如果是特殊物品(比如液体),你得明确告知(手动指定类型)。
3. jdbcType
作用
:指定数据库字段的 JDBC 类型(比如
VARCHAR
、
INTEGER
)。
场景 :
必须指定 当字段允许为空(
NULL
)且参数为null
时,避免 JDBC 类型推导错误。 例子 :你寄快递时,如果“保价金额”是可选的,填单子时必须注明“保价类型”(比如数字或货币),否则快递公司可能不知道如何处理空值。
4. typeHandler
作用 :自定义类型转换器,处理数据库类型和 Java 类型之间的转换。
场景 :
默认转换不满足需求时(比如将数据库的
0/1
转成boolean
)。 例子 :数据库用字符串
"Y"/"N"
表示是否会员,而 Java 用boolean
,这时可以写一个转换器自动处理。
5. select
作用
:通过另一个查询(
select
语句)加载复杂属性(比如关联对象)。
场景 :
用于“延迟加载”关联数据(比如查用户时,关联查询他的订单列表)。
风险 :可能引发“N+1 查询问题”(查 1 个用户,触发 N 次订单查询)。
例子 :查学生信息时,用到班级信息,可以单独写一个
select
查询班级表。
6. resultMap
作用 :引用一个复杂的结果映射,处理多表联查或嵌套对象。
场景 :
替代多次
select
查询,一次性通过联查 SQL 加载所有数据。 例子 :查询订单时,联查用户和商品表,把结果一次性映射到
Order
对象的user
和product
属性中。
7. name
作用 :指定构造方法参数的名称(3.4.3+ 版本支持),解决构造函数参数顺序问题。
场景 :
当类有多个构造方法参数,且顺序不固定时,按名字匹配而非顺序。
例子 :你组装家具时,说明书说“先装螺丝A,再装螺丝B”,但如果你有标签(
name
),可以直接按标签名称装,不用管顺序。
避坑指南
column 别名 :
SQL 中如果用了别名(比如
SELECT user_name AS name
),这里column
要写别名name
。 jdbcType 必填场景 :
当参数可能为
null
时,比如:#{age, jdbcType=INTEGER} <!-- 如果 age 可能为 null -->
慎用 select :
虽然方便,但多级
select
会导致性能问题(N+1 查询),优先用resultMap
联查解决。 typeHandler 配置 :
自定义处理器需要注册到 MyBatis,比如:
`
`
总结
-
简单映射
:用
column
+property
(属性名)即可。 -
复杂类型
:用
javaType
+typeHandler
或resultMap
。 -
关联查询
:
- 简单情况用
select
(但要注意性能)。 - 复杂情况用
resultMap
联查。
- 简单情况用
-
构造方法
:用
name
解决参数顺序问题。