在讲之前先说说它的好处: 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 映射文件
- <!-- 根据用户名查询用户列表(模糊查询)-->
- <select id="getUserListByUserName" resultType="User" parameterType="string">
- SELECT * FROM USER WHERE userName LIKE concat('%',#{userName},'%')
- </select>
各属性介绍:
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 实现多条件查询
使用对象入参
编写映射文件
- <select id="getUserListByUser" resultType="User" parameterType="User">
- SELECT * FROM USER WHERE userName LIKE concat('%',#{userName},'%') and userRole=#{userRole}
- </select>
编写接口
List<User> getUserListByUser(User user);
编写测试
- SqlSession sqlSession=null;
- List<User> userList=new ArrayList<User>(); 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 入参编写接口
List<User> getUserListByMap(Map<String,String> userMap);
编写 UserMapper.xml 文件
- <select id="getUserListByMap" resultType="User" parameterType="Map">
- SELECT * FROM USER WHERE userName LIKE concat('%',#{userName},'%')
- and userRole=#{userRole}
- </select>
编写测试
- SqlSession sqlSession=null;
- List<User> userList=new ArrayList<User>(); try{
- sqlSession=MyBatisUtil.createSqlSession();
- Map<String,String> userMap=new HashMap<String,String>();
- 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 方法
- <select id="getUserList" resultMap="userList" parameterType="User">
- SELECT u.*,r.roleName FROM USER u,Role r WHERE u.userName LIKE concat('%',#{userName},'%')
- AND u.userRole=#{userRole} AND u.userRole=r.id
- </select>
添加 id 为 userList 的 resultMap 元素节点
- <resultMap id="userList" type="User">
- <result property="id" column="id"/>
- <result property="userCode" column="userCode"/>
- <result property="userName" column="userName"/>
- <result property="phone" column="phone"/>
- <result property="birthday" column="birthday"/>
- <result property="gender" column="gender"/>
- <result property="userRole" column="userRole"/>
- <result property="userRoleName" column="roleName"/>
- </resultMap>
测试
- SqlSession sqlSession=null;
- List<User> userList=new ArrayList<User>(); 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 没有做映射关联时也能自动匹配.
关闭方法:
- <settings>
- <!-- 设置 resultMap 的自动映射级别为 NONE(禁止自动匹配)-->
- <setting name="autoMappingBehavior" value="NONE"/>
- </settings>
实现增删改的操作
1 使用 insert 完成增加操作
在接口中添加 add()方法
int add(User user);
在映射文件中编写插入语句
- <insert id="add" parameterType="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})
- </insert>
编写测试代码
- 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 id="modify" parameterType="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}
- </update>
编写测试代码
- 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 id="updatePwd">
- UPDATE USER SET userPassword=#{userPassword} WHERE id=#{id}
- </update>
编写测试
- 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 id="deleteUserById">
- DELETE FROM USER WHERE id=#{id}
- </delete>
编写测试
- 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 接口中添加方法
List<User> getUserListByRoleId(@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 复用配置
- <resultMap id="roleResult" type="Role">
- <id property="id" column="r_id"/>
- <result property="roleCode" column="roleCode"/>
- <result property="roleName" column="roleName"/>
- </resultMap>
- <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" resultMap="roleResult"/>
- </resultMap>
collection 一对多关联
创建 pojo Addres.java
- public 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 类增加地址列表属性
List<Address>addressList;
编写接口中的方法
List<User> getAddressListByUserId(@Param("id")Integer userId);
编写映射文件
- <resultMap id="addressResult" type="Address">
- <id column="a_id" property="id"/>
- <result property="postCode" column="postCode"/>
- <result property="tel" column="tel"/>
- <result property="contact" column="contact"/>
- <result property="addressDesc" column="addressDesc"/>
- </resultMap>
- <resultMap id="userAddressResult" type="User">
- <id property="id" column="id"/>
- <result property="userCode" column="userCode"/>
- <result property="userName" column="userName"/>
- <collection property="addressList" ofType="Address" resultMap="addressResult"/>
- </resultMap>
编写测试
- SqlSession sqlSession=null; try{
- sqlSession=MyBatisUtil.createSqlSession();
- List<User> userList=sqlSession.getMapper(UserMapper.class).getAddressListByUserId(1); for (User user: userList) {
- System.out.println(user.getUserName()); List<Address> 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: 自动匹配所有
来源: https://www.cnblogs.com/Djkang/p/9928268.html