Select
别名不对应时的字段映射
<!-
-resultMap定义映射关系,将属性名与字段名不同的字段创建映射
属性:
id 映射的标识,必须唯一
type 对应实体类的名字
子标签:
result 每个定义一个字段与属性对应关系
column:字段名
property:属性名
查询结果将不写成resultType,而是写成resultMap
-->
<resultMap id="brandMap" type="Brand">
<result column="brand_name" property="brandName"/>
<result column="company_name" property="companyName"/>
</resultMap>
<select id="findAll" resultMap="brandMap">
select * from tb_brand
</select>
一对一映射
<!--
创建映射: user表, 它是主映射
id: 映射名称, 自定义, 唯一即可
type:封装映射结果的实体类, 此处指定封装映射结果的user实体类
autoMapping = true: 开启自动映射, 若数据库字段名与实体类中的属性名不对应, 则需要单独指定映射关系
-->
<resultMap id="userMap" type="user" autoMapping="true">
<!--主键映射
id: 映射主键
result: 映射其它属性, 此处开启了自动映射, 所以不需要手动映射其它字段对应的属性名称之间的关系
-->
<id column="id" property="id"/>
<!--
定义映射关系, user表映射userInfo表, 它是从映射
association:一对一的映射关系
property 另一方的实体类的属性名
resultMap: 另一方映射的名字
-->
<association property="userInfo" resultMap="userInfoMap"/>
</resultMap>
<!--
创建userInfo表的映射, 它是从映射
id: user 映射 userInfo时, 定义在association标签中resultMap属性的值
type: 封装映射结果的实体类, 此处指定封装映射结果的userInfo实体类
autoMapping = true: 开启自动映射, 若数据库字段名与实体类中的属性名不对应, 则需要单独指定映射关系
-->
<resultMap id="userInfoMap" type="userInfo" autoMapping="true"/>
<!--
resultMap: 主映射的id值, 它会将查询后的结果值, 根据resultMap的映射关系封装结果
此处根据用户ID查询用户的详细信息, 结果是查询出用户表中用户对应的所有信息, 以及用户对应的详细信息
用户的信息会封装到User实体类中, 对应主映射, 用户的详细信息会封装到UserInfo实体类中, 对应从映射
-->
<select id="findUserAndInfo" resultMap="userMap">
SELECT *
FROM `user` u
INNER JOIN user_info i ON u.id = i.id
WHERE u.id = #{uid}
</select>
一对多映射
<!--
创建映射: user表, 它是主映射
id: 映射名称, 自定义, 唯一即可
type:封装映射结果的实体类, 此处指定封装映射结果的user实体类
autoMapping = true: 开启自动映射, 若数据库字段名与实体类中的属性名不对应, 则需要单独指定映射关系
-->
<resultMap id="userMap" type="user" autoMapping="true">
<!--主键映射-->
<id column="id" property="id"/>
<!--
定义一对多关系映射: user表映射order表, 它是从映射
collection标签: 定义一对多关系的映射
property: 指定另外一方属性的名称
resultMap: 另一方映射的名字
-->
<collection property="orders" resultMap="orderMap"/>
</resultMap>
<!--
创建order表的映射, 它是从映射
id: user 映射 order时, 定义在collection标签中resultMap属性的值
type: 封装映射结果的实体类, 此处指定封装映射结果的userInfo实体类
autoMapping = true: 开启自动映射, 若数据库字段名与实体类中的属性名不对应, 则需要单独指定映射关系
-->
<resultMap id="orderMap" type="orders" autoMapping="true"/>
<!--
resultMap: 主映射的id值, 它会将查询后的结果值, 根据resultMap的映射关系封装结果
此处根据用户ID查询用户的详细信息, 结果是查询出用户表中用户对应的所有信息, 以及用户对应的详细信息
用户的信息会封装到User实体类中, 对应主映射, 用户的详细信息会封装到Orders实体类中, 对应从映射
-->
<select id="findUserAndOrder" resultMap="userMap">
SELECT *
FROM `user` u
INNER JOIN order_from o ON u.id = o.user_id
WHERE u.id = #{id}
</select>
多对多映射
Entity
/**
角色实体类
*/
@Data
public class Role {
private Integer roleId;
private String roleName;
private String roleDetail;
/**
* 角色 一对多 用户
*/
private List<User> users;
}
/**
* 用户实体类
*/
@Data
public class User implements Serializable {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
/**
* 用户 一对多 角色
*/
private List<Role> roles;
/**
* 用户 一对多 订单
*/
private List<OrderForm> orders;
/**
* 用户 一对一 用户信息
*/
private UserInfo userInfo;
}
Dao
/**
通过 rid 查询指定的角色
*/
Role findRoleById(int rid);
Mapper
<!--
创建映射: user表, 它是主映射
id: 映射名称, 自定义, 唯一即可
type:封装映射结果的实体类, 此处指定封装映射结果的user实体类
autoMapping = true: 开启自动映射, 若数据库字段名与实体类中的属性名不对应, 则需要单独指定映射关系
-->
<resultMap id="userMap" type="user" autoMapping="true">
<!--主键映射-->
<id column="id" property="id"/>
</resultMap>
<!--定义角色的映射-->
<resultMap id="roleMap" type="Role" autoMapping="true">
<!--主键映射-->
<id column="role_id" property="roleId"/>
</resultMap>
<!--
定义 1 对多的映射关系,角色继承于上面的映射,避免重复映射
extends: 继承其它映射关系, 此处继承角色的映射关系
-->
<resultMap id="roleUsersMap" type="Role" extends="roleMap">
<!--
一对多的集合映射, 一个角色映射多个用户信息
resultMap: 由于extends继承了角色映射, 就说明角色是一的一方, 映射后的结果是多的一方, 也就是user, 所以collection标签中的resultMap属性值是user的映射关系的ID
property: 指定映射结果封装到实体类中的属性名
javaType: 属性的数据类型, 通常都是集合
ofType: 映射结果的实体类
-->
<collection property="users" javaType="list" ofType="User" resultMap="userMap"/>
</resultMap>
<!--
定义 1 对多的映射关系,角色继承于上面的映射,避免重复映射
extends: 继承其它映射关系, 此处继承用户的映射关系
-->
<resultMap id="userRolesMap" type="User" extends="userMap">
<collection property="roles" javaType="list" ofType="Role" resultMap="roleMap"/>
</resultMap>
<!--映射结果为 roleUsersMap 角色信息结果封装到Role实体类基础属性中, 用户信息结果封装到Role实体类中的users属性中-->
<select id="findRoleById" parameterType="int" resultMap="roleUsersMap">
select u.*, r.*
from user u
inner join user_role ur on u.id = ur.user_id
inner join role r on ur.role_id = r.role_id
where r.role_id = #{rid}
</select>
<!--映射结果为 userRolesMap 用户信息结果封装到User实体类基础属性中, 角色信息结果封装到User实体类中的roles属性中-->
<select id="findUserById" parameterType="int" resultMap="userRolesMap">
select u.*,
r.*
from role r
inner join user_role ur
on r.id = ur.role_id
inner join user u
on ur.user_id = u.id
where u.id = {uid}
</select>
级联查询
一对一级联查询
<!-- 创建映射,实现级联查询 -->
<resultMap id="userMap" type="user">
<!--主键映射-->
<id column="id" property="id"/>
<!--
一对一关联
association: 指定一对一关系
property: 指定另一方属性名
select:下一条SQL语句方法名字
column: 方法的参数从哪个字段中获取
-->
<association property="userInfo" select="findInfoById" column="id"/>
<!--
一对多关联
property: 指定另一方属性名
select:下一条SQL语句方法名字
column: 方法的参数从哪个字段中获取
-->
<collection property="orders" select="findOrdersByUserId" column="id"/>
</resultMap>
<!-- 查询1号用户基本信息 -->
<select id="findById" resultMap="userMap">
SELECT * FROM USER WHERE id=#{id}
</select>
<!-- 通过id查询用户详情 -->
<select id="findInfoById" resultType="com.itheima.entity.UserInfo">
SELECT * FROM user_info WHERE id=#{id}
</select>
一对多级联查询
<!-- 创建映射,实现级联查询 -->
<resultMap id="userMap" type="user">
<!--主键映射-->
<id column="id" property="id"/>
<!--
一对多关联
property: 指定另一方属性名
select:下一条SQL语句方法名字
column: 方法的参数从哪个字段中获取
-->
<collection property="orders" select="findOrdersByUserId" column="id"/>
</resultMap>
<!-- 查询1号用户基本信息 -->
<select id="findById" resultMap="userMap">
SELECT * FROM USER WHERE id=#{id}
</select>
<!-- 通过id查询用户详情 -->
<select id="findInfoById" resultType="com.itheima.entity.UserInfo">
SELECT * FROM user_info WHERE id=#{id}
</select>
模糊查询
<!--
条件查询: #{变量名} 与 @Param("变量名") 要一致
if 判断 test后面的表达式是否为真,如果为真则拼接if中间SQL语句
where作用:
1. 相当于where关键字,如果有条件才生成,没有条件不生成where
2. 去掉多余的and or 关键字
-->
<select id="selectByCondition" resultType="brand">
SELECT * FROM tb_brand
<where>
<if test="status!=null">
`status`=#{status}
</if>
<if test="companyName!=null and companyName!=''">
AND company_name LIKE "%"#{companyName}"%"
</if>
<if test="brandName!=null and brandName!=''">
AND brand_name LIKE "%"#{brandName}"%"
</if>
</where>
</select>
单条件查询
<!-- 单条件查询,多个条件中选择一个执行
choose: 类似于switch语句
when: 类似于case
otherwise: 类似于default
-->
<select id="selectByConditionSingle" resultType="brand">
SELECT * FROM tb_brand
<where>
<choose>
<when test="status!=null">
`status`=#{status}
</when>
<when test="companyName!=null and companyName!=''">
company_name LIKE "%"#{companyName}"%"
</when>
<when test="brandName!=null and brandName!=''">
brand_name LIKE "%"#{brandName}"%"
</when>
<otherwise>
id > 2
</otherwise>
</choose>
</where>
</select>
// Dao层接口
List<ItemBrandEntity> queryBrandInfoById(@Param("brandIds") List<Long> brandIds);
<!-- 根据品牌id, 查询品牌信息 -->
<select id="queryBrandInfoById" resultType="com.leyou.item.brand.entity.ItemBrandEntity">
select b.id,
b.name,
b.image,
b.letter
from tb_brand b
where b.id in
<foreach collection="brandIds" open="(" item="brandId" separator="," close=")">
#{brandId}
</foreach>
order by b.create_time desc limit 9
</select>
Insert
获取主键
<!--
添加:占位符是brand实体类中属性名字
useGeneratedKeys: true 获取新添加的主键值
keyColumn 指定表中主键的字段名
keyProperty 指定实体类中主键的属性名
-->
<insert id="add" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
insert into tb_brand values(null,#{brandName},#{companyName},#{ordered},#{description},#{status})
</insert>
批量添加
<!--新增品牌id对应的分类id到 tb_category_brand 中间表-->
<insert id="insertCategoryAndBrand">
insert into tb_category_brand
values
<foreach collection="cids" open="(" item="cid" separator="," close=")">
#{cid}, #{bid}
</foreach>
</insert>
Update
动态SQL
<!-- 修改操作
set标签:
1. 生成set关键字
2. 去掉多余的逗号, 逗号的使用场景: 有and、or 不需要逗号, 没有则需要逗号
-->
<update id="update">
update tb_brand
<set>
<if test="brandName!=null and brandName!=''">
brand_name=#{brandName},
</if>
<if test="companyName!=null and companyName!=''">
company_name=#{companyName},
</if>
<if test="ordered!=null">
ordered=#{ordered},
</if>
<if test="description!=null and description!=''">
description=#{description},
</if>
<if test="status!=null">
status=#{status}
</if>
</set>
where
id=#{id}
</update>
// Dao层接口
void updateCategoryAndBrand(@Param("cids") List<Long> cids, @Param("brandId") Long brandId);
<!-- 修改品牌分类信息到 tb_category_brand -->
<update id="updateCategoryAndBrand">
update tb_category_brand tcb
<foreach collection="cids" open="(" item="cid" separator="," close=")">
<set>
<if test="cid != null and cid > 0">
tcb.category_id = #{cid}
</if>
</set>
where tcb.brand_id = #{brandId}
</foreach>
</update>
Delete
常规
<!-- 删除一行 -->
<delete id="deleteById">
delete from tb_brand where id=#{id}
</delete>
批量删除
<!--批量删除-->
<!--
foreach用来遍历数组 或 集合
collection: 指定要遍历的数组 或 集合的名字, 这个名字是在Dao层的接口方法参数列表中用 @Param 注解指定的名称
open: 在遍历元素之前添加的字符
item: 每个遍历元素的名字, 名字自定义
separator: 指定每次循环结束后的分隔符
close: 整个集合遍历结束后添加的字符
-->
<delete id = "deleteById">
delete from tb_order where id in
<foreach collection = "lise" open = "(" item = "id" separator = "," close = ")">
#{id}
</foreach>
</delete>