MyBatis框架進階(二),Mybatis註解開發,實現單表的增刪改查與多表關聯查詢


回顧:

MyBatis框架快速入門(一),搭建MyBatis開發環境
MyBatis框架快速入門(二),使用映射器接口代理對象的方式實現單表的增刪改查
MyBatis框架進階(一),動態Sql,多表關聯查詢與延遲加載策略

之前的CRUD操作是基於 Mybaits 的映射文件來實現的,簡單的CRUD使用配置映射文件的方式實現編碼較繁瑣,這時可以考慮使用Mybatis的註解開發,基於註解的映射方式,實現CRUD,只是將配置映射文件的過程替換了,只要將sql語句直接寫入註解的括號中即可,其他配置編碼與之前的方式是一樣的。

這裏實現也只要編寫接口,而不用寫實現類。(有接口,沒有實現類,生成代理對象,由代理對象完成功能)


Mybatis註解開發-實現單表的增刪改查

  • user表的實體類
public class User {
    private Integer id;
    private String username;
    private String password;
    private String email;
    private Date birthday;
    ...
    ...
}
  • 映射器接口UserMapper
public interface UserMapper {
    //查詢所有用戶
    @Select("select * from t_user")
    List<User> queryAllUser();

    //根據id查詢用戶信息
    @Select("select * from t_user where id=#{id}")
    User selectUserByid(int id);

    //增加用戶
    @Insert("insert into t_user (id,username,password,email,birthday) values (#{id},#{username},#{password},#{email},#{birthday})")
    @SelectKey(keyProperty = "id",resultType = Integer.class,before = false,statement ="select last_insert_id()")
    /**
     *  @SelectKeyz註解:
     *      statement="要執行的SQL語句"
     *      keyProperty="將上述SQL語句查詢的結果賦值給入參的指定屬性"  這裏是賦值給user的id
     *      before="SelectKey中的SQL語句是否先執行"   oracle爲true
     *      resultType="上述SQL語句查詢出的數據需要轉換的數據類型(數據類型和被賦值的屬性類型必須一致)"
     *
     */
    int insertUser(User user);

    //更新指定用戶信息
    @Update(" update t_user set password=#{password},email=#{email} where id=#{id}")
    void  updateUser(User user);

    //根據id刪除指定用戶
    @Delete("delete from t_user where id=#{id}")
    void  deleteUser(int id);

    //根據用戶名模糊查詢
    @Select("select * from t_user where username like #{username}")
    List<User> selectUserByUserName(String username);

    //根據用戶名模糊查詢
    @Select("select * from t_user where username like '%${value}%'")
    List<User> selectUserByUserName2(String username);


    @Select("select count(*) from t_user")
    //查詢總記錄數
    int getTotalCount();
}

  • 這裏測試增加操作 測試@SelectKey 註解的作用
  1. 使用mysql數據庫
    @Test
    public void insertUserTest() throws IOException {
        User user = new User();
        user.setUsername("張三三");
        user.setPassword("3");
        user.setEmail("[email protected]");
        user.setBirthday( new Date());
        System.out.println("插入數據前"+user);
        //User{id=null, username='張三三', password='3', email='[email protected]', birthday=Sat Apr 04 14:50:17 CST 2020}
        mapper.insertUser(user);
        sqlSession.commit();

        /*使用的是mysql數據庫
        當插入數據後,要在界面顯示該數據時,應主鍵(id)是自增的,沒有賦值插入,
        所以這裏插入數據後 輸出的id就爲null,可以通過@SelectKey來查詢id的值,並返回顯示。
         */
        System.out.println("插入數據後"+user);
        //User{id=24, username='張三三', password='3', email='[email protected]', birthday=Sat Apr 04 14:50:17 CST 2020}
    }

  1. 使用oracle數據庫,序列實現自增,使用 @SelectKey 註解可在插入數據前賦值給入參的指定屬性(如id),即可實現id自增。(@SelectKey 註解更多運用於此)

JavaBean中屬性名和字段名不一致的情況解決方案

在這裏插入圖片描述

  • user表的實體類
public class User {
    private Integer uid;
    private String uname;
    private String upassword;
    private String uemail;
    private Date ubirthday;
    ...
    ....
 }
  • 映射器接口UserMapper
    //查詢所有用戶
    @Select("select * from t_user")
    //@Results:相當於映射配置文件裏的resultMap標籤
    //@Result:相當於映射配置文件裏的result標籤,@Result和@Results配合使用,封裝結果集。
    @Results(value = {
           @Result(property ="uid",column ="id",id = true), //是否爲主鍵
           @Result(property ="uname" ,column ="username" ),
           @Result(property ="upassword",column ="password" ),
           @Result(property ="uemail" ,column ="email" ),
           @Result(property ="ubirthday" ,column ="birthday")
    })
    List<AliasUser> selectAllAliasUser();

參考映射配置文件
在這裏插入圖片描述

Mybatis註解開發-多表關聯查詢並實現延遲加載

user表
在這裏插入圖片描述
account表
在這裏插入圖片描述

一對多(多對多)關聯查詢:查詢用戶信息,以及每個用戶擁有的所有帳號信息

  • user表和account表的實體類
public class User {
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;
    private List<Account> accountList;
    ....
    ...
}

public class Account {
    private Integer id;
    private Integer uid;
    private Double money;
    private User user;
    ..
    ...
}
  • 映射器接口UserMapper
public interface UserMapper {
    //一對多(多對多)關聯查詢:查詢用戶信息,以及每個用戶擁有的所有帳號信息
    @Select("select * from user")
    @Results({
            @Result(
                    javaType = List.class,//數據類型 注意,這裏是List.class,而不是Account.class 。 ①測試過 javaType不寫也可
                    many = @Many(      //@Many用於封裝JavaBean中某一屬性關聯的集合,用於一對多(多對多)情形
                            select = "com.mycode.mapper.AccountMapper.selectAccountById",  //調用外部功能查詢
                            fetchType = FetchType.LAZY //懶加載
                    ),
                    column ="id",//調用功能時傳遞的參數從哪個字段裏取  注意這裏映射後 需要寫 @Result(property ="id",column ="id") 否則查詢得到的User的id爲null
                    property ="accountList"//查詢的結果集封裝到User中哪個屬性
            ),
            @Result(property ="id",column ="id",id = true) //上面調用了id,這裏需要再給id賦值,否則爲null
    })
   List<User> queryAllUser();
}
  • 編寫映射器接口UserMapper所調用的外部功能,需要提供 查詢關聯的賬戶信息功能
public interface AccountMapper {
    //根據用戶id查詢賬戶
    @Select("select * from account where uid=#{id}")
    List<Account> selectAccountById(int id);
}

  • 測試1 延遲加載效果
    @Test
    public void testQueryAllUser(){
        List<User> userList = userMapper.queryAllUser();
        for (User user : userList) {
            //這裏只獲取用戶信息,只執行查詢用戶信息的SQL語句
            System.out.println(user.getUsername() +", " + user.getSex());
        }
    }

測試中只使用了用戶信息,所以只會查詢用戶信息,執行查詢用戶的SQL語句
在這裏插入圖片描述

  • 測試2
    @Test
    public void testQueryAllUser(){
        List<User> userList = userMapper.queryAllUser();
        for (User user : userList) {
            //這裏只獲取用戶信息,只執行查詢用戶信息的SQL語句
            System.out.println(user.getUsername() +", " + user.getSex());
           
            //當使用用戶關聯帳號信息時,會執行查詢帳號信息的SQL語句,只查詢用戶id爲32的賬號信息(即按需查詢)
            if (user.getId() == 32) {
                System.out.println(user.getAccountList());
            }
        }
    }

測試中查詢了用戶信息,並判斷了用戶id爲32的,查詢其賬戶信息。(這裏其他用戶的賬戶信息並不會查詢)
在這裏插入圖片描述
回顧:MyBatis框架進階(一),動態Sql,多表關聯查詢與延遲加載策略

一對一(多對一)關聯查詢:查詢賬戶信息及關聯的用戶信息

  • user表和account表的實體類
public class Account {
    private Integer id;
    private Integer uid;
    private Double money;
    
    private User user;
    ..
    ...
}

public class User {
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;
    
    private List<Account> accountList;
    ....
    ...
}
  • 映射器接口AccountMapper
public interface AccountMapper {
    //一對一(多對一)關聯查詢:查詢賬戶信息及關聯的用戶信息
    @Select("select * from account")
    @Results({
           @Result(property = "id",column = "id",id = true),
           @Result(property = "uid",column = "uid"),
           @Result(property = "money",column = "money"),
           @Result(
                   javaType = User.class,//關聯的JavaBean的字節碼
                   one=@One(
                           select ="com.mycode.mapper.UserMapper.selectUserByid"//調用哪個功能,查詢得到關聯的JavaBean對象
                           fetchType = FetchType.LAZY  //懶加載
                   ),
                   column = "uid",//調用功能時傳遞的參數從哪個字段裏取
                   property = "user"//封裝哪個屬性關聯的JavaBean
            )
    })
    List<Account> queryAllAccount()
}
  • 編寫映射器接口AccountMapper 所調用的外部功能,需要提供 查詢關聯用戶信息功能
public interface UserMapper {
    //根據賬號uid查詢用戶信息
    @Select("select * from user where id=#{uid}")
    User selectUserByid(int id);
}
  • 測試1
    @Test
    public void testQueryAllAccount(){
        List<Account> accounts = accountMapper.queryAllAccount();
        for (Account account : accounts) {
            //只使用了帳號信息,只執行查詢帳號的SQL語句
            System.out.println(account.getId() +", " +account.getMoney());
        }
    }

在這裏插入圖片描述

  • 測試2
    @Test
    public void testQueryAllAccount(){
        List<Account> accounts = accountMapper.queryAllAccount();
        for (Account account : accounts) {
            //只使用了帳號信息,只執行查詢帳號的SQL語句
            System.out.println(account.getId() +", " +account.getMoney());

            //當需要使用用戶信息時,纔會執行查詢用戶的SQL語句
            System.out.println(account.getUser());
        }
    }

在這裏插入圖片描述
回顧:MyBatis框架進階(一),動態Sql,多表關聯查詢與延遲加載策略

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章