概述
mybatis高级查询——基于xml配置(详细介绍)
提示
文章目录
- mybatis高级查询——基于xml配置(详细介绍)
- 一、准备工作
- 二、一对一查询
- 1. 需求分析
- 2. 代码实现
- 三、一对多查询
一、准备工作
步骤:
1、数据如下:
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for tb_item
-- ----------------------------
DROP TABLE IF EXISTS `tb_item`;
CREATE TABLE `tb_item` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`item_name` varchar(32) NOT NULL COMMENT '商品名称',
`item_price` float(6,1) NOT NULL COMMENT '商品价格',
`item_detail` text COMMENT '商品描述',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of tb_item
-- ----------------------------
INSERT INTO `tb_item` VALUES ('1', 'iPhone 6', '5288.0', '苹果公司新发布的手机产品。');
INSERT INTO `tb_item` VALUES ('2', 'iPhone 6 plus', '6288.0', '苹果公司发布的新大屏手机。');
-- ----------------------------
-- Table structure for tb_order
-- ----------------------------
DROP TABLE IF EXISTS `tb_order`;
CREATE TABLE `tb_order` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) NOT NULL,
`order_number` varchar(20) NOT NULL COMMENT '订单号',
PRIMARY KEY (`id`),
KEY `FK_orders_1` (`user_id`),
CONSTRAINT `FK_orders_1` FOREIGN KEY (`user_id`) REFERENCES `tb_user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of tb_order
-- ----------------------------
INSERT INTO `tb_order` VALUES ('1', '1', '20140921001');
INSERT INTO `tb_order` VALUES ('2', '2', '20140921002');
INSERT INTO `tb_order` VALUES ('3', '1', '20140921003');
-- ----------------------------
-- Table structure for tb_orderdetail
-- ----------------------------
DROP TABLE IF EXISTS `tb_orderdetail`;
CREATE TABLE `tb_orderdetail` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`order_id` int(32) DEFAULT NULL COMMENT '订单号',
`item_id` int(32) DEFAULT NULL COMMENT '商品id',
`total_price` double(20,0) DEFAULT NULL COMMENT '商品总价',
`status` int(11) DEFAULT NULL COMMENT '状态',
PRIMARY KEY (`id`),
KEY `FK_orderdetail_1` (`order_id`),
KEY `FK_orderdetail_2` (`item_id`),
CONSTRAINT `FK_orderdetail_1` FOREIGN KEY (`order_id`) REFERENCES `tb_order` (`id`),
CONSTRAINT `FK_orderdetail_2` FOREIGN KEY (`item_id`) REFERENCES `tb_item` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of tb_orderdetail
-- ----------------------------
INSERT INTO `tb_orderdetail` VALUES ('1', '1', '1', '5288', '1');
INSERT INTO `tb_orderdetail` VALUES ('2', '1', '2', '6288', '1');
INSERT INTO `tb_orderdetail` VALUES ('3', '2', '2', '6288', '1');
INSERT INTO `tb_orderdetail` VALUES ('4', '3', '1', '5288', '1');
-- ----------------------------
-- Table structure for tb_user
-- ----------------------------
DROP TABLE IF EXISTS `tb_user`;
CREATE TABLE `tb_user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_name` varchar(100) DEFAULT NULL COMMENT '用户名',
`password` varchar(100) DEFAULT NULL COMMENT '密码',
`name` varchar(100) DEFAULT NULL COMMENT '姓名',
`age` int(10) DEFAULT NULL COMMENT '年龄',
`sex` int(11) DEFAULT NULL COMMENT '0-女 1-男',
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`user_name`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of tb_user
-- ----------------------------
INSERT INTO `tb_user` VALUES ('1', 'zhangsan', '123456', '张三', '30', '1');
INSERT INTO `tb_user` VALUES ('2', 'lisi', '123456', '李四', '21', '0');
INSERT INTO `tb_user` VALUES ('3', 'wangwu', '123456', '王五', '22', '1');
INSERT INTO `tb_user` VALUES ('4', 'zhangwei', '123456', '张伟', '20', '1');
INSERT INTO `tb_user` VALUES ('5', 'lina', '123456', '李娜', '28', '0');
INSERT INTO `tb_user` VALUES ('6', '蔡徐坤', '123', '小菜', '18', '1');
2、包结构:创建java项目,导入jar包和log4j日志配置文件以及连接数据库的配置文件如下图:
3、运行sql,得到各表之间的关系:
4、创建实体pojo类:
pojo类代码如下:
package com.it.pojo;
/**
* 商品表
*/
public class Item {
private Integer id;
private String itemName;
private Float itemPrice;
private String itemDetail;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public Float getItemPrice() {
return itemPrice;
}
public void setItemPrice(Float itemPrice) {
this.itemPrice = itemPrice;
}
public String getItemDetail() {
return itemDetail;
}
public void setItemDetail(String itemDetail) {
this.itemDetail = itemDetail;
}
@Override
public String toString() {
return "Item{" +
"id=" + id +
", itemName='" + itemName + ''' +
", itemPrice=" + itemPrice +
", itemDetail='" + itemDetail + ''' +
'}';
}
}
package com.it.pojo;
import java.util.List;
/**
* 订单表
*
*/
public class Order {
private Integer id;
private String orderNumber;
@Override
public String toString() {
return "Order{" +
"id=" + id +
", orderNumber='" + orderNumber + ''' +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getOrderNumber() {
return orderNumber;
}
public void setOrderNumber(String orderNumber) {
this.orderNumber = orderNumber;
}
}
package com.it.pojo;
public class Orderdetail {
private Integer id;
private Double totalPrice;
private Integer status;
public Double getTotalPrice() {
return totalPrice;
}
public void setTotalPrice(Double totalPrice) {
this.totalPrice = totalPrice;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Override
public String toString() {
return "Orderdetail [id=" + id + ", totalPrice=" + totalPrice
+ ", status=" + status + "]";
}
}
package com.it.pojo;
import java.io.Serializable;
import java.util.List;
public class User implements Serializable{
private Long id;
// 用户名
private String userName;
// 密码
private String password;
// 姓名
private String name;
// 年龄
private Integer age;
//0-女 1-男
private Integer sex;
public Long getId() {
return id;
}
public void setId(Long 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 getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", userName='" + userName + ''' +
", password='" + password + ''' +
", name='" + name + ''' +
", age=" + age +
", sex=" + sex +
'}';
}
}
5、配置UserMapper.xml映射文件和接口
需求:查询id=1的用户信息
接口:
package com.it.dao;
import com.it.pojo.User;
import org.apache.ibatis.annotations.Param;
public interface UserDao {
User findById(@Param("id") Long 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:命名空间,全局唯一-->
<mapper namespace="com.it.dao.UserDao">
<resultMap id="userMap" type="user" autoMapping="true">
<id column="id" property="id"/>
<result column="user_name" property="userName"/>
</resultMap>
<select id="findById" resultMap="userMap">
select * from tb_user where id=#{id}
</select>
</mapper>
注意:(1)此时核心配置文件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">
<!--mybatis核心配置的根标签-->
<configuration>
<properties resource="jdbc.properties"/>
<!--取别名-->
<typeAliases>
<package name="com.it.pojo"/>
</typeAliases>
<!--mybatis环境的配置,可以配置多个 比如 开发环境,测试环境,生产环境-->
<environments default="development">
<!--通常我们只配置一个就可以,id是环境的名称-->
<environment id="development">
<!--事务管理器,有JDBC来管理-->
<transactionManager type="JDBC"/>
<!--数据源配置,POOLED表示使用mybatis自带的数据库连接池-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClass}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.userName}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!--批量加载映射文件-->
<mappers>
<!--加载映射文件,-->
<mapper resource="UserDao.xml"/>
</mappers>
</configuration>
(2)log4j.properties为:
# 设置Logger输出级别和输出目的地
log4j.rootLogger=debug, stdout
# 把日志信息输出到控制台
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
(3)jdbc.properties为:
jdbc.url=jdbc:mysql:///day07_01
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.userName=root
jdbc.password=root
关于这几个文件的配置,在我的另一篇文章中有详细的介绍,在此不做赘述。
此时工程结构图如下:
6、单元测试
目的:测试框架是否搭建成功
思路:通过junit注解@BeforeClass初始化一次Mapper动态代理对象,其他方法直接调用公共mapper变量即可
代码如下:
package com.it.test;
import com.it.dao.UserDao;
import com.it.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
public class TestAll {
private static UserDao userDao;
@BeforeClass
public static void init(){
//1.加载核心配置文件,构建会话工厂
InputStream in = null;
try {
in = Resources.getResourceAsStream("mybatis-config.xml");
} catch (IOException e) {
e.printStackTrace();
}
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
//获取会话对象
SqlSession session = sessionFactory.openSession();
//获取代理对象
userDao = session.getMapper(UserDao.class);
}
@Test
public void test1(){
User user = userDao.findById(1l);
System.out.println(user.toString());
}
}
运行结果如下则说明搭建成功:
二、一对一查询
需求:通过订单编号20140921003查询出订单信息,并查询出下单人信息。
说明:一个订单编号对应一个订单,一个订单只能属于一个人。所以上述需求实现是一对一的实现
1. 需求分析
步骤:
(1)书写查询的sql
(2)订单实体添加属性映射
(3)添加order接口及方法
(4)创建order映射文件,编写SQL
(5)测试
2. 代码实现
(1)书写查询的sql
代码如下:
-- 分步查询
-- 1.查询订单信息
select * from tb_order where order_number='20140921003';-- user_id=1
-- 2.根据用户ID查询用户信息
select * from tb_user where id=1;
-- 一步查询
select * from tb_order as tor,tb_user as tus where tor.user_id=tus.id
and tor.order_number='20140921003';
(2)订单实体添加属性映射
在Order类中添加属性:
private User tuser;
private List<Orderdetail> orderdetails;
(3)添加Order接口及方法:
package com.it.dao;
import com.it.pojo.Order;
import org.apache.ibatis.annotations.Param;
public interface OrderDao {
//根据订单编号查询订单信息,包含用户信息
Order findByOrderNumber(@Param("orderNumber") String orderNumber);
}
(4)创建order映射文件,编写SQL
<?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:命名空间,全局唯一-->
<mapper namespace="com.it.dao.OrderDao">
<resultMap id="orderMap" type="order" autoMapping="true">
<id column="order_id" property="id"/>
<result column="order_number" property="orderNumber"/>
<!--说明:
association用于一对一映射
property="tuser":表示关联订单类中的User变量
javaType="user":表示关联的变量类型
-->
<association property="tuser" javaType="user" autoMapping="true">
<id column="id" property="id"/>
<result column="user_name" property="userName"/>
</association>
</resultMap>
<select id="findByOrderNumber" resultMap="orderMap">
select tus.*,tor.id as order_id,tor.order_number
from tb_order as tor,
tb_user as tus
where tor.user_id = tus.id
and tor.order_number = #{orderNumber}
</select>
</mapper>
注意此时的核心配置文件:
(5)测试
代码如下:
package com.it.test;
import com.it.dao.OrderDao;
import com.it.dao.UserDao;
import com.it.pojo.Order;
import com.it.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
public class TestAll {
private static UserDao userDao;
private static OrderDao orderDao;
@BeforeClass
public static void init(){
//1.加载核心配置文件,构建会话工厂
InputStream in = null;
try {
in = Resources.getResourceAsStream("mybatis-config.xml");
} catch (IOException e) {
e.printStackTrace();
}
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
//获取会话对象
SqlSession session = sessionFactory.openSession();
//获取代理对象
userDao = session.getMapper(UserDao.class);
orderDao=session.getMapper(OrderDao.class);
}
@Test
public void test1(){
User user = userDao.findById(1l);
System.out.println(user.toString());
}
@Test
public void test2(){
Order order = orderDao.findByOrderNumber("20140921003");
System.out.println(order);
}
}
运行结果如下图:
注意:mybatis框架的一对一查询格式:
<resultMap id="映射ID" type="主表实体名称" autoMapping="true" >
<!-- 添加主表语主表实体映射 -->
......
<!--association:配置关联对象(User)的映射关系,一般与resultMap标签联合使用 -->
<association property="主表实体中对应从表的属性名称" javaType="从表实体类型" autoMapping="true">
<!-- 添加从表中字段与实体属性映射关系 -->
</association>
</resultMap>
三、一对多查询
需求:查询id为1的用户及其订单信息
分析:一个用户可以有多个订单,一个订单只能属于一个用户。
步骤:
1、查询SQL分析
-- 1.分步查询
-- 1.1 查询用户信息
select * from tb_user where id=1;
-- 1.2 根据用户id查询订单集合
select * from tb_order where user_id=1;
-- 2.一次性获取
select
tus.*,
tor.id as order_id,
tor.order_number
from tb_user as tus,
tb_order as tor
where tus.id = tor.user_id
and tus.id = 1;
2、添加关联关系
User实体添加映射关系:
public class User implements Serializable{
private List<Order> orders;
private Long id;
// 用户名
private String userName;
// 密码
private String password;
// 姓名
private String name;
.....
3、编写接口方法(在UserDao中)
User findUserAndOrderById(@Param("id")Long id);
4、编写映射文件(在UserDao.xml中)
<resultMap id="userOrderMap" type="user" autoMapping="true">
<id column="id" property="id"/>
<result column="user_name" property="userName"/>
<collection property="orders" javaType="list" ofType="order" autoMapping="true">
<id column="order_id" property="id"/>
<result column="order_number" property="orderNumber"/>
</collection>
</resultMap>
<select id="findUserAndOrderById" resultMap="userOrderMap" >
select
tus.*,
tor.id as order_id,
tor.order_number
from tb_user as tus,
tb_order as tor
where tus.id = tor.user_id
and tus.id = #{id}
</select>
5、测试
@Test
public void test3(){
User user = userDao.findUserAndOrderById(1l);
System.out.println(user);
}
运行结果如下图:
注意:mybatis框架的一对多查询格式:
<!--配置一对多关系映射-->
<resultMap id="xx" type="xx" autoMapping="true">
<!--user表主键映射-->
<id column="xx" property="xx"/>
<!--映射实体类中List<Order>集合使用功能Collection标签-->
<collection property="xxx" javaType="list" ofType="xxx" autoMapping="true">
<!--主键映射-->
<id column="xx" property="xx"/>
<result column="xx" property="xx"/>
</collection>
</resultMap>
码字不易,喜欢的朋友麻烦点个赞吧!
最后
以上就是炙热黄豆为你收集整理的mybatis高级查询——基于xml配置(详细介绍)一、准备工作二、一对一查询三、一对多查询的全部内容,希望文章能够帮你解决mybatis高级查询——基于xml配置(详细介绍)一、准备工作二、一对一查询三、一对多查询所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复