【 SQL映射】映射元素、一对一(association)、一对多(collection)

SQL映射文件

SQL映射文件的几个顶级元素

  • mapper – namespace
  • cache – 配置给定命名空间的缓存
  • cache-ref – 从其他命名空间引用缓存配置
  • resultMap –用来描述数据库结果集和对象的对应关系
  • sql – 可以重用的SQL块,也可以被其他语句引用
  • insert – 映射插入语句
  • update – 映射更新语句
  • delete – 映射删除语句
  • select – 映射查询语句
mapper元素:
  • namespace:命名空间
    • namespace和子元素的id联合保证唯一,区别不同的mapper
    • 绑定DAO接口
      • namespace的命名必须跟某个接口同名
      • 接口中的方法问映射文件中SQL语句id相对应
<mapper namespace="cn.smbms.dao.user.UserMapper">
	<select id="getUserList" …
		……
	</select>
</mapper>
select元素:

select语句有很多属性可以详细配置每一条语句

  • id

    • 命名空间中唯一的标识符
    • 接口中的方法与映射文件中的SQL语句id相对应
  • parameterType

    • 传入SQL语句的参数类型
      • 基础数据类型:int、String、Date等。只能传入一个,通过#{参数名}即可获取传入的值
      • 复杂的数据类型:Java实体类、Map等,通过#{属性名}或者{map的keyName}即可获取传入值
  • resultType

    • SQL语句返回值类型的完整类名或别名
  • resultMap:数据库字段信息与对象属性不一致;复杂的联合查询

    • resultMap自动映射匹配前提:字段名column与属性名property一致

    • resultMap的自动映射级别(autoMappingBehavior)三个匹配级别:

      PARTIAL(默认):自动匹配所有属性,内部嵌套除外

      NONE:禁止自动匹配

      FULL:自动匹配所有

    <settings>
    	<setting  name="autoMappingBehavior" value="NONE"/>
    </settings>
    

resultMap与resultTypeu二者不能同时存在,本质上都是Map数据结构

select小结:
属性描述
id在命名空间中唯一的标识符,可以被用来引用这条语句
parameterType将会传入这条语句的参数类的完全限定名或别名
resultType从这条语句中返回的期望类型的类的完全限定名或别名。注意集合情形,那应该是集合可以包含的类型,而不能是集合本身。使用resultType或resultMap,但不能同时使用
resultMap命名引用外部的resultMap
flushCache将其设置为true,不论语句什么时候被调用,都会导致缓存被清空。默认值:false
useCache将其设置为true,将会导致本条语句的结果被缓存。默认值:true
timeout这个设置驱动程序等待数据库返回请求结果,并抛出异常时间的最大等待值。默认不设置(驱动自行处理)
fetchSize这是暗示驱动程序每次批量返回的结果行数
statementTypeSTATEMENT,PREPARED或CALLABLE的一种。让MyBatis选择使用Statement,PreparedStatement或CallableStatement。默认值:PREPARED
resultSetTypeFORWARD_ONLY|SCROLL_SENSITIVE|SCROLL_INSENSITIVE中的一种。默认是不设置(驱动自行处理)
insert元素:
<insert  id="add" parameterType="User" >
	 insert into  smbms_user (userCode,userName,userPassword) 
			values ( #{userCode},#{userName},#{userPassword})
</insert>

注意:insert、update、delete元素均没有resultType属性

update元素:
<update id ="modify" parameterType="User">
	update smbms_user 
    set userCode = #{userCode},
        userName = #{userName},
        userPassword = #{userPassword} 
    where id = #{id}
</update>
delete元素:
<delete id ="deleteUserById" parameterType="int">
	delete from smbms_user where id = #{id}
</delete>
增删改查小结:
  • DAO层接口方法常见的返回类型

    • Java对象、Map、List等复杂数据类型

    • int:(增删改)更新操作时,影响的数据行数

  • MyBatis参数入参

    • @Param注解参数
    • 封装成对象入参
resultMap:

resultMap属性

  • id:resultMap的唯一标识
  • type:java实体类

resultMap子元素

  • id:一般对应数据库中该行的主键id,设置此项可提高MyBatis性能

  • result:映射到JavaBean的某个“简单类型”属性

  • association:映射到JavaBean的某个“复杂类型”属性,比如JavaBean类

    • 复杂的类型关联,一对一

    • 内部嵌套:映射一个嵌套JavaBean属性

    • 属性:

      • property:映射数据库列的实体对象的属性

      • javaType:完整Java类名或者别名

      • resultMap:引用外部resultMap

    • 子元素:

      • id

      • result:property、column

  • collection:映射到JavaBean的某个“复杂类型”属性,比如集合

    • 复杂类型集合,一对多
    • 内部嵌套:映射一个嵌套结果集到一个列表
    • 属性………………(内容同association)
一对一association:

一个订单对应一个用户

//接口:
public User  findAll();

在这里插入图片描述
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5wJPl1Ve-1666616912578)(F:\AAAAAAAANEW\Typora-user-images\1666616859286.png)]
另一种联表的配置association:
在这里插入图片描述
在这里插入图片描述

一对多collection

一个用户会有多个订单List

//接口:
public List<User> findAll();

实体类User中:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

完整范例(整个项目资源代码太多了,主要的就在下面了)

实体类:User中有角色Id连接角色表(一个用户一个地址);有用户Id连接地址表(一个用户多个收获地址)

……
	private Role role;   //Role整个类封装,一对一
	private List<Address> addressList;   //Address的封装,一对多

dao:


   public User findUserById(Integer id);

   public User findAddressListUser(Integer id);

Mapper.xml

 <!--一对一-->
    <resultMap id="UserMap" type="User">
        <id property="id" column="id"></id>
        <result property="userName" column="userName"></result>
        <result property="userPassword" column="userPassword"></result>
        <association property="role" javaType="Role">
            <id property="id" column="id"></id>
            <result property="roleName" column="roleName"></result>
        </association>
    </resultMap>
    <select id="findUserById" resultMap="UserMap">
        select a.id, userName, userPassword, b.roleName
        from smbms_user a LEFT JOIN smbms_role b ON a.userRole = b.id
        where a.id=#{id}
    </select>

 <!--一对多-->
    <resultMap id="UserAddress" type="User">
        <id property="id" column="id"></id>
        <result property="userName" column="userName"></result>
        <result property="userPassword" column="userPassword"></result>
        <collection property="addressList" ofType="Address">
            <id property="id" column="addrid"></id>
            <result property="addressDesc" column="addressDesc"></result>
            <result property="contact" column="contact"></result>
        </collection>
    </resultMap>
    <select id="findAddressListUser" resultMap="UserAddress">
        select a.id, userName, d.id as addrid, d.addressDesc, d.contact
        from smbms_user a LEFT JOIN smbms_address d ON a.id = d.userId
        where a.id=#{id}
    </select>

测试类:

    @Test
    public void findUserById() {
        SqlSession sqlSession = MyBatisUtil.createSqlSession();
        UserDao userDao = sqlSession.getMapper(UserDao.class);

        User user = userDao.findUserById(1);
        System.out.println("输出=====================");
        System.out.println("用户名:\t\t用户密码:\t用户角色:\t");
        System.out.println(user.getUserName()+"\t"+user.getUserPassword()+"\t\t"+user.getRole().getRoleName());
        MyBatisUtil.closeSqlSession(sqlSession);
    }

    @Test
    public void findAddressListUser() {
        SqlSession sqlSession = MyBatisUtil.createSqlSession();
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        User user = userDao.findAddressListUser(1);
        for(Address address : user.getAddressList()) {
            System.out.println("该用户的地址有:"+address.getAddressDesc());
        }
        MyBatisUtil.closeSqlSession(sqlSession);
    }

`

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
在mapper中进行一对多和多对多的SQL映射,可以使用MyBatis的关联查询功能。 一对多查询可以使用MyBatiscollection标签,示例代码如下: ``` <select id="selectOrderAndOrderDetailByOrderId" resultMap="orderDetailResultMap"> SELECT * FROM orders WHERE order_id = #{orderId} </select> <resultMap id="orderDetailResultMap" type="Order"> <id property="id" column="order_id"/> <result property="orderNo" column="order_no"/> <collection property="orderDetails" ofType="OrderDetail"> <id property="id" column="detail_id"/> <result property="productName" column="product_name"/> <result property="productPrice" column="product_price"/> </collection> </resultMap> ``` 多对多查询可以使用MyBatis的association标签,示例代码如下: ``` <select id="selectUserAndRoleByUserId" resultMap="userResultMap"> SELECT * FROM user WHERE user_id = #{userId} </select> <resultMap id="userResultMap" type="User"> <id property="id" column="user_id"/> <result property="username" column="username"/> <association property="roles" column="role_id" javaType="java.util.List" select="selectRoleByUserId"/> </resultMap> <select id="selectRoleByUserId" resultMap="roleResultMap"> SELECT r.* FROM user_role ur JOIN role r ON ur.role_id = r.role_id WHERE ur.user_id = #{userId} </select> <resultMap id="roleResultMap" type="Role"> <id property="id" column="role_id"/> <result property="name" column="role_name"/> </resultMap> ``` 以上示例代码仅供参考,具体的SQL语句和映射配置需要根据实际需求进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

朱尔斯Jules

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值