Dao层Mapper映射文件.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">
<!--namespace名称空间: 需要你配置该文件对应的是哪个接口,需要编写接口的完整类-->
<mapper namespace="com.itheima.dao.UserMapper">
<!-- id: 配置接口中对应的方法名
resultType : 方法返回的结果类型,如果是集合,我们应该编写是集合中存储的对象的完整类名。
-->
<select id="findAll" resultType="user">
select * from user
</select>
<!--
通过id查找用户
如果Dao的方法有形参,sql语句需要使用形参,我们是使用#{名字}作为参数的占位符的
*/
-->
<select id="findUserById" resultType="user">
SELECT * FROM USER WHERE id = #{id}
</select>
<!--模糊查询
注意: 如果是要拼接字符串,那么我们要求使用$符号取值,
并且如果形参是java中的八种基本数据类型与String类型,必须使用value属性名去取。
1. 使用字符串拼接符 拼接参数
2. 字符串的参数类型此处只能使用value名字
3. 模糊查询前后使用%,外面使用单引号
方式一:
select * from user where username like '%%'
方式二:
select * from user where username like #{name}
-->
<select id="findUserLikeName" resultType="User">
select * from user where username like #{name}
</select>
<!--添加用户
注意: 如果形式参数是 引用类型(除String类型以外),我们需要获取实参对象的属性值,
我们只需要 #{对象的属性名}
selectKey标签的作用就是用于查询最后一次插入数据主键值,并且把主键值封装到实参中。
useGeneratedKeys : 是否为自动生成主键
keyColumn : 指定数据库表的主键名
keyProperty : 把主键值封装到你指定的属性中
resultType="int" 主键的数据类型
order="AFTER" BEFORE: 在添加语句前执行查询主键的语句
AFTER: 在添加语句后执行查询主键的语句
<selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER">
select LAST_INSERT_ID()
</selectKey>
-->
<insert id="addUser" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
insert into user values(null,#{username},#{birthday},#{sex},#{address})
</insert>
<!--更新用户-->
<update id="updateUser">
update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id = #{id}
</update>
<!--删除用户-->
<delete id="deleteUser">
delete from user where id =#{id}
</delete>
<!--多条件查询-->
<select id="queryByCondition" resultType="user">
select * from user where username like '%${user.username}%' and birthday>=#{startTime} and birthday <=#{endTime}
</select>
<!--多个参数时候
//注意: 如果参数是多个参数的时候,需要使用@param注解去指定参数的名字
List<User> queryByCondition2(@Param("name") String username, @Param("birthday") Date birthday);
-->
<select id="queryByCondition2" resultType="user">
select * from user where username like '%${name}%' and birthday >= #{birthday}
</select>
<select id="getAmountBySex" resultType="int">
select count(*) from user where sex=#{sex}
</select>
<!-- ======================================================= 动态SQL 标签===============================================================-->
<!-- 定义一个结果映射
resultMap标签的作用:配置sql语句中字段(列)的名称与java实体类的属性名对应的关系。
id: 结果映射的唯一标记。
type: 描述的是何种数据类型
column : 数据库表中列名
property : 实体类的属性名
-->
<resultMap id="userMap" type="user">
<!-- 描述的是主键列-->
<id column="id" property="id"/>
<!--除了主键列我们是使用id标签,其他列我们都使用reuslt标签-->
<result column="user_name" property="username"/>
<result column="birthday" property="birthday"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
</resultMap>
<!--表的列名与实体类的属性名不一致 -->
<!--注意: 如果使用了ResultMap指定列名与属性名的对应关系,那么结果类型则不能再使用resultType,应该要使用ResultMap-->
<select id="findUserById2" resultMap="userMap">
select * from user where id =#{id}
</select>
<select id="findByCondition" resultType="user">
select * from user
<!--where标签的作用:
1.为sql语句添加where关键字,注意你是有条件的时候才会你添加where关键字。
2. where标签会检查你的第一个条件是否有and关键字,如果有会帮助你清除。
3. if 判断条件是否为真,如果为真 则将if中字符串写入到SQL语句中
//精 sex=null
-->
<where>
<!--注意: if标签的test属性编写属性值的时候,千万别写#之类,直接编写属性名即可-->
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
<if test="sex!=null and sex!=''">
and sex=#{sex}
</if>
</where>
</select>
<!--更新用户
User user = new User(男,“广州”)
-->
<update id="updateUser">
update user
<!-- set标签作用:
1. 根据实际情况动态添加set关键字。
2. 清除多余的逗号.
-->
<set>
<if test="username!=null and username!=''">
username=#{username},
</if>
<if test="sex!=null and sex!=''">
sex=#{sex},
</if>
<if test="address!=null and address!=''">
address=#{address},
</if>
</set>
<!-- 由于sql语句其实本质上就是做字符串的拼接的,where条件本应在最后,所以位于set语句后面。-->
where id =#{id}
</update>
<!--批量添加用户
insert into user values(null,?,?,?,?),(null,?,?,?,?),(null,?,?,?,?);
-->
<insert id="addUsers">
insert into user values
<!--
collection: 代表你要遍历的目标的名字,如果是List集合建议你们都写上list即可,如果是数组建议使用的名字是array,否则需要使用@Param指定参数的名字
// int addUsers(@Param("users") List<User> users);
item: 相当于你遍历出来的每一个对象存储的变量名。
separator : 分割符, 元素与元素之间要使用的分隔符 , user对象与user之间要使用分隔符。
-->
<foreach collection="list" item="user" separator=",">
(null,#{user.username},#{user.birthday},#{user.sex},#{user.address})
</foreach>
</insert>
<!--
目标的sql语句: delete from user where id in (?,?,?)-->
<delete id="deleteUsers">
delete from user where id in
<!--
collection: 代表你要遍历的目标的名字,如果是List集合建议你们都写上list即可,如果是数组建议使用的名字是array,
否则需要使用@Param指定参数的名字
item: 相当于你遍历出来的每一个对象存储的变量名。
separator : 分割符, 元素与元素之间要使用的分隔符 , user对象与user之间要使用分隔符。
open : 指定拼接时使用的开始字符串。
-->
<foreach collection="array" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</delete>
<!--
-->
<!--把sql语句封装起来-->
<sql id="conditionSql">
<where>
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
<if test="startTime!=null and startTime!=''">
and birthday >= #{statTime}
</if>
<if test="endTime!=null and endTime!=''">
and birthday <= #{endTime}
</if>
</where>
</sql>
<select id="findUsersByCondition" resultType="user">
select * from user
/*引入了id 为conditionSql的所有sql语句,提高sql语句的复用性*/
<include refid="conditionSql"/>
</select>
<select id="findUserCount" resultType="int">
select count(*) from user
<include refid="conditionSql"/>
</select>
<!--===========================================多表关联================================================================-->
<!--我们把用户的基本信息处理出来形成单个ResultMap,以后其他ResultMap需要使用可以直接继承。-->
<resultMap id="UserMap" type="user">
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="birthday" property="birthday"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
</resultMap>
<!-- 如果需要解决一对一关系,我们需要自定义一个resultMap指定列名与属性名的对应关系,并且要使用association标签。-->
<resultMap id="UserByInfoMap" type="user" extends="UserMap"> <!-- extends 继承另外一个ResultMap-->
<!--描述实体对象的属性
association : 标签是用于描述一对一的关系的。
javatype: 表示该属性的数据类型
resultMap: 指定另一方映射配置的id,如:用户扩展信息的映射
property: 一对一对应的另一方实体类的属性名,如:userInfo
-->
<association property="userInfo" javaType="userInfo">
<id column="id" property="id"/>
<result column="height" property="height"/>
<result column="weight" property="weight"/>
<result column="married" property="married"/>
</association>
</resultMap>
<!--一对一的关系-->
<!--
-->
<select id="findUserAndInfo" resultMap="UserByInfoMap">
SELECT * FROM USER u , user_info i WHERE i.`id` = u.`id` AND u.id=#{id}
</select>
<!--一对多的关系-->
<resultMap id="UserAndOrderMap" type="user">
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="birthday" property="birthday"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
<!--如果是描述一对多属性的关系,我们需要使用collection标签。
property: 描述名
javaType: 当前的属性类型,可以省略
ofType:代表了当前集合存储的数据类型,绝对不能省略。
-->
<collection property="orders" ofType="orderForm">
<id column="oid" property="oid"/>
<result column="user_id" property="userId"/>
<result column="number" property="number"/>
<result column="create_time" property="createTime"/>
<result column="note" property="note"/>
</collection>
</resultMap>
<select id="findUserAndOrders" resultMap="UserAndOrderMap">
SELECT * FROM USER u , order_form o WHERE u.id=o.`user_id` AND u.id=#{id}
</select>
<!--多对多的关系-->
<resultMap id="UserRolesMap" type="user" extends="UserMap">
<!-- <id column="id" property="id"/>
<result column="username" property="username"/>
<result column="birthday" property="birthday"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>-->
<collection property="roles" ofType="Role">
<id column="role_id" property="roleId"/>
<result column="role_name" property="roleName"/>
<result column="role_detail" property="roleDetail"/>
</collection>
</resultMap>
<!--多对多的关系:多对多的关系如果从单边的角度去看的时候本质上一对多关系-->
<select id="findRolesByUserId" resultMap="UserRolesMap">
SELECT * FROM USER u,user_role ur, role r WHERE u.`id`=ur.`user_id` AND ur.`role_id`=r.`role_id` AND
u.`id`=#{id};
</select>
</mapper>