Mybatis入门---一对多、多对多
前幾天自己配置了Mybatis的高級查詢:一對多和多對多,現(xiàn)在記錄一下,方便以后用到的時候再回顧,下面是具體的操作步驟
一、首先就是配置Mybatis的xml文件及mapper的xml文件,在這里就不多說了,之前寫過這個基本的配置,可以參考:https://www.cnblogs.com/blogs-of-xiu/p/10405407.html
經(jīng)過配置完基本的xml文件之后,我們就開始實現(xiàn)一對多和多對多的需求。
我這里舉的例子是用戶和訂單,一個用戶可以對應(yīng)多個訂單,所以需要的表也是用戶表和訂單表。數(shù)據(jù)結(jié)構(gòu)如下:之前的文章中是一對一查詢,只用到了user表,現(xiàn)在多了三個表分別是orders【訂單表】、order_detail【訂單詳情】、product【商品表】。
用戶與訂單的關(guān)系為一對多,訂單與訂單明細(xì)的關(guān)系是一對多,訂單明細(xì)與商品表的關(guān)系是一對一,用戶與商品的關(guān)系是多對多。
在這里我們使用的關(guān)系是用戶與訂單【一對多】和用戶與商品的關(guān)系【多對多】,下面會說明多對多的關(guān)系如何配置。
整個數(shù)據(jù)庫的sql結(jié)構(gòu)如下【從邏輯上面推敲,可能有些字段設(shè)置的不合適】:
/* Navicat MySQL Data TransferSource Server : xxx Source Server Version : 50540 Source Host : localhost:3306 Source Database : mybatisTarget Server Type : MYSQL Target Server Version : 50540 File Encoding : 65001Date: 2019-03-14 11:07:30 */SET FOREIGN_KEY_CHECKS=0;-- ---------------------------- -- Table structure for orders -- ---------------------------- DROP TABLE IF EXISTS `orders`; CREATE TABLE `orders` (`id` int(11) NOT NULL AUTO_INCREMENT,`user_id` int(11) DEFAULT NULL,`order_number` int(11) DEFAULT NULL,PRIMARY KEY (`id`),KEY `user_id` (`user_id`),CONSTRAINT `user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;-- ---------------------------- -- Table structure for order_detail -- ---------------------------- DROP TABLE IF EXISTS `order_detail`; CREATE TABLE `order_detail` (`id` int(11) NOT NULL AUTO_INCREMENT,`order_id` int(11) NOT NULL,`product_id` int(255) DEFAULT NULL,PRIMARY KEY (`id`),KEY `order_id` (`order_id`),KEY `product_id` (`product_id`),CONSTRAINT `order_id` FOREIGN KEY (`order_id`) REFERENCES `orders` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,CONSTRAINT `product_id` FOREIGN KEY (`product_id`) REFERENCES `product` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8;-- ---------------------------- -- Table structure for product -- ---------------------------- DROP TABLE IF EXISTS `product`; CREATE TABLE `product` (`id` int(11) NOT NULL AUTO_INCREMENT,`product_name` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;-- ---------------------------- -- Table structure for user -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` (`id` int(11) NOT NULL AUTO_INCREMENT,`username` varchar(255) DEFAULT NULL,`password` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;二、經(jīng)過數(shù)據(jù)庫的設(shè)計之后,我們開始進(jìn)行實現(xiàn)代碼,下面是主要的類:
1、實體類中除了product類不需要加入其它類的對象之外,另外幾個類中都需要加入其它實體類的對象。
【原因:例如用戶 UserBean 中,屬性需要加上訂單 Orders 的對象,因為訂單對于用戶來說是多的一方】
具體的代碼如下:
UserBean:
package bean;import java.util.List;public class UserBean {private int id;private String username;private String password;private List<Orders> ordersList;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public List<Orders> getOrdersList() {return ordersList;}public void setOrdersList(List<Orders> ordersList) {this.ordersList = ordersList;}@Overridepublic String toString() {return "UserBean [id=" + id + ", username=" + username + ", password=" + password + ", ordersList=" + ordersList+ "]";}public UserBean(String username, String password) {super();this.username = username;this.password = password;}public UserBean(int id, String username, String password, List<Orders> ordersList) {super();this.id = id;this.username = username;this.password = password;this.ordersList = ordersList;}public UserBean() {super();}}訂單類? Orders:
package bean;import java.util.List;public class Orders {private int id;private int user_id;private String number;private List<Order_Detail> order_detail;public int getId() {return id;}public void setId(int id) {this.id = id;}public int getUser_id() {return user_id;}public void setUser_id(int user_id) {this.user_id = user_id;}public String getNumber() {return number;}public void setNumber(String number) {this.number = number;}public List<Order_Detail> getOrder_detail() {return order_detail;}public void setOrder_detail(List<Order_Detail> order_detail) {this.order_detail = order_detail;}@Overridepublic String toString() {return "Orders [id=" + id + ", user_id=" + user_id + ", number=" + number + ", order_detail=" + order_detail+ "]";}public Orders(int id, int user_id, String number, List<Order_Detail> order_detail) {super();this.id = id;this.user_id = user_id;this.number = number;this.order_detail = order_detail;}public Orders() {super();}}訂單明細(xì) Order_Detail:
package bean;public class Order_Detail {private int id;private int order_id;private int product_id;private Product product;public int getId() {return id;}public void setId(int id) {this.id = id;}public int getOrder_id() {return order_id;}public void setOrder_id(int order_id) {this.order_id = order_id;}public int getProduct_id() {return product_id;}public void setProduct_id(int product_id) {this.product_id = product_id;}public Product getProduct() {return product;}public void setProduct(Product product) {this.product = product;}@Overridepublic String toString() {return "Order_Detail [id=" + id + ", order_id=" + order_id + ", product_id=" + product_id + ", product="+ product + "]";}public Order_Detail(int id, int order_id, int product_id, Product product) {super();this.id = id;this.order_id = order_id;this.product_id = product_id;this.product = product;}public Order_Detail() {super();} }商品類? Product:
package bean;public class Product {private int id;private String product_name;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getProduct_name() {return product_name;}public void setProduct_name(String product_name) {this.product_name = product_name;}@Overridepublic String toString() {return "Product [id=" + id + ", product_name=" + product_name + "]";}public Product(int id, String product_name) {super();this.id = id;this.product_name = product_name;}public Product() {super();}}2、mapper 接口和mapper.xml文件:
UserMapper 接口:
package mapper;import java.util.List;import bean.Orders; import bean.UserBean;public interface UserMapper {/*** description select all users*/public List<UserBean> selectAllUser();/*** description insert*/public int insertUser(UserBean userbean);/*** description delete user by id* */public int deleteUserById(int id);/*** description update user* */public int updateUser(UserBean userbean);/*** description select user by id* */public UserBean selectUserById(int id);// 一對多 查詢一個用戶對應(yīng)的多個訂單public List<Orders> selectOrdersOfUser();// 多對多 查詢一個用戶對應(yīng)的多個商品public List<Orders> selectProductOfUser();}xml文件 UserMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="mapper.UserMapper"><resultMap id="usermap" type="UserBean"><id property="id" column="id" javaType="java.lang.Integer" /><result property="username" column="username" javaType="java.lang.String" /><result property="password" column="password" javaType="java.lang.String" /></resultMap><!-- 一對多 查詢用戶的訂單 --><resultMap id="ordersmap" type="UserBean"><!--這個id的column是你要映射到SQL語句中的,這個property是你從真實的beans實體類的屬性中的id --><id column="id" property="id" /><result column="username" property="username" /><result column="password" property="password" /><!--因為這個地方的是一對多,要關(guān)聯(lián)到的是一個集合所以使用collection --><collection property="ordersList" ofType="Orders"><id column="id" property="id" /><result column="order_number" property="number" /></collection></resultMap><resultMap id="selectProductOfUserMap" type="UserBean"><id column="id" property="id" /><result column="username" property="username" /><result column="password" property="password" /><!-- 通過用戶查詢訂單 ordersList 字段來自UserBean實體類中聲明的Order對象名,以下的情況都是--><collection property="ordersList" ofType="Orders"> <id column="id" property="id" />
<result column="order_number" property="number" />
<!-- 通過訂單查詢訂單明細(xì) --> <collection property="order_detail" ofType="Order_Detail">
<id column="id" property="id" />
<result column="order_id" property="order_id" />
<result column="product_id" property="product_id" />
<!-- 通過訂單明細(xì)查詢商品 --> <association property="product" javaType="Product">
<id column="id" property="id" /> <result column="product_name" property="product_name" />
</association> </collection> </collection> </resultMap>
<select id="selectAllUser" resultMap="usermap">
select * from user </select> <insert id="insertUser">
insert into user(username,password)values(#{username},#{password}) </insert>
<delete id="deleteUserById"> delete from user where id=#{id} </delete>
<update id="updateUser"> update user set username=#{username},password=#{password} where id=#{id} </update>
<select id="selectUserById" resultMap="usermap"> select * from user where id=#{id} </select>
<!-- 一對多 查詢用戶的訂單 -->
<select id="selectOrdersOfUser" resultMap="ordersmap"> select t1.*, t2.order_number from user t1, orders t2 where t1.id=t2.user_id </select>
<select id="selectProductOfUser" resultMap="selectProductOfUserMap">
select t1.id as user_id,t1.username, t2.id as order_id,t2.order_number, t3.id as order_detail_id,t3.product_id, t4.id as product_id,t4.product_name
from user t1, orders t2, order_detail t3, product t4 where t1.id=t2.user_id and t3.order_id=t2.id and t3.product_id=t4.id </select> </mapper>
3、邏輯層和測試 我寫在了service類,但是這樣不太符合規(guī)范
UserService類:
package service;import java.util.List;import org.apache.ibatis.session.SqlSession;import bean.UserBean; import mapper.UserMapper; import tools.DB;public class UserService {public static void main(String[] args) {// selectAllUser();// insertUser();// deleteUserById();// updateUser();// 一對多 查詢用戶的訂單// selectOrdersOfUser();// 多對多 查詢用戶對應(yīng)的商品 selectProductOfUser();}private static void selectAllUser() {SqlSession session = DB.getSession();UserMapper mapper = session.getMapper(UserMapper.class);try {List<UserBean> user = mapper.selectAllUser();System.out.println(user.toString());session.commit();} catch (Exception e) {e.printStackTrace();session.rollback();}}private void insertUser() {SqlSession session = DB.getSession();UserMapper mapper = session.getMapper(UserMapper.class);try {UserBean userbean = new UserBean("zs", "123");mapper.insertUser(userbean);System.out.println(userbean.toString());session.commit();} catch (Exception e) {e.printStackTrace();session.rollback();}}private static void deleteUserById() {SqlSession session = DB.getSession();UserMapper mapper = session.getMapper(UserMapper.class);try {mapper.deleteUserById(3);System.out.println("刪除成功");session.commit();} catch (Exception e) {e.printStackTrace();session.rollback();}}private static void updateUser() {SqlSession session = DB.getSession();UserMapper mapper = session.getMapper(UserMapper.class);UserBean userbean = mapper.selectUserById(4);System.out.println("修改之前的userbean:" + userbean);try {userbean.setUsername("hhh");userbean.setPassword("111");mapper.updateUser(userbean);System.out.println("修改之后的userbean:" + userbean);session.commit();} catch (Exception e) {e.printStackTrace();session.rollback();}}// 一對多 查詢用戶訂單private static void selectOrdersOfUser() {SqlSession session = DB.getSession();UserMapper mapper = session.getMapper(UserMapper.class);System.out.println(mapper.selectOrdersOfUser().toString());}// 多對多 查詢用戶對應(yīng)的商品private static void selectProductOfUser() {SqlSession session = DB.getSession();UserMapper mapper = session.getMapper(UserMapper.class);System.out.println(mapper.selectProductOfUser().toString());} }4、mybatis.xml 文件:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration><typeAliases><typeAlias type="bean.UserBean" alias="UserBean"/><typeAlias type="bean.Orders" alias="Orders"/><typeAlias type="bean.Order_Detail" alias="Order_Detail"/><typeAlias type="bean.Product" alias="Product"/></typeAliases><environments default="cybatis"><environment id="cybatis"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mybatis"/><property name="username" value="root"/><property name="password" value="123456"/></dataSource></environment></environments><mappers><package name="mapper"/></mappers> </configuration>5、一對多的關(guān)鍵點是collection標(biāo)簽的配置,多對多中的關(guān)鍵點事collection和association標(biāo)簽的配置。collection里面property的值是來自一對多中多的那方的對象。
多對多的關(guān)系中,我們需要將多對多關(guān)系拆分成一對多來實現(xiàn)。
【例如多個用戶對應(yīng)多個商品,可以拆分成 :
一個用戶對應(yīng)多個訂單(一對多)+ 一個訂單對應(yīng)多個訂單明細(xì)(一對多) + 一個訂單明細(xì)對應(yīng)一個商品(一對一),最終實現(xiàn)用戶->商品的聯(lián)系。】
6、以上就是主要的代碼實現(xiàn),但是這樣正常運行的話,在控制臺出現(xiàn)的結(jié)果和我們將sql語句粘貼到數(shù)據(jù)庫中運行得到的結(jié)果不一致。不一致的現(xiàn)象就是在數(shù)據(jù)庫中正常得到我們需要的數(shù)據(jù),但是在控制臺中得出的卻是相同用戶id多個訂單的情況,只能查到一條數(shù)據(jù),原因是mybatis查到主鍵為id的數(shù)據(jù),只會查到第一條。解決辦法就是將表中的主鍵為id的修改一下,不讓主鍵名為id,這樣查到的結(jié)果就是我們得到的全部數(shù)據(jù)了。
?
轉(zhuǎn)載于:https://www.cnblogs.com/blogs-of-xiu/p/10528791.html
總結(jié)
以上是生活随笔為你收集整理的Mybatis入门---一对多、多对多的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php对接海康视频教程_海康安防管理平台
- 下一篇: 相机标定(一) —— 深入理解齐次坐标及