Mybatis實現--多對多數據庫關係

Mybatis實現–多對多數據庫關係

多對多關係在數據庫中十分常見,比如一個購物系統中,一個用戶可以有多個訂單,這個是一對多的關係;一個訂單可以有多個商品,一個商品又可以存在於多個訂單,這就是多對多的關係。對於數據庫中多對多的關係建議使用一個中間表來維護關係,中間表中的訂單id作爲外鍵參照訂單表的id,商品id作爲外鍵參照商品表的id

建表造數據

  • TB_USERS ( 用戶表 )
  • TB_ARTICLE (商品表)
  • TB_ORDER (訂單表)
  • TB_ITEM (中間表)

TB_USERS

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for tb_users
-- ----------------------------
DROP TABLE IF EXISTS `tb_users`;
CREATE TABLE `tb_users` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `USERNAME` varchar(18) DEFAULT NULL,
  `LOGINNAME` varchar(18) DEFAULT NULL,
  `PASSWORD` varchar(18) DEFAULT NULL,
  `PHONE` varchar(18) DEFAULT NULL,
  `ADDRESS` varchar(18) DEFAULT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of tb_users
-- ----------------------------
INSERT INTO `tb_users` VALUES ('1', '傑克', 'jack', '123456', '13765435673', '廣州');
INSERT INTO `tb_users` VALUES ('2', '瑪麗', 'mary', '123456', '13765435673', '北京');

TB_ORDER

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for tb_order
-- ----------------------------
DROP TABLE IF EXISTS `tb_order`;
CREATE TABLE `tb_order` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `CODE` varchar(32) DEFAULT NULL,
  `TOTAL` double DEFAULT NULL,
  `USER_ID` int(11) DEFAULT NULL,
  PRIMARY KEY (`ID`),
  KEY `USER_ID` (`USER_ID`),
  CONSTRAINT `USER_ID` FOREIGN KEY (`USER_ID`) REFERENCES `tb_users` (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of tb_order
-- ----------------------------
INSERT INTO `tb_order` VALUES ('1', '546457657658ygyufyu', '566', '1');
INSERT INTO `tb_order` VALUES ('2', '3534terteyeyew', '467', '1');

TB_ARTICLE

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for tb_article
-- ----------------------------
DROP TABLE IF EXISTS `tb_article`;
CREATE TABLE `tb_article` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `NAME` varchar(18) DEFAULT NULL,
  `PRICE` double(10,2) DEFAULT NULL,
  `REMARK` varchar(18) DEFAULT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of tb_article
-- ----------------------------
INSERT INTO `tb_article` VALUES ('1', '瘋狂java講義', '11.00', '瘋狂java講義');
INSERT INTO `tb_article` VALUES ('2', '瘋狂android講義', '22.00', '瘋狂android講義');
INSERT INTO `tb_article` VALUES ('3', '瘋狂ios講義', '33.00', '瘋狂ios講義');
INSERT INTO `tb_article` VALUES ('4', 'spring企業級開發', '44.00', 'spring企業級開發');

TB_ITEM

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for tb_item
-- ----------------------------
DROP TABLE IF EXISTS `tb_item`;
CREATE TABLE `tb_item` (
  `ORDER_ID` int(11) NOT NULL,
  `ARTICLE_ID` int(11) NOT NULL,
  `AMOUNT` int(11) DEFAULT NULL,
  PRIMARY KEY (`ORDER_ID`,`ARTICLE_ID`),
  KEY `ARTICLE_ID` (`ARTICLE_ID`),
  CONSTRAINT `ORDER_ID` FOREIGN KEY (`ORDER_ID`) REFERENCES `tb_order` (`ID`),
  CONSTRAINT `ARTICLE_ID` FOREIGN KEY (`ARTICLE_ID`) REFERENCES `tb_article` (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of tb_item
-- ----------------------------
INSERT INTO `tb_item` VALUES ('1', '1', '1');
INSERT INTO `tb_item` VALUES ('1', '2', '1');
INSERT INTO `tb_item` VALUES ('1', '3', '2');
INSERT INTO `tb_item` VALUES ('2', '1', '1');
INSERT INTO `tb_item` VALUES ('2', '4', '2');

創建與數據庫表對應的實體類

  • User.java
  • Order.java
  • Article.java

User.java

public class User implements Serializable{
    private Integer id;
    private String username;
    private String loginname;
    private String password;
    private String phone;
    private String address;
    //用戶和訂單是一對多的關係
    private List<Order> orders;
    //set get方法省略
}

Order.java

public class Order implements Serializable{
    private Integer id;
    private String code;
    private Double total;

    //訂單和用戶是多對一的關係
    private User user;

    //訂單和商品是多對多的關係
    private List<Article> articles;
    //set get方法省略
}

Article.java

public class Article {
    private Integer id;
    private String name;
    private Double price;
    private String remark;
    //商品和訂單應該是多對多的關係
    private List<Order> orders;
}

創建mapper映射xml文件

  • UserMapper.xml
  • OrderMapper.xml
  • ArticleMapper.xml

UserMapper.xml

selectById
根據用戶ID查詢用戶信息

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.liusl.mapper.UserMapper">
    <select id="selectById" resultMap="userResultMap">
        SELECT * FROM TB_USERS WHERE ID = #{id}
    </select>
    <resultMap id="userResultMap" type="User">
        <id property="id" column="ID" />
        <result property="username" column="USERNAME" />
        <result property="loginname" column="LOGINNAME" />
        <result property="password" column="PASSWORD" />
        <result property="phone" column="PHONE" />
        <result property="address" column="ADDRESS" />
        <!--用戶和訂單是一對多的關係使用collection標籤-->
        <collection property="orders" javaType="ArrayList" column="id" fetchType="lazy" ofType="com.liusl.model.Order" select="com.liusl.mapper.OrderMapper.selectByUserId">
            <id property="id" column="ID" />
            <result property="code" column="CODE" />
            <result property="total" column="TOTAL" />
        </collection>
    </resultMap>
</mapper>

因爲查詢用戶的時候會查詢該用戶所有訂單的詳情,用戶與訂單是一對多的關係,使用collection標籤;collection標籤中有幾個屬性。

  • property:對應的是User.java中的屬性名稱“orders”
  • column: 列名id,傳給select屬性中方法的參數
  • fetchType:數據加載方式,lazy代表懶加載,查詢的時候可能不會訪問訂單信息,啓用lazy還需要配置
mybatis:
  configuration:
    lazy-loading-enabled: true
    aggressive-lazy-loading: false
  • ofType: select返回的數據類型
  • select:調用其他的方法來返回該collection的結果,在這個地方會調用com.liusl.mapper.OrderMapper.selectByUserId

OrderMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.liusl.mapper.OrderMapper">
    <!--根據Order Id查詢訂單信息-->
    <select id="selectByOrderId" resultMap="orderResultMap">
        SELECT u.*,o.ID AS OID,o.CODE,o.TOTAL
        FROM TB_USERS u,TB_ORDER o
        WHERE u.ID = o.USER_ID AND o.ID = #{id}
    </select>
    <!--根據用戶ID 查詢訂單信息-->
    <select id="selectByUserId" resultType="com.liusl.model.Order">
        SELECT * FROM TB_ORDER WHERE USER_ID = #{id}
    </select>
    <resultMap id="orderResultMap" type="Order">
        <id property="id" column="ID" />
        <result property="code" column="CODE" />
        <result property="total" column="TOTAL" />
        <!--多對一關聯,多個訂單有一個用戶-->
        <association property="user2" javaType="User2">
            <id property="id" column="ID" />
            <result property="username" column="USERNAME" />
            <result property="loginname" column="LOGINNAME" />
            <result property="password" column="PASSWORD" />
            <result property="phone" column="PHONE" />
            <result property="address" column="ADDRESS" />
        </association>
        <!--多對多關聯collection-->
        <collection property="articles" javaType="ArrayList" ofType="com.liusl.model.Article" fetchType="lazy" column="OID" select="com.liusl.mapper.ArticleMapper.selectArticleByOrderId">
            <id property="id" column="ID" />
            <result property="name" column="NAME" />
            <result property="price" column="PRICE" />
            <result property="remark" column="REMARK" />
        </collection>
    </resultMap>
</mapper>

ArticleMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.liusl.mapper.ArticleMapper">
    <!--根據Order Id查詢商品信息-->
    <!--傳過來的值是ORDER_ID,首先通過中間表查詢出該OID中的所有商品ID,在通過ARTICLE表查詢出商品信息-->
    <select id="selectArticleByOrderId" resultType="com.liusl.model.Article">
        SELECT *
        FROM TB_ARTICLE
        WHERE id IN (
          SELECT ARTICLE_ID FROM TB_ITEM WHERE ORDER_ID = #{id}
        )
    </select>
</mapper>

創建mapper.java文件

  • UserMapper.java
  • OrderMapper.java

UserMapper.java

@Mapper
public interface UserMapper {
    public User selectById(Integer id);
}

OrderMapper.java

@Mapper
public interface OrderMapper {
    public Order selectByOrderId(Integer id);
}

測試

創建測試類

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private OrderMapper orderMapper;
    @Test
    public void selectById() throws Exception {
        User user = userMapper.selectById(1);
        System.out.println(JSON.toJSONString(user,true));
    }
    @Test
    public void selectByOrderId() throws Exception{
        Order order = orderMapper.selectByOrderId(1);
        System.out.println(JSON.toJSONString(order,true));
    }

}

返回結果分別是:

{
    "address":"廣州",
    "id":1,
    "loginname":"jack",
    "orders":[
        {
            "code":"546457657658ygyufyu",
            "id":1,
            "total":566.0
        },
        {
            "code":"3534terteyeyew",
            "id":2,
            "total":467.0
        }
    ],
    "password":"123456",
    "phone":"13765435673",
    "username":"傑克"
}
{
    "articles":[
        {
            "id":1,
            "name":"瘋狂java講義",
            "price":11.0,
            "remark":"瘋狂java講義"
        },
        {
            "id":2,
            "name":"瘋狂android講義",
            "price":22.0,
            "remark":"瘋狂android講義"
        },
        {
            "id":3,
            "name":"瘋狂ios講義",
            "price":33.0,
            "remark":"瘋狂ios講義"
        }
    ],
    "code":"546457657658ygyufyu",
    "id":1,
    "total":566.0,
    "user2":{
        "address":"廣州",
        "id":1,
        "loginname":"jack",
        "password":"123456",
        "phone":"13765435673",
        "username":"傑克"
    }
}

大家要是想買書的話,可以加我的微信15313876221,或者qq1010893356,或者qq羣376448087,比正常的要便宜,程序員你懂得,買個書動不動就100多。^-^

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章