使用Mybatis进行多表联查操作
Posted 365天小人物
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Mybatis进行多表联查操作相关的知识,希望对你有一定的参考价值。
(1)增加一个测试数据库shop_order,sql语句如下:
CREATE DATABASE `shop_order`; USE `shop_order`; CREATE TABLE `t_user` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `username` VARCHAR(20) DEFAULT NULL, `password` VARCHAR(50) DEFAULT NULL, `sex` VARCHAR(2) DEFAULT NULL, `brithday` DATE DEFAULT NULL, `address` VARCHAR(200) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=INNODB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8; CREATE TABLE `t_product` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `name` VARCHAR(100) DEFAULT NULL, `price` FLOAT DEFAULT NULL, `description` TEXT, PRIMARY KEY (`id`) ) ENGINE=INNODB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8; CREATE TABLE `t_order` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `userId` INT(11) DEFAULT NULL, `createTime` DATETIME DEFAULT NULL, `state` VARCHAR(20) DEFAULT NULL, PRIMARY KEY (`id`), KEY `fk_userId` (`userId`), CONSTRAINT `fk_userId` FOREIGN KEY (`userId`) REFERENCES `t_user` (`id`) ) ENGINE=INNODB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; CREATE TABLE `t_orderdetail` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `productId` INT(11) DEFAULT NULL, `orderId` INT(11) DEFAULT NULL, `num` INT(11) DEFAULT NULL, `price` FLOAT DEFAULT NULL, PRIMARY KEY (`id`), KEY `fk_productId` (`productId`), KEY `fk_orderId` (`orderId`), CONSTRAINT `fk_orderId` FOREIGN KEY (`orderId`) REFERENCES `t_order` (`id`), CONSTRAINT `fk_productId` FOREIGN KEY (`productId`) REFERENCES `t_product` (`id`) ) ENGINE=INNODB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; INSERT INTO `t_user`(`id`,`username`,`password`,`sex`,`brithday`,`address`) VALUES (16,\'小黄\',\'2222\',\'男\',\'2014-01-01\',\'中国\'),(17,\'陌拜\',\'1100\',\'男\',\'2014-03-03\',\'深圳\'),(18,\'本拉登\',\'9999\',\'男\',\'2003-09-09\',\'印度\'),(19,\'奥巴马小号\',\'1399\',\'男\',\'2005-01-09\',\'美国\'); INSERT INTO `t_product`(`id`,`name`,`price`,`description`) VALUES (6,\'飞机\',20000000,\'预售,提货时间暂定\'),(7,\'坦克\',300000000,\'预售,提货时间暂定\'),(8,\'大炮\',500000,\'预售,提货时间暂定\'),(9,\'航母\',900000000,\'预售,提货时间暂定\'); INSERT INTO `t_order`(`id`,`userId`,`createTime`,`state`) VALUES (1,18,\'2015-07-04 00:00:00\',\'已付\'),(2,19,\'2017-01-02 00:00:00\',\'已付\'),(3,16,\'2017-12-13 10:07:21\',\'待付\'),(4,18,\'2017-12-05 14:44:04\',\'报废\'); INSERT INTO `t_orderdetail`(`id`,`productId`,`orderId`,`num`,`price`) VALUES (1,8,1,6,3000000),(2,9,2,1,900000000),(3,6,NULL,NULL,NULL);
(2)建立程序的结构,结构如下
(3)建立实体类,与数据库中的表对应
Order.java代码如下:
package entity; import java.util.ArrayList; import java.util.Date; import java.util.List; public class Order { private int id; private Date userId; private String createTime; private String state;
//注意这里报错是正常的,因为这里之后引用了其他的实体类,它们还没被定义,把所有的实体类建立好了以后,保存一下就可以了 private User user; //一个订单对应一个用户,所以在订单中放置一个User的对象 //一个订单可以有多件商品,这里对应多个商品详情,所以放置一个商品详情集合 private List<OrderDetail> orderDetails = new ArrayList<OrderDetail>(); public Order() { super(); } public Order(int id, Date userId, String createTime, String state) { super(); this.id = id; this.userId = userId; this.createTime = createTime; this.state = state; } public int getId() { return id; } public void setId(int id) { this.id = id; } public Date getUserId() { return userId; } public void setUserId(Date userId) { this.userId = userId; } public String getCreateTime() { return createTime; } public void setCreateTime(String createTime) { this.createTime = createTime; } public String getState() { return state; } public void setState(String state) { this.state = state; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } public List<OrderDetail> getOrderDetails() { return orderDetails; } public void setOrderDetails(List<OrderDetail> orderDetails) { this.orderDetails = orderDetails; } }
OrderDetail.java类的代码如下:
package entity; public class OrderDetail { private int id; private int productId; private int orderId; private double price; private int num; private Order order; //一个订单详情,对应某一个订单,所有在这里添加一个订单对象 private Product product; //一个订单详情里面存放一种商品,对应一个商品详情 public OrderDetail() { super(); } public OrderDetail(int id, int productId, int orderId, double price, int num) { super(); this.id = id; this.productId = productId; this.orderId = orderId; this.price = price; this.num = num; } public int getId() { return id; } public void setId(int id) { this.id = id; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public int getNum() { return num; } public void setNum(int num) { this.num = num; } public Order getOrder() { return order; } public void setOrder(Order order) { this.order = order; } public int getProductId() { return productId; } public void setProductId(int productId) { this.productId = productId; } public int getOrderId() { return orderId; } public void setOrderId(int orderId) { this.orderId = orderId; } public Product getProduct() { return product; } public void setProduct(Product product) { this.product = product; } }
Product.java类代码
package entity; public class Product { private int id; private String name; private float price; private String description; public Product() { super(); } public Product(int id, String name, float price, String description) { super(); this.id = id; this.name = name; this.price = price; this.description = description; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } }
User.java类的代码如下:
package entity; import java.util.ArrayList; import java.util.Date; import java.util.List; public class User { private int id; private String username; private String password; private String sex; private Date brithday; private String address; private List<Order> orders = new ArrayList<Order>(); public User() { super(); } public User(int id, String username, String password, String sex, Date brithday, String address) { super(); this.id = id; this.username = username; this.password = password; this.sex = sex; this.brithday = brithday; this.address = address; } 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 String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Date getBrithday() { return brithday; } public void setBrithday(Date brithday) { this.brithday = brithday; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public List<Order> getOrders() { return orders; } public void setOrders(List<Order> orders) { this.orders = orders; } }
(4)编写mybatis-config.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> <!-- 环境:配置mybatis的环境 --> <environments default="development"> <!-- 可以使用多个环境变量,切换时只需修改对应default的属性为该环境变量的id即可 --> <!-- 环境变量:可以配置多个环境变量,比如使用多数据源时,就需要配置多个环境变量 --> <environment id="development"> <!-- 事务管理 --> <transactionManager type="JDBC"></transactionManager> <!-- 数据源 --> <dataSource type="POOLED"> <property name="username" value="root" /> <property name="url" value="jdbc:mysql://localhost:3306/shop_order" /> <property name="password" value="123" /> <!-- 定义驱动连接,根据所使用的数据库的不同进行更换,作者使用的是mySql --> <property name="driver" value="com.mysql.jdbc.Driver" /> </dataSource> </environment> </environments> </configuration>
(5)编写SqlSessionUtil.java拿到数据库的操作对象SqlSession,代码如下
package common; import java.io.IOException; import java.io.InputStream; 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 SqlSessionUtil { public static SqlSession getSession(){ InputStream input = null; try { input = Resources.getResourceAsStream("mybatis-config.xml"); } catch (IOException e) { e.printStackTrace(); } SqlSessionFactoryBuilder builder =new SqlSessionFactoryBuilder(); SqlSessionFactory sqlSessionFactory=builder.build(input); SqlSession session=sqlSessionFactory.openSession(); return session; } }
(6)编写dao里面的接口,这边学习就只写了两个,里面的方法也很简单
OrderDao.java
package dao; import java.util.List; import entity.Order; public interface OrderDao { /** * 查询所有的订单,并取出该订单的用户信息 * @return */ List<Order> queryAllOrder(); }
UserDao.java
package dao; import java.util.List; import entity.User; public interface UserDao { /** * 查询所有用户,并显示每个用户的订单 * @return */ List<User> queryAllUser(); }
(7)编写mapper里面的xml文件,里面存放数据库语句
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="dao.OrderDao"> <select id="queryAllOrder" resultMap="Order_User"> select *,od.id as o_id,us.id as u_id from t_order as od inner join t_user as us on od.userId=us.id </select> <resultMap type="entity.Order" id="Order_User"> <id column="o_id" property="id"/> <result column="userId" property="userId"/> <result column="createTime" property="createTime"/> <result column="state" property="state"/> <association property="user" javaType="entity.User"> <id column="u_id" property="id"></id> <result column="username" property="username"/> <result column="password" property="password"/> <result column="sex" property="sex"/> <result column="brithday" property="brithday"/> <result column="address" property="address"/> </association> </resultMap> </mapper>
UserMapper.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="dao.UserDao"> <resultMap type="entity.User" id="User_Order"> <id column="id" property="id"/> <result column="username" property="username"/> <result column="password" property="password"/> <result column="sex" property="sex"/> <result column="brithday" property="brithday"/> <result column="address" property="address"/> <collection property="orders" ofType="entity.Order"> <id column="o_id" property="id"/> <result column="userId" property="userId"/> <result column="createTime" property="createTime"/> <result column="state" property="state"/> </collection> </resultMap> <select id="queryAllUser" resultMap="User_Order"> SELECT *,o.id AS o_id FROM t_user AS u INNER JOIN t_order AS o ON u.id=o.userId </select> </mapper>
(8)在mybatis-config.xml中的<configuration>标签里面<environments>标签下面添加如下映射
<mappers> <mapper resource="mapper/UserMapper.xml"/><!-- 包名。xml文件名 <以上是关于使用Mybatis进行多表联查操作的主要内容,如果未能解决你的问题,请参考以下文章
MyBatis关于多表联查 关联关系之一--------一对多(单条sql语句查询)
使用mybatis多表联查的时候结果异常及springmvc的理解