MyBatis框架进阶(二),Mybatis注解开发,实现单表的增删改查与多表关联查询

文章目录

  • Mybatis注解开发-实现单表的增删改查
      • JavaBean中属性名和字段名不一致的情况解决方案
  • 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中属性名和字段名不一致的情况解决方案

MyBatis框架进阶(二),Mybatis注解开发,实现单表的增删改查与多表关联查询_第1张图片

  • 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框架进阶(二),Mybatis注解开发,实现单表的增删改查与多表关联查询_第2张图片

Mybatis注解开发-多表关联查询并实现延迟加载

user表
MyBatis框架进阶(二),Mybatis注解开发,实现单表的增删改查与多表关联查询_第3张图片
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语句
MyBatis框架进阶(二),Mybatis注解开发,实现单表的增删改查与多表关联查询_第4张图片

  • 测试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框架进阶(二),Mybatis注解开发,实现单表的增删改查与多表关联查询_第5张图片
回顾: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框架进阶(二),Mybatis注解开发,实现单表的增删改查与多表关联查询_第6张图片
回顾:MyBatis框架进阶(一),动态Sql,多表关联查询与延迟加载策略

你可能感兴趣的:(#,MyBatis)