在数据库中建立表的脚本
table.sqljava
CREATE TABLE tb_user( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(18), loginname VARCHAR(18), PASSWORD VARCHAR(18), phone VARCHAR(18), address VARCHAR(18) ); INSERT INTO tb_user(username,loginname,PASSWORD,phone,address) VALUES('杰克','jack','123456','13920001616','广州'); CREATE TABLE tb_article( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(50), price DOUBLE, remark VARCHAR(18) ); INSERT INTO tb_article(NAME,price,remark) VALUES('疯狂Java讲义',108.9,'李刚老师经典著做'); INSERT INTO tb_article(NAME,price,remark) VALUES('疯狂Android讲义',99.9,'李刚老师经典著做'); INSERT INTO tb_article(NAME,price,remark) VALUES('疯狂iOS讲义',89.9,'李刚老师经典著做'); INSERT INTO tb_article(NAME,price,remark) VALUES('SpringMVC+MyBatis企业开发',69.9,'肖文吉老师经典著做'); CREATE TABLE tb_order( id INT PRIMARY KEY AUTO_INCREMENT, CODE VARCHAR(32), total DOUBLE, user_id INT, FOREIGN KEY (user_id) REFERENCES tb_user(id) ); INSERT INTO tb_order(CODE,total,user_id) VALUES('6aa3fa359ff14619b77fab5990940a2d',388.6,1); INSERT INTO tb_order(CODE,total,user_id) VALUES('6aa3fa359ff14619b77fab5990940b3c',217.8,1); CREATE TABLE tb_item( order_id INT, article_id INT, amount INT, PRIMARY KEY(order_id,article_id), FOREIGN KEY (order_id) REFERENCES tb_order(id), FOREIGN KEY (article_id) REFERENCES tb_article(id) ); INSERT INTO tb_item(order_id,article_id,amount) VALUES(1,1,1); INSERT INTO tb_item(order_id,article_id,amount) VALUES(1,2,1); INSERT INTO tb_item(order_id,article_id,amount) VALUES(1,3,2); INSERT INTO tb_item(order_id,article_id,amount) VALUES(2,4,2); INSERT INTO tb_item(order_id,article_id,amount) VALUES(2,1,1);
接下来建立一个User类,Article和一个Order类来映射数据库中的表
用户和订单是一对多的关系,即一个用户能够有多个订单,在User类中定义一个orders属性,该属性是一个List集合,用来映射一对多的关联关系
订单与用户是多对一的关系,一个订单只是属于一个用户,在Order类中定义一个user属性,用来映射多对一的关联关系
商品和订单是多对多的关系,即一种商品能够出如今多个订单中,在Article类中定义一个orders属性,该属性是一个List集合,用来映射多对多的关联关系,表示该商品关联的多个订单
Article.javasql
public class Article implements Serializable { private Integer id; // 商品id,主键 private String name; // 商品名称 private Double price; // 商品价格 private String remark; // 商品描述 // 商品和订单是多对多的关系,即一种商品能够包含在多个订单中 private List<Order> orders; }
Order.java数据库
public class Order implements Serializable { private Integer id; // 订单id,主键 private String code; // 订单编号 private Double total; // 订单总金额 // 订单和用户是多对一的关系,即一个订单只属于一个用户 private User user; // 订单和商品是多对多的关系,即一个订单能够包含多种商品 private List<Article> articles; }
User.javaapache
public class User implements Serializable{ private Integer id; // 用户id,主键 private String username; // 用户名 private String loginname; // 登陆名 private String password; // 密码 private String phone; // 联系电话 private String address; // 收货地址 // 用户和订单是一对多的关系,即一个用户能够有多个订单 private List<Order> orders;
xml文件配置
ArticleMapper.xmlsession
<?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"> <!-- namespace指用户自定义的命名空间。 --> <mapper namespace="com.rookie.bigdata.mapper.ArticleMapper"> <select id="selectArticleByOrderId" parameterType="int" resultType="com.rookie.bigdata.domain.Article"> SELECT * FROM tb_article WHERE id IN ( SELECT article_id FROM tb_item WHERE order_id = #{id} ) </select> </mapper>
OrderMapper.xmlmybatis
<?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"> <!-- namespace指用户自定义的命名空间。 --> <mapper namespace="com.rookie.bigdata.mapper.OrderMapper"> <resultMap type="com.rookie.bigdata.domain.Order" id="orderResultMap"> <id property="id" column="oid"/> <result property="code" column="code"/> <result property="total" column="total"/> <!-- 多对一关联映射:association --> <association property="user" javaType="com.rookie.bigdata.domain.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"/> </association> <!-- 多对多映射的关键:collection --> <collection property="articles" javaType="ArrayList" column="oid" ofType="com.rookie.bigdata.domain.Article" select="com.rookie.bigdata.mapper.ArticleMapper.selectArticleByOrderId" fetchType="lazy"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="price" column="price"/> <result property="remark" column="remark"/> </collection> </resultMap> <!-- 注意,若是查询出来的列同名,例如tb_user表的id和tb_order表的id都是id,同名,须要使用别名区分 --> <select id="selectOrderById" parameterType="int" resultMap="orderResultMap"> SELECT u.*,o.id AS oid,CODE,total,user_id FROM tb_user u,tb_order o WHERE u.id = o.user_id AND o.id = #{id} </select> <!-- 根据userid查询订单 --> <select id="selectOrderByUserId" parameterType="int" resultType="com.rookie.bigdata.domain.Order"> SELECT * FROM tb_order WHERE user_id = #{id} </select> </mapper>
UserMapper.xmlapp
<?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"> <!-- namespace指用户自定义的命名空间。 --> <mapper namespace="com.rookie.bigdata.mapper.UserMapper"> <resultMap type="com.rookie.bigdata.domain.User" id="userResultMap"> <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" ofType="com.rookie.bigdata.domain.User" select="com.rookie.bigdata.mapper.OrderMapper.selectOrderByUserId" fetchType="lazy"> <id property="id" column="id"/> <result property="code" column="code"/> <result property="total" column="total"/> </collection> </resultMap> <select id="selectUserById" parameterType="int" resultMap="userResultMap"> SELECT * FROM tb_user WHERE id = #{id} </select> </mapper>
测试代码dom
package com.rookie.bigdata.test; import java.io.InputStream; import java.util.List; import com.rookie.bigdata.domain.Article; import com.rookie.bigdata.domain.Order; import com.rookie.bigdata.domain.User; import com.rookie.bigdata.mapper.OrderMapper; import com.rookie.bigdata.mapper.UserMapper; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; public class ManyToManyTest { public static void main(String[] args) throws Exception { // 读取mybatis-config.xml文件 InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml"); // 初始化mybatis,建立SqlSessionFactory类的实例 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder() .build(inputStream); // 建立Session实例 SqlSession session = sqlSessionFactory.openSession(); ManyToManyTest t = new ManyToManyTest(); // 根据用户id查询用户,测试一对多 // t.testSelectUserById(session); // 根据订单id查询订单,测试多对多 t.testSelectOrderById(session); // 提交事务 session.commit(); // 关闭Session session.close(); } // 测试一对多,查询班级User(一)的时候级联查询订单Order(多) public void testSelectUserById(SqlSession session){ // 得到UserMapper接口的代理对象 UserMapper um = session.getMapper(UserMapper.class); // 调用selectUserById方法 User user = um.selectUserById(1); // 查看查询到的user对象信息 System.out.println(user.getId() + " " + user.getUsername()); // 查看user对象关联的订单信息 List<Order> orders = user.getOrders(); for(Order order : orders){ System.out.println(order); } } // 测试多对多,查询订单Order(多)的时候级联查询订单的商品Article(多) public void testSelectOrderById(SqlSession session){ // 得到OrderMapper接口的代理对象 OrderMapper om = session.getMapper(OrderMapper.class); // 调用selectOrderById方法 Order order = om.selectOrderById(2); // 查看查询到的order对象信息 System.out.println(order.getId() + " " + order.getCode() + " " + order.getTotal()); // 查看order对象关联的用户信息 User user = order.getUser(); System.out.println(user); // 查看order对象关联的商品信息 List<Article> articles = order.getArticles(); for(Article article : articles){ System.out.println(article); } } }
多对多关系测试代码测试