我是靠谱客的博主 俊秀月饼,最近开发中收集的这篇文章主要介绍2021/9/27Mybatis(配置文件详解,多对一,一对多)4.API详解5. 关联查询:一对多,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

2021/9/27,经过一天的学习我们终于学习一对多和多对一,但是我感觉不够,还不能应对所有问题,可以再去网上找找例题看看。

4.API详解

4.1 核心配置文件详解

​ 在实际开发中,开发者会事先准备好配置文件模板,然后把模板Copy到项目中,再去修改重要的配置参数即可。这样开发者就无需把配置文件的结构背下来。但是开发者还是需要能够读懂配置文件的。下面我们来学习MyBatis核心配置文件。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TZ4Ky3ef-1632701639077)(assets/image-20210720181532001.png)]

4.1.1 根标签:<configuration>

  • 配置子标签时,多个标签之间有先后顺序,使用时一定要注意。

  • 如下就是常用4个标签的使用顺序:

    <?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>
    	<properties></properties>
    	
    	<typeAliases></typeAliases>
    
    	<environments></environments>
    
    	<mappers></mappers>
    </configuration>
    
  • 常见子标签介绍

标签名称描述
properties属性配置,也可引入外部properties文件
settings系统参数配置,所有参数都有默认值,通常不用配置
typeAliases类型别名,简化开发,仅减少类完全限定名的冗余。用于xml开发。
plugins插件,用于添加扩展功能。
environments环境配置,提供给factory配置信息
mappers映射器,确定SQL语句的位置

4.1.2 属性:<properties>

​ 将易于修改的配置内容抽取到properties中,方便统一管理。mybatis提供两种方式来维护properties:property标签和properties配置文件。

方式1:property标签
  • 1)配置:将需要的内容配置在 <property name="标识" value="值"/>

    <properties>
    	<property name="jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
    	<property name="jdbc.url" value="jdbc:mysql://localhost:3306/ssm_db1"/>
    	<property name="jdbc.username" value="root"/>
    	<property name="jdbc.password" value="1234"/>
    </properties>
    
  • 2)使用:在配置文件的其他位置,通过 ${标识} 方式获得内容

    <!-- 使用连接池 -->
    <dataSource type="POOLED">
    	<!-- 数据库连接基本信息 -->
    	<property name="driver" value="${jdbc.driver}"/>
    	<property name="url" value="${jdbc.url}"/>
    	<property name="username" value="${jdbc.username}"/>
    	<property name="password" value="${jdbc.password}"/>
    </dataSource>
    
  • 整体示意图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qmkab9xV-1632701639081)(assets/image-20210720183034856.png)]

方式2:properties配置文件

​ 在实际开发中,我们常见数据库的配置信息存放到properties文件,mybatis也提供了对配置文件的支持。

  • 1)添加 db.properties配置文件

    jdbc.driver=com.mysql.cj.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/ssm_db1
    jdbc.username=root
    jdbc.password=1234
    
  • 2)加载properties文件,修改核心配置文件

    <properties resource="db.properties" />
    
  • 整体示意图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v4uKekN7-1632701639083)(assets/image-20210720183406195.png)]

注意事项
  • properties配置文件加载的内容,将覆盖<property>标签配置的内容。
    • 先加载<property>标签配置的内容
    • 再加载 resource指定的properties配置文件配置的内容,也就是后者覆盖了前者。
<!--最后url的值为 db.properties配置的内容 -->
<properties resource="db.properties" >
	<property name="jdbc.url" value="jdbc:mysql://localhost:3306/ssm_db2"/>
</properties>

<!-- 【开发中不建议混搭使用】 -->

4.1.3 设置:<settings>

  • mybatis框架系统配置settings,用于改变 MyBatis 的运行时行为。

  • mybatis提供可多种设置,用于系统的优化。

设置参数描述有效值默认值
mapUnderscoreToCamelCase是否开启自动驼峰命名规则映射, 即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。true | falsefalse
autoMappingBehavior指定 MyBatis 是否以及如何自动映射指定的列到字段或属性。 NONE 表示取消自动映射; PARTIAL 只会自动映射没有定义嵌套结果集映射的结果集。 FULL 会自动映射任意复杂的结果集NONE, PARTIAL, FULLPARTIAL
useGeneratedKeys允许 JDBC 支持自动生成主键,需要驱动兼容。true | falsefalse
useColumnLabel使用列标签代替列名。true | falsetrue
cacheEnabled该配置影响的所有映射器中配置的缓存的全局开关。true | falsetrue
lazyLoadingEnabled延迟加载的全局开关。true | falsefalse
  • 驼峰命名设置
	<settings>
		<!-- java对象属性驼峰,对应数据的下划线 -->
		<setting name="mapUnderscoreToCamelCase" value="true"/>
	</settings>

4.1.4 环境:<environments>

  • MyBatis通过环境environments来配置数据库的连接和事务管理。

  • 确定使用哪个配置

    <!--
    	default用于确定当前环境使用哪个配置
    	<environment id=””>用于提供一套配置方案,id的值提供给default使用。
    -->
    <environments default="配置2">
    	<environment id="配置1">
    	</environment>
    	
    	<environment id="配置2">
    	</environment>
    </environments>
    
  • 配置内容

    <!--
    	<transactionManager> 用于配置事务管理方案
    		type:用于确定管理事务具体方案,取值:JDBC、MANAGED
    			JDBC,jdbc底层事务管理,commit提交,rollback回顾。
    			MANAGED,交予其他框架管理,自己不做事务操作,仅关闭连接。
    	<dataSource>用于配置连接池(多个连接的池子)
    		type:用于确定管理连接的方案,取值:POOLED、UNPOOLED、JNDI
    			POOLED:通过连接池,管理连接创建和销毁。
    			UNPOOLED:不使用连接池,每一次都创建和销毁连接。
    			JNDI:将连接池存放到JNDI中。
    -->
    <environment id="development">
    	<!-- 使用jdbc管理事务 -->
    	<transactionManager type="JDBC"></transactionManager>
    	<!-- 配置数据源(配置连接) -->
    	<dataSource type="POOLED">
    		<property name="driver" value="${jdbc.driver}"/>
    		<property name="url" value="${jdbc.url}"/>
    		<property name="username" value="${jdbc.username}"/>
    		<property name="password" value="${jdbc.password}"/>
    	</dataSource>
    </environment>
    
    
  • 扩展(查看源码,可以确定 type 配置内容)

    1. 事务的配置项

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BX8QSZ8D-1632701639085)(assets/image-20210720184221903.png)]

    2. 连接池的配置项

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wlv4TI6V-1632701639086)(assets/image-20210720184235536.png)]

    3. MANAGED 不管事务,只关闭连接

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J6RUyNJc-1632701639087)(assets/image-20210720184248418.png)]

4.1.5 映射器:<mappers>

  • 加载指定包package所有的接口。

    <!-- 映射文件 -->
    <mappers>
    	<package name="com.czxy.ssm.mapper"/>
    </mappers>
    

4.2 输入:vo 条件查询

​ 在开发中,一个对象的查询条件,比对象中封装的属性更多。例如:user有birthday,我们需要查询2010-2020年的数据,时间段beginTime、endTime在User对象中就没有提供属性,实际开发中,一般提供一个自定义对象,例如:UserVo。

  • 1)编写vo

    package com.czxy.ssm.vo;
    
    /**
     * @author 桐叔
     * @email liangtong@itcast.cn
     */
    public class UserVo {
        private String beginTime;       // 开始时间
        private String endTime;         // 结束时间
    
        public UserVo() {
        }
    
        public UserVo(String beginTime, String endTime) {
            this.beginTime = beginTime;
            this.endTime = endTime;
        }
    
        public String getBeginTime() {
            return beginTime;
        }
    
        public void setBeginTime(String beginTime) {
            this.beginTime = beginTime;
        }
    
        public String getEndTime() {
            return endTime;
        }
    
        public void setEndTime(String endTime) {
            this.endTime = endTime;
        }
    }
    
    
  • 2)修改Mapper,添加 condition 方法

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7TH7vNKn-1632701639087)(assets/image-20210721100334133.png)]

        /**
         * 条件查询
         * @param userVo
         * @return
         */
        @Select("select * from user where birthday >= #{beginTime} and birthday <= #{endTime}")
        public List<User> condition(UserVo userVo);
    
  • 3)测试类

    package com.czxy.ssm.test;
    
    import com.czxy.ssm.domain.User;
    import com.czxy.ssm.mapper.UserMapper;
    import com.czxy.ssm.utils.MyBatisUtils;
    import com.czxy.ssm.vo.UserVo;
    
    import java.util.Date;
    import java.util.List;
    
    /**
     * @author 桐叔
     * @email liangtong@itcast.cn
     */
    public class Test07_Condition {
        public static void main(String[] args) {
            UserMapper userMapper = MyBatisUtils.getMapper(UserMapper.class);
    
            List<User> list = userMapper.condition(new UserVo("2010-01-01", "2021-01-01"));
            // 打印
            list.forEach(user -> {
                System.out.println(user);
            });
    
            MyBatisUtils.commitAndclose();
        }
    }
    
    

4.3 输出:结果集映射Result

实际开发中,如果数据库字段和Java对象字段不能对应,就需要我们编写对应关系。

注解描述
@Results对象和表的映射关系。
@Result一个对象属性和一个表的字段的映射关系。
@ResultMap映射关系,使用@Results声明的映射关系。

4.3.1 基本使用

  • 语法
/** 
	@Results(value = 一组Result )
*/    
@Results(value = {
     @Result(property = "属性名", column = "字段名", id = true),
     @Result(property = "属性名2", column = "字段名2"),
     @Result(property = "属性名3", column = "字段名3")
})
  • 基本使用
    /**
     * 查询所有
     * @return
     */
    @Select("select * from user")
    @Results({
            @Result(property = "uid", column = "uid", id = true),
            @Result(property = "username", column = "username"),
            @Result(property = "password", column = "password")
    })
    public List<User> selectAll();

4.3.2 重复使用

  • 语法

    @Select(...)
    @Results(id = "标识", value = {...})
    public 返回值 方法名();
    
    @Select(...)
    @ResultMap("标识")
    public 返回值 方法名2();
    
  • 使用

        /**
         * 查询所有
         * @return
         */
        @Select("select * from user")
        @Results(id = "userResult", value = {
                @Result(property = "uid", column = "uid", id = true),
                @Result(property = "username", column = "username"),
                @Result(property = "password", column = "password")
        })
        public List<User> selectAll();
    
        /**
         * 通过id查询详情
         * @param uid
         * @return
         */
        @Select("select * from user where uid = #{uid}")
        @ResultMap("userResult")
        public User selectById(@Param("uid") String uid);
    

4.4 已有注解总结

注解名称描述
@Insert添加sql
@Update更新sql
@Delete删除sql
@Select查询sql
@Param形参命名
@Results对象和表的映射关系。
@Result一个对象属性和一个表的字段的映射关系。

5. 关联查询:一对多

5.1 用户和订单数据模型

5.1.1 表关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yJHnKCMe-1632701711116)(assets/image-20210721112640991.png)]

CREATE TABLE `orders` (
  `oid` VARCHAR(32) PRIMARY KEY NOT NULL,
  `ordertime` DATETIME DEFAULT NULL,		#下单时间
  `total_price` DOUBLE DEFAULT NULL,		#总价
  `state` INT(11) DEFAULT NULL,			#订单状态:1=未付款;2=已付款,未发货;3=已发货,没收货;4=收货,订单结束
  `address` VARCHAR(30) DEFAULT NULL,		#收获地址
  `name` VARCHAR(20) DEFAULT NULL,		#收获人
  `telephone` VARCHAR(20) DEFAULT NULL,		#收货人电话
  `uid` VARCHAR(32) DEFAULT NULL,
  CONSTRAINT `order_fk_0001` FOREIGN KEY (`uid`) REFERENCES `user` (`uid`)
) ;

INSERT INTO `orders` VALUES ('x001','2010-10-10',10,1,'江苏','张三','12345','u001');
INSERT INTO `orders` VALUES ('x002','2010-11-11',20,2,'河北','李四','67890','u001');
INSERT INTO `orders` VALUES ('x003','2011-10-10',30,3,'山西','王五','66666','u002')

5.1.2 JavaBean

  • 默认情况下,两个JavaBean没有关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pL7hd4KO-1632701711118)(assets/image-20210721114058980.png)]

package com.czxy.ssm.domain;

import java.util.Date;

/**
 *
 Create Table

 CREATE TABLE `orders` (
 `oid` varchar(32) NOT NULL,
 `ordertime` datetime DEFAULT NULL,
 `total` double DEFAULT NULL,
 `state` int(11) DEFAULT NULL,
 `address` varchar(30) DEFAULT NULL,
 `name` varchar(20) DEFAULT NULL,
 `telephone` varchar(20) DEFAULT NULL,
 `uid` varchar(32) DEFAULT NULL,
 PRIMARY KEY (`oid`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8

 */
public class Order {

	private String oid; 		// 订单编号
	private Date ordertime; 	// 下单时间
	private Double total; 		// 订单总金额
	private Integer state; 		// 订单状态 0 未支付 1 已支付 2已发货 3已收货
	private String address;		// 收货人地址
	private String name;		// 收货人姓名
	private String telephone;	// 收货人电话
	private String uid;

	@Override
	public String toString() {
		return "Order{" +
				"oid='" + oid + ''' +
				", ordertime=" + ordertime +
				", total=" + total +
				", state=" + state +
				", address='" + address + ''' +
				", name='" + name + ''' +
				", telephone='" + telephone + ''' +
				", uid='" + uid + ''' +
				'}';
	}

	public String getOid() {
		return oid;
	}

	public void setOid(String oid) {
		this.oid = oid;
	}

	public Date getOrdertime() {
		return ordertime;
	}

	public void setOrdertime(Date ordertime) {
		this.ordertime = ordertime;
	}

	public Double getTotal() {
		return total;
	}

	public void setTotal(Double total) {
		this.total = total;
	}

	public Integer getState() {
		return state;
	}

	public void setState(Integer state) {
		this.state = state;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getTelephone() {
		return telephone;
	}

	public void setTelephone(String telephone) {
		this.telephone = telephone;
	}

	public String getUid() {
		return uid;
	}

	public void setUid(String uid) {
		this.uid = uid;
	}


	public Order(String oid, Date ordertime, Double total, Integer state, String address, String name, String telephone, String uid) {
		this.oid = oid;
		this.ordertime = ordertime;
		this.total = total;
		this.state = state;
		this.address = address;
		this.name = name;
		this.telephone = telephone;
		this.uid = uid;
	}

	public Order() {

	}
}

5.1.3 JavaBean关系

  • 以对象的方法,描述两个JavaBean之间的关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rNX1oss6-1632701711120)(assets/image-20210721114451321.png)]

  • JavaBean:User

    public class User {
    
    	private String uid;
    	private String username;
    	private String password;
    	private String name;
    	private String email;
    	private Date birthday;
    	private String sex;
    	private Integer state;
    	private String code;
    	// 一对多:一个用户 拥有【多个用户】
    	private List<Order> orderList = new ArrayList<>();
        // ...
    }
    
  • JavaBean:Order

    public class Order {
    
    	private String oid; 		// 订单编号
    	private Date ordertime; 	// 下单时间
    	private Double total; 		// 订单总金额
    	private Integer state; 		// 订单状态 0 未支付 1 已支付 2已发货 3已收货
    	private String address;		// 收货人地址
    	private String name;		// 收货人姓名
    	private String telephone;	// 收货人电话
    	private String uid;
    	// 多对一, 多个订单 属于 【一个用户】
    	private User user;
        // ...
    }
    

5.2 一对多

5.2.1 语法

在Mybatis注解开发中,需要通过@Result进行关联关系的描述。

  • 一对多:需要使用many属性和@Many注解。
@Result(
    property = "1表JavaBean属性名", 
    column = "1表字段名",
    many = @Many(select = "多表Mapper的方法签名")
)

5.2.2 需求&分析

  • 需求:查询用户的同时,查询每个用户对应的订单
  • 分析:
    • 修改OrderMapper,完成通过uid查询所有的订单
    • 修改UserMapper,完成查询用户信息时,查询对应的订单

5.2.3 订单功能:通过uid查询所有的订单

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zYuBryue-1632701711122)(assets/image-20210721115807048.png)]

package com.czxy.ssm.mapper;

import com.czxy.ssm.domain.Order;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

/**
 * @author 桐叔
 * @email liangtong@itcast.cn
 */
public interface OrderMapper {

    /**
     * 通过id查询详情
     * @param uid
     * @return
     */
    @Select("select * from orders where uid = #{uid}")
    public Order findOrdersByUserId(@Param("uid") String uid) ;

}

5.2.4 用户功能:关联查询

public interface UserMapper {
    /**
     * 查询所有
     * @return
     */
    @Select("select * from user")
    @Results(id = "userResult", value = {
            @Result(property = "uid", column = "uid", id = true),
            @Result(property = "username", column = "username"),
            @Result(property = "password", column = "password"),
            @Result(property="orderList" , many=@Many(select="com.czxy.ssm.mapper.OrderMapper.findOrdersByUserId"), column="uid")
    })
    public List<User> selectAll();

}

5.3 多对一

5.3.1 语法

在Mybatis注解开发中,需要通过@Result进行关联关系的描述。

  • 多对一:需要使用one属性和@One注解
@Result(
    property = "多表JavaBean属性名", 
    column = "多表字段名",
    one = @One(select ="1表Mapper的方法签名")
)

5.3.2 需求&分析

  • 需求:查询订单时,查询关联的用户信息

  • 分析:

    1)通过user_id查询用户详情

    2)通过id查询订单详情

5.4.3 用户功能:通过id查询用户详情(已有)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5WhyL14U-1632701711122)(assets/image-20210721143850814.png)]

    /**
     * 通过id查询详情
     * @param uid
     * @return
     */
    @Select("select * from user where uid = #{uid}")
    @ResultMap("userResult")
    public User selectById(@Param("uid") String uid);

5.4.4 订单功能:通过id查询订单详情

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2sQCw3Fd-1632701711123)(assets/image-20210721143730694.png)]

    /**
     *
     * @param id
     * @return
     */
    @Select("select * from orders where oid = #{oid}")
    @Results({
            @Result(property="oid" , column="oid"),
            @Result(property="ordertime" , column="ordertime"),
            @Result(property="total" , column="total"),
            @Result(property="state" , column="state"),
            @Result(property="address" , column="address"),
            @Result(property="name" , column="name"),
            @Result(property="telephone" , column="telephone"),
            @Result(property="uid" , column="uid"),
            @Result(property="user" , one=@One(select="com.czxy.ssm.mapper.UserMapper.selectById") , column="uid"),
    })

    public Order selectById(@Param("oid") String id);

总结:
我觉得一对多很好理解就是正常的一个与多个有联系,
而多对一我觉得可以拆开成,多个平行关系的一对一,比如老师和学生,老师对学生是一对多,而学生对老师是多个学生级别的一对一。

问题不大离工作又近了一天

最后

以上就是俊秀月饼为你收集整理的2021/9/27Mybatis(配置文件详解,多对一,一对多)4.API详解5. 关联查询:一对多的全部内容,希望文章能够帮你解决2021/9/27Mybatis(配置文件详解,多对一,一对多)4.API详解5. 关联查询:一对多所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(39)

评论列表共有 0 条评论

立即
投稿
返回
顶部