提交学习笔记专用
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

379 lines
10 KiB

2 weeks ago
  1. # Mybatis初步复习
  2. ## 1.SpringBoot整合Mybatis
  3. ## 1.1第一步添加依赖
  4. ```
  5. <!-- mybatis启动器-->
  6. <dependency>
  7. <groupId>org.mybatis.spring.boot</groupId>
  8. <artifactId>mybatis-spring-boot-starter</artifactId>
  9. <version>3.0.5</version>
  10. </dependency>
  11. ```
  12. ### 1.2进行配置
  13. ```
  14. #配置Mybatis
  15. mybatis:
  16. configuration:
  17. #在映射为java对象,将表中的下划线命名自动转换成驼峰式命名
  18. map-underscore-to-camel-case: true
  19. #日志前缀 可选
  20. log-prefix: mybatis.
  21. #日志实现类 可选
  22. log-impl: org.apache.ibatis.logging.commons.JakartaCommonsLoggingImpl
  23. #动态sql文件存储位置
  24. mapper-locations: classpath:/mapper/**/*.xml
  25. #配置日志显示sql
  26. logging:
  27. level:
  28. #指定日志前缀
  29. mybatis: debug
  30. ```
  31. ### 1.3 在Dao层编写的mapper接口,添加@Mapper注解
  32. ![1762578862653](C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1762578862653.png)
  33. ### 1.4 编写动态sql文件(xx.xml文件)
  34. ![1762578878514](C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1762578878514.png)
  35. ### 1.5 安装mybatisx插件
  36. ![1762578934144](C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1762578934144.png)
  37. 安装之后在mapper和动态SQL文件对应代码左边有一个小鸟图标,方便直接跳转
  38. ![1762578917583](C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1762578917583.png)
  39. ## 2.自动映射
  40. 当开启驼峰命名自动映射
  41. ```yaml
  42. mybatis:
  43. configuration:
  44. map-underscore-to-camel-case: true
  45. ```
  46. ## 3.手动映射
  47. 当自动映射无法满足需求时,可以使用 `<resultMap>` 进行精确的手动映射。
  48. ```xml
  49. <resultMap id="唯一标识" type="要映射的Java类型">
  50. <!-- 主键映射 -->
  51. <id property="Java属性名" column="数据库列名"/>
  52. <!-- 普通字段映射 -->
  53. <result property="Java属性名" column="数据库列名"/>
  54. <!-- 关联关系映射 -->
  55. <association property="关联对象属性" javaType="关联对象类型"/>
  56. <collection property="集合属性" ofType="集合元素类型"/>
  57. </resultMap>
  58. ```
  59. 举例:
  60. ### 3.1基础字段映射
  61. ```java
  62. 实体类
  63. public class User {
  64. private Long userId; // 与数据库字段名不同
  65. private String userName; // 需要手动映射
  66. private String email;
  67. private Integer status;
  68. private LocalDateTime createTime;
  69. private LocalDateTime updateTime;
  70. // 构造函数、getter、setter...
  71. }
  72. ```
  73. ```sql
  74. 数据库表结构:
  75. CREATE TABLE t_user (
  76. id BIGINT PRIMARY KEY,
  77. name VARCHAR(50),
  78. email VARCHAR(100),
  79. status TINYINT,
  80. created_at DATETIME,
  81. updated_at DATETIME
  82. );
  83. ```
  84. ```xml
  85. <!-- 基础手动映射示例 -->
  86. <resultMap id="BaseUserMap" type="User">
  87. <!-- 主键字段,使用 id 标签 -->
  88. <id property="userId" column="id"/>
  89. <!-- 普通字段,使用 result 标签 -->
  90. <result property="userName" column="name"/>
  91. <result property="email" column="email"/>
  92. <result property="status" column="status"/>
  93. <result property="createTime" column="created_at"/>
  94. <result property="updateTime" column="updated_at"/>
  95. </resultMap>
  96. <!-- 使用 resultMap -->
  97. <select id="selectUserById" resultMap="BaseUserMap">
  98. SELECT id, name, email, status, created_at, updated_at
  99. FROM t_user
  100. WHERE id = #{id}
  101. </select>
  102. ```
  103. 说明:
  104. ![1762581420222](C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1762581420222.png)
  105. ### 3.2一对一关联映射
  106. #### 3.2.1单次查询嵌套结果映射
  107. 举例:
  108. ```java
  109. 实体类
  110. public class User {
  111. private Long userId;
  112. private String userName;
  113. private UserProfile userProfile; // 一对一关联
  114. // getter/setter...
  115. }
  116. public class UserProfile {
  117. private Long profileId;
  118. private Long userId;
  119. private String realName;
  120. private Integer age;
  121. private String address;
  122. private String phone;
  123. // getter/setter...
  124. }
  125. ```
  126. ```xml
  127. 手动映射配置:
  128. <!-- 用户和用户详情的一对一映射 -->
  129. <resultMap id="UserWithProfileMap" type="User">
  130. <id property="userId" column="id"/>
  131. <result property="userName" column="name"/>
  132. <!-- association: 一对一关联映射 -->
  133. <association property="userProfile" javaType="UserProfile">
  134. <id property="profileId" column="profile_id"/>
  135. <result property="userId" column="id"/> <!-- 注意:这里复用外层查询的id -->
  136. <result property="realName" column="real_name"/>
  137. <result property="age" column="age"/>
  138. <result property="address" column="address"/>
  139. <result property="phone" column="phone"/>
  140. </association>
  141. </resultMap>
  142. <!-- 关联查询SQL -->
  143. <select id="selectUserWithProfile" resultMap="UserWithProfileMap">
  144. SELECT
  145. u.id, u.name,
  146. up.id as profile_id, up.real_name, up.age, up.address, up.phone
  147. FROM t_user u
  148. LEFT JOIN t_user_profile up ON u.id = up.user_id
  149. WHERE u.id = #{userId}
  150. </select>
  151. ```
  152. #### 3.2.2 多次查询嵌套查询映射
  153. ```xml
  154. <!-- 主结果映射 -->
  155. <resultMap id="UserWithProfileNestedMap" type="User">
  156. <id property="userId" column="id"/>
  157. <result property="userName" column="name"/>
  158. <!-- 嵌套查询:通过 select 属性引用另一个查询 -->
  159. <association property="userProfile" column="id"
  160. select="selectUserProfileByUserId"/>
  161. </resultMap>
  162. <!-- 主查询 -->
  163. <select id="selectUserWithProfileNested" resultMap="UserWithProfileNestedMap">
  164. SELECT id, name
  165. FROM t_user
  166. WHERE id = #{userId}
  167. </select>
  168. <!-- 嵌套查询 -->
  169. <select id="selectUserProfileByUserId" resultType="UserProfile">
  170. SELECT
  171. id as profileId,
  172. user_id as userId,
  173. real_name as realName,
  174. age, address, phone
  175. FROM t_user_profile`
  176. WHERE user_id = #{userId}
  177. </select>
  178. ```
  179. ### 3.3一对多集合映射
  180. ```java
  181. 实体类:
  182. public class User {
  183. private Long userId;
  184. private String userName;
  185. private List<Order> orders; // 一对多关联
  186. // getter/setter...
  187. }
  188. public class Order {
  189. private Long orderId;
  190. private Long userId;
  191. private String orderNumber;
  192. private BigDecimal amount;
  193. private LocalDateTime orderTime;
  194. // getter/setter...
  195. }
  196. ```
  197. ```xml
  198. <!-- 用户和订单的一对多映射 -->
  199. <resultMap id="UserWithOrdersMap" type="User">
  200. <id property="userId" column="id"/>
  201. <result property="userName" column="name"/>
  202. <!-- collection: 一对多关联映射 -->
  203. <collection property="orders" ofType="Order">
  204. <id property="orderId" column="order_id"/>
  205. <result property="userId" column="id"/> <!-- 注意:这里复用外层查询的id -->
  206. <result property="orderNumber" column="order_number"/>
  207. <result property="amount" column="amount"/>
  208. <result property="orderTime" column="order_time"/>
  209. </collection>
  210. </resultMap>
  211. <!-- 关联查询SQL -->
  212. <select id="selectUserWithOrders" resultMap="UserWithOrdersMap">
  213. SELECT
  214. u.id, u.name,
  215. o.id as order_id, o.order_number, o.amount, o.order_time
  216. FROM t_user u
  217. LEFT JOIN t_order o ON u.id = o.user_id
  218. WHERE u.id = #{userId}
  219. </select>
  220. ```
  221. ### 3.4复杂的多层嵌套
  222. ```java
  223. public class User {
  224. private Long userId;
  225. private String userName;
  226. private List<Order> orders;
  227. }
  228. public class Order {
  229. private Long orderId;
  230. private String orderNumber;
  231. private List<OrderItem> orderItems;
  232. }
  233. public class OrderItem {
  234. private Long itemId;
  235. private Long productId;
  236. private Integer quantity;
  237. private Product product; // 关联商品
  238. }
  239. public class Product {
  240. private Long productId;
  241. private String productName;
  242. private BigDecimal price;
  243. }
  244. ```
  245. ```xml
  246. <!-- 完整的多层嵌套映射 -->
  247. <resultMap id="CompleteUserMap" type="User">
  248. <id property="userId" column="user_id"/>
  249. <result property="userName" column="user_name"/>
  250. <!-- 第一层嵌套:订单集合 -->
  251. <collection property="orders" ofType="Order" resultMap="OrderWithItemsMap"/>
  252. </resultMap>
  253. <resultMap id="OrderWithItemsMap" type="Order">
  254. <id property="orderId" column="order_id"/>
  255. <result property="orderNumber" column="order_number"/>
  256. <!-- 第二层嵌套:订单项集合 -->
  257. <collection property="orderItems" ofType="OrderItem" resultMap="OrderItemMap"/>
  258. </resultMap>
  259. <resultMap id="OrderItemMap" type="OrderItem">
  260. <id property="itemId" column="item_id"/>
  261. <result property="quantity" column="quantity"/>
  262. <!-- 第三层嵌套:商品信息 -->
  263. <association property="product" javaType="Product">
  264. <id property="productId" column="product_id"/>
  265. <result property="productName" column="product_name"/>
  266. <result property="price" column="price"/>
  267. </association>
  268. </resultMap>
  269. <!-- 复杂查询SQL -->
  270. <select id="selectUserWithOrderDetails" resultMap="CompleteUserMap">
  271. SELECT
  272. u.id as user_id, u.name as user_name,
  273. o.id as order_id, o.order_number,
  274. oi.id as item_id, oi.quantity,
  275. p.id as product_id, p.name as product_name, p.price
  276. FROM t_user u
  277. LEFT JOIN t_order o ON u.id = o.user_id
  278. LEFT JOIN t_order_item oi ON o.id = oi.order_id
  279. LEFT JOIN t_product p ON oi.product_id = p.id
  280. WHERE u.id = #{userId}
  281. ORDER BY o.order_time DESC, oi.id
  282. </select>
  283. ```
  284. ### 3.5.注意
  285. 1.可以 自动映射与手动映射结合
  286. ```xml
  287. <!-- 混合映射:autoMapping="true" 开启自动映射 -->
  288. <resultMap id="HybridUserMap" type="User" autoMapping="true">
  289. <!-- 只手动映射名称不匹配的字段 -->
  290. <id property="userId" column="id"/>
  291. <result property="userName" column="name"/>
  292. <result property="createTime" column="created_at"/>
  293. <!-- 关联对象也可以使用自动映射 -->
  294. <association property="userProfile" javaType="UserProfile" autoMapping="true">
  295. <id property="profileId" column="profile_id"/>
  296. <!-- 只覆盖需要特殊处理的字段 -->
  297. <result property="realName" column="real_name"/>
  298. </association>
  299. </resultMap>
  300. ```
  301. ##