目录

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

  • 多主键:返回 MapObject (比如同时返回订单号和地区码)。

    例子 ‌:你取快递报手机号,快递员查到的取件码可能是数字( 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 对象的类型(比如 StringInteger 或自定义类)。

细节 ‌:

  • MyBatis 通常能自动推断类型(比如从 User 对象的 name 属性推断为 String )。

  • 但如果你用 HashMap 接收数据,必须明确指定 javaType ,否则可能类型混乱。

    例子 ‌:你网购时,快递员默认知道包裹是“电子产品”(自动推断类型),但如果是特殊物品(比如液体),你得明确告知(手动指定类型)。


3. jdbcType

作用 ‌:指定数据库字段的 JDBC 类型(比如 VARCHARINTEGER )。

场景 ‌:

  • 必须指定 ‌当字段允许为空( 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 对象的 userproduct 属性中。


7. name

作用 ‌:指定构造方法参数的名称(3.4.3+ 版本支持),解决构造函数参数顺序问题。

场景 ‌:

  • 当类有多个构造方法参数,且顺序不固定时,按名字匹配而非顺序。

    例子 ‌:你组装家具时,说明书说“先装螺丝A,再装螺丝B”,但如果你有标签( name ),可以直接按标签名称装,不用管顺序。


避坑指南

  1. column 别名 ‌:

    SQL 中如果用了别名(比如 SELECT user_name AS name ),这里 column 要写别名 name

  2. jdbcType 必填场景 ‌:

    当参数可能为 null 时,比如:

    #{age, jdbcType=INTEGER}  <!-- 如果 age 可能为 null -->
  3. 慎用 select ‌:

    虽然方便,但多级 select 会导致性能问题(N+1 查询),优先用 resultMap 联查解决。

  4. typeHandler 配置 ‌:

    自定义处理器需要注册到 MyBatis,比如:

    `

    `


总结

  • 简单映射 ‌:用 column + property (属性名)即可。
  • 复杂类型 ‌:用 javaType + typeHandlerresultMap
  • 关联查询 ‌:
    • 简单情况用 select (但要注意性能)。
    • 复杂情况用 resultMap 联查。
  • 构造方法 ‌:用 name 解决参数顺序问题。