一.Mapper接口动态代理规范
1). namespace必须是Mapper接口的全限定名(带包名)
2). 配置的id(statement的id)必须是接口方法的方法名
3). parameterType必须和接口方法的参数类型一致
4). resultType必须和接口方法的返回值类型一致
二.Mapper映射文件相关
1.动态sql之
1).if标签<!-- 根据用户名和性别查询用户(动态sql之if标签) --> <!-- if标签:进行条件的判断,在test中编写判断的语句. --> <!-- 如果为true,标签内的sql会执行(最终的sql就有这个部分),如果为false就不会执行这个sql(最终的sql就没有这个部分) --> <select id="queryUserByUsernameAndSex" parameterType="user" resultType="user"> <!-- include标签:把提取的sql片段进行引用,refid就是引用片段的id --> SELECT <include refid="fields" /> FROM `user` <!-- where标签的作用:1.能自动添加where关键词;2.能自动处理where关键词后面的第一个and --> <where> <if test="username != null and username != ''"> AND username LIKE #{username} </if> <if test="sex != null and sex != ''"> AND sex = #{sex} </if> </where> </select>
2). foreach标签
<!-- 根据用户名和性别查询用户(动态sql之if标签) --> <!-- if标签:进行条件的判断,在test中编写判断的语句. --> <!-- 如果为true,标签内的sql会执行(最终的sql就有这个部分),如果为false就不会执行这个sql(最终的sql就没有这个部分) --> <select id="queryUserByUsernameAndSex" parameterType="user" resultType="user"> <!-- include标签:把提取的sql片段进行引用,refid就是引用片段的id --> SELECT <include refid="fields" /> FROM `user` <!-- where标签的作用:1.能自动添加where关键词;2.能自动处理where关键词后面的第一个and --> <where> <if test="username != null and username != ''"> AND username LIKE #{username} </if> <if test="sex != null and sex != ''"> AND sex = #{sex} </if> </where> </select>
3).selectKey标签
<!-- 新增用户 --> <!-- selectKey:解决新增的数据主键无法返回的问题 --> <!-- select last_insert_id():获取当前事务中最后一次自增的主键,说白了,就是拿到自己的主键 --> <!-- keyColumn:数据库那一列是主键 --> <!-- keyProperty:pojo实体的哪一个属性是主键 --> <!-- resultType:查询的主键数据类型 --> <!-- order:在插入语句执行之前获取主键,还是在插入语句执行之后获取主键,本案例是之后执行查询主键,使用AFTER --> <insert id="saveUser" parameterType="com.free.pojo.User"> <selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER"> select last_insert_id() </selectKey> INSERT INTO `user` ( username, sex, birthday, address ) VALUES ( #{username}, #{sex}, #{birthday}, #{address} ) </insert>
4).resultMap标签<!-- 配置ResultMap --> <!-- type:指定最终会将结果映射到哪个pojo,需要填写全限定名(带包名),也可以使用别名 --> <!-- id:唯一标识符,也是名字 --> <resultMap type="order" id="orderRM"> <!-- id标签:配置哪个属性是主键,如果有多个主键,就配置多个id --> <!-- property:pojo的属性名,哪一个是主键 --> <!-- column:数据库字段名(列名),哪一个是主键 --> <id property="id" column="id"/> <!-- result:配置除了主键以外的属性,pojo属性名与数据库字段名相同可以省略 --> <result property="userId" column="user_id"/> <!--<result property="number" column="number"/>--> <!--<result property="createtime" column="createtime"/>--> <!--<result property="note" column="note"/>--> </resultMap> <!-- 解决属性名和字段名不一样,映射不成功,使用ResultMap --> <select id="queryOrderAll" resultMap="orderRM"> select * from `order` </select>
2.输出简单数据类型<!--查询数据库表的数据条数,输出简单数据类型 注意:输出简单类型必须是查询后的结果集只能有一条记录,最终将第一个字段的值转换为输出类型 --> <select id="queryUserCount" resultType="int"> select count(1) from `user` </select>
3.根据queryVo包装类查询数据<!--根据queryVo包装类查询数据--> <select id="queryUserByQueryVo" parameterType="queryVo" resultType="user"> select * from user where username like #{user.username} </select>
4.根据username查询用户<select id="queryUserByUsername" parameterType="string" resultType="User"> SELECT * FROM user where username LIKE #{username} </select>
5.一对一的方式(ResultType)<!-- 查询所有订单数据,包含用户数据(一对一的方式一),ResultType--> <select id="queryOrderUser" resultType="orderUser"> SELECT o.id, o.user_id userId, o.number, o.createtime, o.note, u.username, u.address FROM `order` o LEFT JOIN `user` u ON o.user_id = u.id </select>
6.一对一的方式(ResultMap)配置一对一的第一种方式
<!-- 查询所有订单数据,包含用户数据(一对一的方式一),ResultType--> <select id="queryOrderUser" resultType="orderUser"> SELECT o.id, o.user_id userId, o.number, o.createtime, o.note, u.username, u.address FROM `order` o LEFT JOIN `user` u ON o.user_id = u.id </select>
配置一对一的第二种方式
<!--查询所有订单数据,包含用户数据(一对一的方式二),使用ResultMap--> <select id="queryOrderRM" resultMap="orderUserRM"> SELECT o.id, o.user_id userId, o.number, o.createtime, o.note, u.username, u.address FROM `order` o LEFT JOIN `user` u ON o.user_id = u.id </select> <!-- 配置一对一查询的ResultMap --> <!-- 最终返回的应该是订单,所以type编写order --> <resultMap type="order" id="orderUserRM"> <!-- id配置注解 --> <id property="id" column="id"/> <!-- result配置其他属性,字段 --> <result property="userId" column="userId"/> <result property="number" column="number"/> <result property="createtime" column="createtime"/> <result property="note" column="note"/> <!-- association配置一对一的映射,这里配置user的映射 --> <!-- property:配置哪一个属性进行一对一的映射 --> <!-- javaType:配置这个属性的类型,需要填写全限定名,也可以使用别名 --> <association property="user" javaType="User"> <!-- 配置映射的pojo的主键 --> <id property="id" column="userId"/> <!-- 配置映射的pojo的主键以外的属性 --> <result property="username" column="username"/> <result property="address" column="address"/> </association> </resultMap>
7.一对多方式在一实体中配置多的一方List<Order> <!--查询所有的用户,管理订单数据(一对多),只能使用ResultMap--> <select id="queryUserOrder" resultMap="userOrderRM"> SELECT u.*, o.id oid, o.number, o.createtime, o.note FROM `user` u LEFT JOIN `order` o ON u.id = o.user_id </select> <!-- 配置一对多的ResultMap --> <resultMap type="user" id="userOrderRM"> <id property="id" column="id"/> <result property="username" column="username"/> <result property="birthday" column="birthday"/> <result property="sex" column="sex"/> <result property="address" column="address"/> <!-- collection配置一对多的关联 --> <!-- javaType:配置属性的类型,本例中使用的List集合. --> <!-- ofType:配置集合里面的元素类型 --> <collection property="orders" javaType="list" ofType="order"> <id property="id" column="oid"/> <result property="userId" column="id"/> <result property="number" column="number"/> <result property="createtime" column="createtime"/> <result property="note" column="note"/> </collection> </resultMap>