Springboot中使用Mybatis框架對資料庫進行聯表查詢,踩坑填坑
因為mybatis使用的基本是原生sql語句 所以首先從資料庫開始說 以mysql資料庫為例,對錶的連線查詢分為四種 內連線,外連線,交叉連線,和聯合連線
內連線使用比較運算子根據每個表共有的列的值匹配兩個表中的行 sql語句舉例:聯接查詢user,order表中user的id相同的資料,前五列為user表的內容,後面的是order表。
SELECT * FROM `user` INNER JOIN `order` ON user.id=order.userID;
內連線也被稱為普通連線或者自然連線,內連線是從結果表中刪除與其他被連線表中沒有匹配行的所有行,所以內連線可能會丟失資訊
外連線
左外連線:以左表為基表(驅動表),將左表的每一條資料都與右表匹配,如果在右表中沒有匹配資料,則右表補null 舉例說明一下 我們把使用者表當做左表,訂單表為右表
SELECT * FROM `user` LEFT JOIN `order` ON user.id=order.userID;
看一下查詢結果,發現id為2的沒有訂單表的資訊,全部用null填充了。 左外連線就是對左邊的表不加限制,左邊表的資訊不會丟失
右外連線和左外連線相反,保留右表的所有資訊。
SELECT * FROM `user` RIGHT JOIN `order` ON user.id=order.userID;
全外連線就是左右資訊都保留,匹配不到的用null填充。
第三種是交叉連線 它返回結果集合中的資料行數等於第一個表中符合查詢條件的資料行數乘以第二個表中符合查詢條件的資料行數,也叫笛卡爾積,不帶where字句。
SELECT * FROM `user` CROSS JOIN `order`;
第四種是聯合聯接 這是一種很少見的連線方式。Oracle、MySQL均不支援,其作用是:找出全外連線和內連線之間差異的所有行。這在資料分析中排錯中比較常用。也可以利用資料庫的集合操作來實現此功能,這裡不做展示了。
接下來說一下連表容易踩到的坑 首先是外來鍵衝突 如果A表關聯了B表,比如說我使用者關聯了訂單表 那麼在插入訂單時,應該先去判斷是否有這個使用者 刪除使用者時,應該先去把他關聯的訂單刪除, 否則就會有外來鍵衝突。
再就是表的名字,在mysql中,如果使用了關鍵字作為表的名字會報語句錯誤,應該給表名加上``這個符號,這是橫排數字按鍵數字1旁邊的那個鍵在英文輸入下輸出的。
下面放一下在mybatis下連表查詢的程式碼步驟。
第一步正常建表就不說了,如果忘記設定外來鍵,說一下增加外來鍵的語句
ALTER TABLE `order` ADD CONSTRAINT fk_user_id FOREIGN KEY (user_id) REFERENCES `user`(id)
然後是建相應的實體類,和Mapper.xml User.java
package com.jerry.springbootdemo.entity;
import lombok.Data;
import java.util.List;
@Data
public class User {
private Integer id;
private String username;
private String passsword;
private String gender;
private String hobby;
private List<Order> orderList;
}
Order.java
package com.jerry.springbootdemo.entity;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
@Data
public class Order {
private Integer orderid;
private String orderno;
private Integer userid;
private Byte orderstatus;
private BigDecimal goodsmoney;
private Byte ispay;
private Byte payfrom;
private String username;
private String gamename;
private Date createtime;
private String areaidpath;
private String userphone;
private String orderremarks;
private BigDecimal realtotalmoney;
private Integer orderscore;
private Byte isappraise;
private Byte isclosed;
}
主要看一下UserMapper.xml,因為是一對多的關係,所以下面這個查詢語句是主要學習的,這個查詢就是查詢使用者的資訊和他名下的訂單詳情,包括結果型別,和引數型別,資料型別的設定都要注意。
<select id="getUserDetails" parameterType="Integer" resultMap="UserResultMap">
select * from `user` u ,`order` o where u.id=o.userID and u.id=#{id}
</select>
<resultMap type="com.jerry.springbootdemo.entity.User" id="UserResultMap">
<id column="id" property="id" jdbcType="INTEGER" />
<result column="username" property="username" jdbcType="VARCHAR" />
<result column="passsword" property="passsword" jdbcType="VARCHAR" />
<result column="gender" property="gender" jdbcType="CHAR" />
<result column="hobby" property="hobby" jdbcType="VARCHAR" />
<!-- ofType指定order集合中的物件型別 -->
<collection property="orderList" ofType="com.jerry.springbootdemo.entity.Order">
<id column="orderID" property="orderid" jdbcType="INTEGER" />
<result column="orderNo" property="orderno" jdbcType="VARCHAR" />
<result column="userID" property="userid" jdbcType="INTEGER" />
<result column="orderStatus" property="orderstatus" jdbcType="TINYINT" />
<result column="goodsMoney" property="goodsmoney" jdbcType="DECIMAL" />
<result column="isPay" property="ispay" jdbcType="TINYINT" />
<result column="payFrom" property="payfrom" jdbcType="TINYINT" />
<result column="userName" property="username" jdbcType="VARCHAR" />
<result column="gameName" property="gamename" jdbcType="VARCHAR" />
<result column="createTime" property="createtime" jdbcType="TIMESTAMP" />
<result column="areaIdPath" property="areaidpath" jdbcType="VARCHAR" />
<result column="UserPhone" property="userphone" jdbcType="CHAR" />
<result column="orderRemarks" property="orderremarks" jdbcType="VARCHAR" />
<result column="realTotalMoney" property="realtotalmoney" jdbcType="DECIMAL" />
<result column="orderScore" property="orderscore" jdbcType="INTEGER" />
<result column="isAppraise" property="isappraise" jdbcType="TINYINT" />
<result column="isClosed" property="isclosed" jdbcType="TINYINT" />
</collection>
</resultMap>
UserController.java
一個是返回json,一個是返回view。
@GetMapping(value="/userdetails")
public ModelAndView userDetalis(){
ModelAndView mv=new ModelAndView();
mv.addObject("details",userMapper.getUserDetails(1));
mv.setViewName("UserDetails");
return mv;
}
@GetMapping(value = "/userjson/{id}")
public @ResponseBody User userJson(@PathVariable() Integer id){
User user1=userMapper.getUserDetails(id);
return user1;
}
swagger測試成功