目录
- MyBatis增删改查的用法
- sql映射文件
- myBatis框架的缓存
- myBatis框架的新增
- myBatis框架的更新
- myBatis框架的删除
- myBatis框架的简单查询
- MyBatis框架的结果映射
- resultType和resultMap总结
MyBatis增删改查的用法
sql映射文件
sql映射文件中的顶级元素说明
使用规则
1,sql映射文件与该mapper接口同名(实体类名+mapper),并放置在同意包路径下。
2,要以映射的mapper接口的完全限定名(包名+类名)作为namespace属性的值。
3,接口中的方法名与映射文件中sql语句映射的ID一一对应。
4,在不同的sql映射文件中,子元素的id可以相同。
myBatis框架的缓存
缓存分类
二级缓存的使用方法
1>在核心配置文件中设置全局开启二级缓存
<settings> <setting name="cacheEnabled" value="true" /> </settings>
2>根据需要在sql映射文件中配置缓存,为当前namespace启用二级缓存
<!--在mapper标签内--> <!--缓存设置--> <cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true" />
cache元素中各种属性的作用
3>在sql映射文件中配置支持二级缓存后,如需对个别查询进行调整,可在select元素中单独设置
<select id="selectAll" resultType="SysUser" useCache="true"> .... </select>
myBatis框架的新增
新增,使用insert元素来映射插入语句。
//接口中的方法 /** * 新增的方法 * @param smbmsUser smbmsUser对象 * @return 返回受影响的行数 */ int insertUserInfo(SmbmsUser smbmsUser);
<!--对应的mapper标签--> <!--属性id的值为对应的Mapper接口中的方法名 ,属性parameterType的值为此方法形参的类型 --> <insert id="insertUserInfo" parameterType="com.pojo.SmbmsUser"> <!--sql语句中 #{xxx} 中xxx均为实体类中的属性名一致--> insert into smbms_user (userName,userPassword,userCode)values (#{userName},#{userPassword},#{userCode}) </insert>
myBatis框架的更新
//接口中的方法 /** * 更新信息的方法 * @param smbmsUser smbmsUser对象 * @return 返回受影响的行数 */ int updateUserInfo(SmbmsUser smbmsUser);
<!--对应的mapper标签--> <!--属性id的值为对应的Mapper接口中的方法名 ,属性parameterType的值为此方法形参的类型 --> <update id="updateUserInfo" parameterType="com.pojo.SmbmsUser"> <!--sql语句中 #{xxx} 中xxx均为实体类中的属性名一致--> Update smbms_user set userName=#{userName} where id=#{id} </update>
myBatis框架的删除
//接口中的方法 /** * 根据id删除的方法 * @param id 要删除的id * @return 返回受影响的行数 */ int deleteUserInfoById(@Param("id")int id);
<!--对应的mapper标签--> <!--属性id的值为对应的Mapper接口中的方法名 ,属性parameterType的值为此方法形参的类型 --> <delete id="deleteUserInfoById" parameterType="int"> <!--此时#{xxx}参数中xxx可以不与对应Mapper类方法中的形参一直--> delete from smbms_user where id=#{id} </delete>
注意总结
1>对于增删改这类操作,数据库本身默认返回执行sql所影响的行数,所以DAO层的Mapper接口方法的返回值一般设置为int类型。
2>insert , update, delete元素中均没有resultType/resultMap属性。
myBatis框架的简单查询
基本数据类型—实现单一条件查询
//接口中的方法 /** * 根据用户名模糊查的方法 * @param userName 用户名 * @return 集合 */ List<SmbmsUser> listByUserName(String userName);
<!--对应的mapper标签--> <!--属性id的值为对应的Mapper接口中的方法名 ,属性parameterType的值为此方法形参的类型 --> <!--属性resultType的值为返回结果的类型,要使用完全限定名或别名(这里用了完全限定名) --> <select id="listByUserName" parameterType="string" resultType="com.pojo.SmbmsUser"> <!--此时#{xxx}参数中xxx可以不与对应Mapper类方法中的形参一直--> SELECT u.*,r.`roleName` FROM smbms_user AS u INNER JOIN `smbms_role` AS r ON u.`userRole`=r.`id` WHERE userName LIKE CONCAT('%',#{param},'%') </select>
select标签中的parameterType属性 ,表示为向sql语句传入的参数类型,使用完全限定名(包名+类名)或别名,支持基础数据类型和复杂数据类型。
被映射的sql语句中,参数的表示方法为*#{参数名},此参数名不需要**和Mapper接口中方法的形参刻意匹配,因为myBatis框架将映射的sql语句自动转换成 “?” 占位符的sql语句并实现赋值。*
mybatis框架内建的部分别名与java数据类型的映射关系
基本数据类型—实现多条件查询
使用@Param注解实现多参数入参
//接口中的方法 /** * 根据商品名和id查询商品通过注解的方式 * @param name 商品名 * @param id id * @return 返回一个商品对象 */ SmbmsProvider getByNameAndIdInNote(@Param("proName")String name,@Param("id")int id); //注解中的参数名,将用于Sql映射文件中的对应select标签的sql语句中的参数值
<!--对应的mapper标签中--> <!--属性id的值为对应的Mapper接口中的方法名 ,属性parameterType的值为此方法形参的类型 --> <!--属性resultType的值为返回结果的类型,要使用完全限定名或别名(这里用了完全限定名) --> <select id="getByNameAndIdInNote" resultType="com.pojo.SmbmsProvider"> select * from smbms_provider where proName like CONCAT('%',#{proName},'%') and id=#{id} </select>
注意:
1,当输入的参数类型为基本数据类型时,select标签中的parameterType属性可省略(无论单参还是多参)
2,注解中定义的参数名称要和sql语句占位符中的参数名称一致
实现多条件查询
将查询条件封装成java对象作为入参
//接口中的方法 /** * 根据输入参数查询商品信息 * @param provider 对象 * @return 商品对象 */ List<SmbmsProvider> getAll(SmbmsProvider provider);
<!--对应的mapper标签中--> <!--属性id的值为对应的Mapper接口中的方法名 ,属性parameterType的值为此方法形参的类型 --> <!--属性resultType的值为返回结果的类型,要使用完全限定名或别名(这里用了完全限定名) --> <select id="getAll" resultType="com.pojo.SmbmsProvider" parameterType="com.pojo.SmbmsProvider"> <!--sql中的#{xxx}中的xxx要和实体类中的属性名一致--> select * from smbms_provider where proName like CONCAT('%',#{proName},'%') </select>
将查询条件封装成Map对象作为入参 //接口中的方法
/** * 根据商品名和id查询商品的方法 * @param map map集具体合对象中存有商品名和id的值 * @return 返回一个具体对象 */ SmbmsProvider getByNameAndId(Map<String,Object> map);
<!--对应的mapper标签中--> <!--属性id的值为对应的Mapper接口中的方法名 ,属性parameterType的值为此方法形参的类型 --> <!--属性resultType的值为返回结果的类型,要使用完全限定名或别名(这里用了完全限定名) --> <select id="getByNameAndId" parameterType="map" resultType="com.pojo.SmbmsProvider"> <!--sql中的#{xxx}中的xxx要和map集合中的key一致--> select * from smbms_provider where proName like CONCAT('%',#{proName},'%') and id=#{id} </select>
//测试类中 @Test void getByNameAndId() { SqlSession session= MyBatisUtil.getSqlSession(); ProviderMapper providerMapper=session.getMapper(ProviderMapper.class); Map<String,Object> map=new HashMap<>() ; //注意添加的key map.put("proName","北京"); map.put("id",6); SmbmsProvider smbmsProvider= providerMapper.getByNameAndId(map); System.out.println(smbmsProvider.getProName()); }
使用Map类型传递多个参数,绑定的sql语句中使用#{Map的key}来取得参数值。使用Map传参的方式更加灵活,不受域模型(实体类)设计的限制,可以更加灵活的组织查询所需的条件。
MyBatis框架的结果映射
使用resultMap元素定义结果映射,对名称不同的结果集字段和实体类属性进行映射。
resultMap元素包含的属性
resultMap元素包含的子元素
eg:
<!--使用resultMap元素定义结果映射--> <resultMap id="userWithRoleName" type="com.pojo.SmbmsUser"> <id property="id" column="id"></id> <result property="userRoleName" column="roleName"></result> </resultMap> <!--使用resultMap元素定义的规则封装查询结果--> <select id="listByUserName" parameterType="string" resultMap="userWithRoleName"> SELECT u.*,r.`roleName` FROM smbms_user AS u INNER JOIN `smbms_role` AS r ON u.`userRole`=r.`id` WHERE userName LIKE CONCAT('%',#{userName},'%') </select>
注意
1,select元素中的resultMap属性的值要与resultMap元素中id属性的值一致。
2,select元素中的parameterType属性的值要与resultMap元素中type属性的值一致。
3,resultMap元素中的id子元素是数据表主键字段的列, 其中property属性是相应实体类中的对应属性,其中column属性是结果集中列的名称。
4,resultMap元素中的result子元素是用来映射其他的列, 其中property属性是相应实体类中的对应属性,其中column属性是结果集中列的名称。
resultMap的自动映射行为
可以在核心配置文件中进行设置
<settings> <!-- 设置自动映射行为 --> <setting name="autoMappingBehavior" value="FULL"/> </settings>
其上value的值有3种
自动映射行为对resultType和resultMap的影响
注意
1, resultType不支持嵌套映射,无论autoMappingBehavior设置为PARTIAL还是FULL,实体类都会自动映射,而实体类中的关联属性都不会被初始化,始终未null.
2,resultType完全依赖自动映射,如果autoMappingBehavior设置为NONE,resultType会失效,无法初始化实体类对象而返回null,此时返回 查询只能使用resultMap手工映射。
嵌套结果映射
1,association元素
------------此元素用来处理‘’has-one‘’类型的关系(复合类型)。
处理:多对一或一对一
association元素包含的属性
association元素包含的子元素
eg:
//用户实体类中,添加一个角色类型的属性 private SmbmsRole smbmsRole;//系统角色实体类类型的属性 public SmbmsRole getSmbmsRole() { return smbmsRole; } public void setSmbmsRole(SmbmsRole smbmsRole) { this.smbmsRole = smbmsRole; }
//接口中添加相应的查询方法 /** * 根据roleId查找信息--使用嵌套方式 * @param roleId * @return */ List<SmbmsUser> listByRoleId(@Param("roleId")Long roleId);
<!--相应的mapper文件中--> <resultMap id="showRoleName" type="com.smbms.pojo.SmbmsUser"> <id property="id" column="id"/> <!----> <association property="smbmsRole" javaType="com.smbms.pojo.SmbmsRole"> <id property="id" column="rid" /> <result property="roleName" column="roleName"/> <result property="roleCode" column="roleCode"/> </association> </resultMap> <select id="listByRoleId" parameterType="long" resultMap="showRoleName"> SELECT u.*,r.id AS rid,r.`roleName`,r.`roleCode` FROM `smbms_user` AS u INNER JOIN `smbms_role` AS r ON u.`userRole`=r.id </select>
//测试类 @Test void listByRoleId() { List<SmbmsUser> list=userMapper.listByRoleId(3L); for (SmbmsUser smbmsUser : list) { System.out.println(smbmsUser.getUserName()+"\t"+ smbmsUser.getSmbmsRole().getRoleName()); } //结果--- 赵燕 普通员工 赵敏 打工人 ss 打工人
注意:
1,因为结果映射的需要,要确保所有列名都是唯一的。
2,id子元素在嵌套结果映射中扮演了重要的角色。最好选择尽量少的属性来表示唯一结果。
对上述Mapper文件可修改为
<!--相应的mapper文件中--> <!--把其单独提取出来,便于重用--> <resultMap id="showRoleInfo" type="com.smbms.pojo.SmbmsRole"> <id property="id" column="rid" /> <result property="roleName" column="roleName"/> <result property="roleCode" column="roleCode"/> </resultMap> <resultMap id="showRoleName" type="com.smbms.pojo.SmbmsUser"> <id property="id" column="id"/> <!----> <association property="smbmsRole" javaType="com.smbms.pojo.SmbmsRole" resultMap="showRoleInfo"> </association> </resultMap> <select id="listByRoleId" parameterType="long" resultMap="showRoleName"> SELECT u.*,r.id AS rid,r.`roleName`,r.`roleCode` FROM `smbms_user` AS u INNER JOIN `smbms_role` AS r ON u.`userRole`=r.id </select>
2,collection元素
---------实体类内部嵌套的是一个集合类型的属性
collection元素包含的属性
collection元素包含的子元素
eg:
//用户的实体类中 添加属性 private List<SmbmsAddress> addressList;//用户地址列表 public List<SmbmsAddress> getAddressList() { return addressList; } public void setAddressList(List<SmbmsAddress> addressList) { this.addressList = addressList; }
//相应接口中编写方法 /** * 根据永用户id查询用户及相关地址 * @param id * @return */ List<SmbmsUser> listUserAndAddressesByUserId(@Param("userId")int id);
<!--相应的mapper文件中--> <resultMap id="show" type="com.smbms.pojo.SmbmsUser"> <id property="id" column="id"></id> <collection property="addressList" ofType="com.smbms.pojo.SmbmsAddress"> <id property="id" column="aid"></id> <result property="contact" column="contact"></result> <result property="addressDesc" column="addressDesc"></result> <result property="postCode" column="postCode"></result> <result property="tel" column="tel"></result> </collection> </resultMap> <select id="listUserAndAddressesByUserId" parameterType="int" resultMap="show"> SELECT u.*,a.id AS aid,a.`addressDesc`,a.`contact`,a.`postCode`,a.`tel` FROM `smbms_user` AS u INNER JOIN `smbms_address` AS a ON u.id=a.`userId` WHERE u.id=#{userId} </select>
//测试类 @Test void listUserAndAddressesByUserId() { List<SmbmsUser> list=userMapper.listUserAndAddressesByUserId(1); for (SmbmsUser smbmsUser : list) { System.out.println(smbmsUser.getUserName()+"\t"); //找到此用户的地址集合并打印 for (SmbmsAddress smbmsAddress : smbmsUser.getAddressList()) { System.out.println(smbmsAddress.getAddressDesc()); } } } //结果 系统管理员 北京市东城区东交民巷44号 北京市海淀区丹棱街3号 北京市东城区美术馆后街23号
resultType和resultMap总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持自由互联。