如何快速上手SQL映射文件的编写

在讲之前先说说它的好处: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:查询语句返回结果类型的完全限定名或别名别名表

别名映射的类型别名映射类型
stringStringdoubleDouble
byteBytefloatFloat
loangLongbooleanBoolean
shortShortdateDate
intIntegermapMap
integerIntegerhashmapHashMap
arrayListArrayListlistList
使用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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值