在讲之前先说说它的好处:Mybatis真正强大之处就是在于SQL映射语句,也是他的魅力所在。相对于它强大的功能,SQL映射文件的配置却非常简单。简单的对比一下SQL映射配置和JDBC代码,发现使用SQL映射文件配置可减少50%以上的代码量。并且MyBatis专注于SQL,对于开发人员来说,也可极大限度地进行SQL调优,以保证性能。
关于SQL映射文件的几个顶级元素配置:
顶级元素配置
mapper:映射文件的根元素节点,只有一个属性namespace(命名空间),作用如下:- 用于区分不同的mapper,全局唯一
- 绑定DAO接口,即面向接口编程。当namespace绑定某一接口之后,可以不用写该接口的实现类, MyBatis会通过接口的完全限定名查找到对应的mapper配置来执行SQL语句,因此namespace的命名必须要跟接口同名
cache:配置给定命名空间的缓存
cache-ref:从其他命名空间引用缓存配置 resultMap:用来描述数据库结果集和对象的对应关系 sql:可以重用的SQL块,也可以被其他语句引用 insert:映射插入语句 update:映射更新语句 delete:映射删除语句 select:映射查询语句使用select完成单条件查询编写Mapper映射文件
各属性介绍:
id:命名空间中唯一的标识符,可以被用来引用这条语句 parameterType:表示查询语句传入参数的类型的完全限定名或别名。 resultType:查询语句返回结果类型的完全限定名或别名别名表别名 | 映射的类型 | 别名 | 映射类型 | |
---|---|---|---|---|
string | String | double | Double | |
byte | Byte | float | Float | |
loang | Long | boolean | Boolean | |
short | Short | date | Date | |
int | Integer | map | Map | |
integer | Integer | hashmap | HashMap | |
arrayList | ArrayList | list | List |
使用select实现多条件查询
使用对象入参
编写映射文件编写接口
ListgetUserListByUser(User user);
编写测试
SqlSession sqlSession=null;ListuserList=new ArrayList (); try{ sqlSession=MyBatisUtil.createSqlSession(); User user=new User(); user.setUserName("赵"); user.setUserRole(3); userList=sqlSession.getMapper(UserMapper.class).getUserListByUser(user);}catch (Exception ex){ ex.printStackTrace();}finally { MyBatisUtil.closeSqlSession(sqlSession);}for (User user: userList) { System.out.println(user.getUserName()+"\t"+user.getUserRole());}
使用Map入参编写接口
ListgetUserListByMap(Map userMap);
编写UserMapper.xml文件
编写测试
SqlSession sqlSession=null;ListuserList=new ArrayList (); try{ sqlSession=MyBatisUtil.createSqlSession(); Map userMap=new HashMap (); userMap.put("userName","赵"); userMap.put("userRole","3"); userList=sqlSession.getMapper(UserMapper.class).getUserListByMap(userMap);}catch (Exception ex){ ex.printStackTrace();}finally { MyBatisUtil.closeSqlSession(sqlSession);}for (User user: userList) { System.out.println(user.getUserName()+"\t"+user.getUserRole());}
使用resultMap完成查询结果的展现
先在User类中加入userRoleName属性:private String userRoleName,及其相应的getter和setter方
法编写UserMapper.xml文件,修改其中的getUserList方法
添加id为userList的resultMap元素节点
测试
SqlSession sqlSession=null;ListuserList=new ArrayList (); try{ sqlSession=MyBatisUtil.createSqlSession(); User user=new User(); user.setUserName("赵"); user.setUserRole(3); userList=sqlSession.getMapper(UserMapper.class).getUserList(user); }catch (Exception ex){ ex.printStackTrace();}finally { MyBatisUtil.closeSqlSession(sqlSession);}for (User user: userList) { System.out.println(user.getUserName()+"\t"+user.getUserRole()+"\t"+user.getUserRoleName());}
resultMap元素的属性值和子节点:
id属性:唯一标识,此id值用于select元素resultMap属性的引用 type属性:表示该resultMap的映射结果类型 result子节点:用于标识一些简答的属性,其中column属性表示从数据库中查询的字段名,property则 表示查询出来的字段对应的赋值给实体对象的哪个属性 resultType和resultMap的异同点及场景- 1.resultType直接表示返回类型,包括基本数据类型和复杂数据类型
- 2.resultMap则是对外部resultMap定义的引用,对应外部resultMap的id
- 3.MyBatis的每个查询映射的返回类型都是resultMap,当我们提供的返回类型是resultType,会自动赋值 给指定属性
- 4.resultMap自动映射界别默认映射级别为PARTIAL,在resultMap没有做映射关联时也能自动匹配。 关闭方法:
实现增删改的操作
1使用insert完成增加操作
在接口中添加add()方法 int add(User user); 在映射文件中编写插入语句INSERT INTO USER (userCode,userName,userPassword,gender,birthday, phone,address,userRole,createdBy,creationDate) VALUES (#{userCode},#{userName},#{userPassword},#{gender},#{birthday}, #{phone},#{address},#{userRole},#{createdBy},#{creationDate})
编写测试代码
SqlSession sqlSession=null; try{ sqlSession=MyBatisUtil.createSqlSession(); User user=new User(); user.setUserCode("testtt"); user.setUserName("测试"); user.setUserPassword("fajklfd"); user.setGender(1); Date birthday=new SimpleDateFormat("yyyy-MM-dd").parse("1990-1-1"); user.setBirthday(birthday); user.setPhone("1228392324"); user.setAddress("北京"); user.setUserRole(3); user.setCreatedBy(1); user.setCreationDate(new Date()); int count=sqlSession.getMapper(UserMapper.class).add(user); System.out.println("数量:"+count); sqlSession.commit();}catch (Exception ex){ ex.printStackTrace(); sqlSession.rollback();}finally { MyBatisUtil.closeSqlSession(sqlSession);}
使用update完成修改
在接口中添加modify()方法
int modify(User user); 在映射文件中编写修改语句UPDATE USER SET userCode=#{userCode},userName=#{userName},userPassword=# {userPassword}, gender=#{gender},phone=#{phone},address=#{address},userRole=#{userRole},modifyBy=# {modifyBy}, modifyDate=#{modifyDate},birthday=#{birthday} WHERE id=#{id}
编写测试代码
SqlSession sqlSession=null; try{ sqlSession=MyBatisUtil.createSqlSession(); User user=new User(); user.setId(15); user.setUserCode("testtt"); user.setUserName("测试修改"); user.setUserPassword("fajklfd"); user.setGender(1); Date birthday=new SimpleDateFormat("yyyy-MM-dd").parse("1990-1-1"); user.setBirthday(birthday); user.setPhone("1228392324"); user.setAddress("北京"); user.setUserRole(3); user.setCreateBy(1); user.setCreationDate(new Date()); int count=sqlSession.getMapper(UserMapper.class).modify(user); //int i=2/0;//测试事务回滚 System.out.println("数量:"+count); sqlSession.commit();}catch (Exception ex){ ex.printStackTrace(); sqlSession.rollback();}finally { MyBatisUtil.closeSqlSession(sqlSession);}
使用@Param注解实现多参数入参
如果参数只有两个,封装成对象并不合适,多参数入参可读性高。
在参数前增加@Param注解int updatePwd(@Param("id")Integer id,@Param("userPassword")String pwd);
编写修改语句
UPDATE USER SET userPassword=#{userPassword} WHERE id=#{id}
编写测试
SqlSession sqlSession=null; try{ sqlSession=MyBatisUtil.createSqlSession(); int id=15; String pwd="abc1223"; int count=sqlSession.getMapper(UserMapper.class).updatePwd(id,pwd); //int i=2/0;//测试事务回滚 System.out.println("数量:"+count); sqlSession.commit();}catch (Exception ex){ ex.printStackTrace(); sqlSession.rollback();}finally { MyBatisUtil.closeSqlSession(sqlSession);}
使用delete完成删除操作
编写接口方法
int deleteUserById(@Param("id")Integer delId);
在映射文件中编写删除语句
DELETE FROM USER WHERE id=#{id}
编写测试
SqlSession sqlSession=null;try{ sqlSession=MyBatisUtil.createSqlSession(); int id=15; int count=sqlSession.getMapper(UserMapper.class).deleteUserById(id); System.out.println("数量:"+count); sqlSession.commit();}catch (Exception ex){ ex.printStackTrace(); sqlSession.rollback();}finally { MyBatisUtil.closeSqlSession(sqlSession);}
使用resultMap实现高级结果映射(表表关联)
使用resultMap实现高级结果映射(表表关联)
Role类public class Role { private Integer id; private String roleCode; private String roleName; private Integer createdBy; private Date creationDate; private Integer modifyBy; private Date modifyDate; //省略getter和setter}
修改pojo User类
public class User { private Integer id; //id private String userCode; //用户编码 private String userName; //用户名称 private String userPassword; //用户密码 private Integer gender; //性别 private Date birthday; //出生日期 private String phone; //电话 private String address; //地址 private Integer userRole; //用户角色 private Integer createdBy; //创建者 private Date creationDate; //创建时间 private Integer modifyBy; //更新者 private Date modifyDate; //更新时间 //private String userRoleName; //用户角色名称 private Role role; //省略getter&setter方法}在UserMapper接口中添加方法ListgetUserListByRoleId(@Param("userRole")Integer roleId);
修改UserMapper.xml 增加getUserListByRoleId
xml <resultMap id="userRoleResult" type="User"> <id property="id" column="id"/> <result property="userCode" column="userCode"/> <result property="userName" column="userName"/> <result property="userRole" column="userRole"/> <association property="role" javaType="Role"> <id property="id" column="r_id"/> <result property="roleCode" column="roleCode"/> <result property="roleName" column="roleName"/> </association> </resultMap> <select id="getUserListByRoleId" parameterType="Integer" resultMap="userRoleResult"> SELECT u.*,r.id AS r_id,r.roleCode,r.roleName FROM user u,role r WHERE u.userRole=#{userRole} and u.userRole=r.id </select>
使用外部resultMap复用配置 collection 一对多关联
创建pojo Addres.javapublic class Address { private Integer id; private String contact; private String addressDesc; private String postCode; private String tel; private Integer createdBy; private Date creationDate; private Integer modifyBy; private Date modifyDate; private Integer userId; //省略getter和setter}
修改User类增加地址列表属性
ListaddressList;
编写接口中的方法
ListgetAddressListByUserId(@Param("id")Integer userId);
编写映射文件
编写测试
SqlSession sqlSession=null; try{ sqlSession=MyBatisUtil.createSqlSession(); ListuserList=sqlSession.getMapper(UserMapper.class).getAddressListByUserId(1); for (User user: userList) { System.out.println(user.getUserName()); List addresses=user.getAddressList(); for (Address address: addresses) { System.out.println("--- "+address.getContact()); } }}catch (Exception ex){ ex.printStackTrace();}finally { MyBatisUtil.closeSqlSession(sqlSession);}
resultMap自动映射级别和MyBatis缓存
autoMappingBehavior的三个级别
NONE:禁止自动匹配 PARTIAL:(默认)自动匹配所有属性,有内部嵌套(assocition,collection)除外 FULL:自动匹配所有