如何快速上手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:自動匹配全部

相關文章
相關標籤/搜索