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

在讲以前先说说它的好处:Mybatis真正强大之处就是在于SQL映射语句,也是他的魅力所在。相对于它强大的功能,SQL映射文件的配置却很是简单。简单的对比一下SQL映射配置和JDBC代码,发现使用SQL映射文件配置可减小50%以上的代码量。而且MyBatis专一于SQL,对于开发人员来讲,也可极大限度地进行SQL调优,以保证性能。java

关于SQL映射文件的几个顶级元素配置:

顶级元素配置
mapper:映射文件的根元素节点,只有一个属性namespace(命名空间),做用以下:sql

  • 用于区分不一样的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>

编写接口app

List<User> getUserListByUser(User user);

编写测试post

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

<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:自动匹配全部

相关文章
相关标签/搜索