MyBatis 注解开发

一、单表查询

1. @Select 注解

前面的章节介绍了 MyBatis 的基本用法、关联映射、动态 SQL 和缓存机制等知识,所有的配置都是基于 XML 文件完成的,但在实际开发中,大量的 XML 配置文件的编写是非常繁琐的,为此,MyBatis 提供了更加简便的基于注解的配置方式。本篇将对 MyBatis 的注解开发进行详细讲解。

① 在项目的 com.tyut.pojo 包下创建持久化类 Worker,在 Worker 类中定义 id、员工姓名、年龄、性别、工号等属性以及属性对应的 getter/setter 方法。

② 在 com.tyut.dao 包下创建 WorkerMapper 接口,用于编写 @Select 注解映射的 select 查询方法。

package com.tyut.dao;
import com.tyut.pojo.Worker;
import org.apache.ibatis.annotations.Select;
public interface WorkerMapper {
    @Select("select * from tb_worker where id = #{id}")
    public Worker selectWorker(int id);
}

与之前不同的是,之前我们的 SQL 语句是写在 XML 映射文件中的,现在我们是注解开发不再需要 XML 了,而是去创建一个接口类,编写注解映射的 SQL 方法。

注意接口类的名字是有规范的,表名加 Mapper 的格式!

③ 因为不再是映射文件了,而是一个接口,所以需要在核心配置文件中引入 WorkerMapper 接口,告诉 MyBatis 我们的接口在哪里。

<mapper class="com.tyut.dao.WorkerMapper"/>

注意这里是 class 属性,不是 resource!

④ 编写测试方法,我们通过 MyBatis 的固定 API session.getMapper(WorkerMapper.class) 得到接口对象,然后就可以调用接口的方法了。

public void findWorkerByIdTest() {
    //1.获取SqlSession对象
    SqlSession session = MyBatisUtils.getSession();
    WorkerMapper mapper = session.getMapper(WorkerMapper.class);
    //2.查询id为1的员工信息
    Worker worker = mapper.selectWorker(1);
    System.out.println(worker);
    //3.关闭SqlSession
    session.close();
}

为了减少代码量,其实我们可以把公共部分写在 Before 和 After 中,代表每做一次 Test 都会先去执行 Before,并且最后执行一遍 After,而在 Test 中直接调用接口方法即可。

在这里插入图片描述

2. @Insert 注解

① 在 WorkerMapper 接口中添加插入数据的方法 insertWorker(),并在方法中添加 @Insert 注解。

@Insert("insert into tb_worker(name, age, sex, worker_id)"+"values(#{name}, #{age}, #{sex}, #{worker_id})")
public int insertWorker(Worker worker);

② 编写测试类

public void insertWorkerTest() {
    //1.生成SqlSession对象
    SqlSelssion session = MyBatisUtils.getSession();
    Worker worker = new Worker();
    worker.setId(4);
    worker.setName("张三");
    worker.setAge(36);
    worker.setSex("女");
    worker.setWorker_id("1004");
    WorkerMapper mapper = session.getMapper(WorkerMapper.class);
    //2.插入员工信息
    int result = mapper.insertWorker(worker);
    System.out.println(result);
    //3.手动提交修改并关闭SqlSession
    session.commit();
    session.close();
}

3. @Update 注解

① 在 WorkerMapper 接口中添加更新数据的方法,并在方法中添加 @Update 注解。

@Update("update tb_worker set name = #{name}, age = #{age}"+"where id = #{id}")
public int updateWorker(Worker worker);

② 编写测试类

public void updateWorkerTest() {
    //1.生成SqlSession对象
    SqlSession session = MyBatisUtils.getSession();
    Worker worker = new Worker();
    worker.setId(4);
    worker.setName("李华");
    worker.setAge(28);
    WorkerMapper mapper = session.getMapper(WorkerMapper.class);
    //2.更新员工信息
    int result = mapper.updateWorker(worker);
    System.out.println(result);
    //3.手动提交修改并关闭SqlSession
    session.commit();
    session.close();
}

4. @Delete 注解

① 同样,在 WorkerMapper 接口中添加删除数据的方法,并在方法上添加 @Delete 注解。

@Delete("delete from tb_worker where id = #{id}")
public int deleteWorker(int id);

② 编写测试类

public void deleteWorkerTest() {
    //1.生成SqlSession对象
    SqlSession session = MyBatisUtils.getSession();
    WorkerMapper mapper = session.getMapper(WorkerMapper.class);
    //2.删除员工信息
    int result = mapper.deleteWorker(4);
    if(result > 0) {
        System.out.println("成功删除"+result+"条数据");
    } else {
        System.out.println("删除数据失败");
    }
    //3.手动提交修改并关闭SqlSession
    session.commit();
    session.close();
}

增删改操作需要手动去提交!

5. @Param 注解

下面通过一个案例来演示 @Param 注解的使用,该案例要求根据员工的 id 和姓名查询员工信息,具体步骤如下:

① 添加注解,在 WorkerMapper 接口中添加多条件查询的方法。

@Select("select * from tb_worker where id = #{param01} and name = #{param02}")
public Worker selectWorkerByIdAndName(@Param("param01") int id, @Param("param02") String name); 

param01 和 param02 是我们给这两个参数分别起的别名!

② 编写测试类

public void selectWorkerByIdAndNameTest() {
    //1.生成SqlSession对象
    SqlSession session = MyBatisUtils.getSession();
    WorkerMapper mapper = session.getMapper(WorkerMapper.class);
    //2.查询id为3姓名为王五的员工的信息
    Worker worker = mapper.selectWorkerByIdAndName(3,"王五");
    System.out.println(worker);
    session.close();
}

二、多表关联查询

1. 一对一查询

根据 person 的 id 查询人的信息,以及 IdCard 的信息。
Mybatis 注解式开发多表查询的前提是,将一条多表查询的 SQL,拆分成多条单表查询的 SQL!

① 创建 Person 和 IdCard 的两个实体类

//Person.java
package com.tyut.pojo;

public class Person {
    private int id;
    private String name;
    private int age;
    private String sex;
    //一对一的映射
    private IdCard card;

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                ", card=" + card +
                '}';
    }

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public IdCard getCard() {
        return card;
    }
    public void setName(IdCard card) {
        this.card = card;
    }
}

//IdCard.java
package com.tyut.pojo;

public class IdCard {
    private int id;
    private String code;

    @Override
    public String toString() {
        return "IdCard{" +
                "id=" + id +
                ", code='" + code + '\'' +
                '}';
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

}

② 在 com.tyut.dao 包下创建 IdCardMapper 接口 和 PersonMapper 接口,关键在于第二个接口的编写

//IdCardMapper.java
package com.tyut.dao;
import com.tyut.pojo.IdCard;
import org.apache.ibatis.annotations.Select;
public interface IdCardMapper {
    @Select("select * from tb_idcard where id = #{id}")
    public IdCard selectIdCardById(int id);
}
//PersonMapper.java
package com.tyut.dao;
import com.tyut.pojo.Person;
import org.apache.ibatis.annotations.Select;
public interface PersonMapper {
    @Select("select * from tb_person where id = #{id}")
    @Results(@Result(column = "card_id", property = "card",
        one = @One(select = "com.tyut.dao.IdCardMapper.selectIdCardById")
    ))
    public Person selectPersonById(int id);
}

@Result 注解的三个属性及含义:
(1)property 属性用来指定关联属性,这里为 card;
(2)column 属性用来指定关联的数据库表中的字段,这里为 card_id;
(3)one 属性用来指定数据表之间属于哪种关联关系,通过 @One 注解表明数据表 tb_idcard 和 tb_person 之间是一对一关联关系。

③ 在核心配置文件中引入接口

<mapper class="com.tyut.dao.IdCardMapper"/>
<mapper class="com.tyut.dao.PersonMapper"/>

要注意接口的引入顺序,由于 MybatisConfig.xml 文件的扫描方式是从上往下扫描,所以先引入 IdCardmapper,后引入 PersonMapper!

④ 编写测试类

public void selectPersonByIdTest() {
    //1.生成SqlSession对象
    SqlSession session = MyBatisUtils.getSession();
    PersonMapper mapper = session.getMapper(PersonMapper.class);
    //2.查询id为1的人员信息
    Person person = mapper.selectPersonById(1);
    System.out.println(person);
    session.close();
}

2. 一对多查询

基于用户与订单的关系演示一对多查询,这里实体类我仅展示部分代码,完整代码可参考我前面的文章 —— MyBatis 关联映射,实体类完全一致,不再重复。

① 在 com.tyut.dao 包下创建 OrdersMapper 接口 和 UsersMapper 接口

//OrdersMapper.java
public interface OrdersMapper {
    @Select("select * from tb_orders where user_id = #{id}")
    @Results(@Result(id = true, column = "id", property = "id"),
        @Result(column = "number", property = "number")
    )
    public List<Orders> selectOrdersByUserId(int user_id);
}

id = true 代表此处是主键映射,当实体的属性名与数据表的列名一致时,映射这一步骤可以省略!

//UsersMapper.java
public interface UsersMapper {
    @Select("select * from tb_user where id = #{id}")
    @Results(@Result(id = true, column = "id", property = "id"),
        @Result(column = "username", property = "username"),
        @Result(column = "address", property = "address"),
        @Result(column = "id", property = "ordersList",
            many = @Many(select = "com.tyut.dao.OrdersMapper.selectOrdersByUserId"))
    )
    public Users selectUserById(int id);
}

② 编写测试类

public void selectUserById() {
    //1.生成SqlSession对象
    SqlSession session = MyBatisUtils.getSession();
    UsersMapper mapper = session.getMapper(UsersMapper.class);
    //2.查询id为1的用户订单信息
    Users users = mapper.selectUserById(1);
    System.out.println(users);
    session.close();
}

3. 多对多查询

多对多关联关系通常使用一个中间表来维护,我们依然以前面的订单表和商品表为例进行演示,根据订单的 id 查询订单信息以及订单对应的商品信息。

① 在 com.tyut.dao 包下创建 ProductMapper 接口 和 OrdersMapper 接口

//ProductMapper.java
public interface ProductMapper {
    @Select("select * from tb_product where id in (select product_id from tb_ordersitem where orders_id = #{id})")
    public List<Product> selectProductByOrdersId(int orders_id);
}
//OrdersMapper.java
public interface OrdersMapper {
    @Select("select * from tb_orders where id = #{id}")
    @Results(@Result(id = true, column = "id", property = "id"),
        @Result(column = "number", property = "number"),
        @Result(column = "id", property = "productList",
            many = @Many(select = "com.tyut.dao.ProductMapper.selectProductByOrdersId"))
    )
    public Orders selectOrdersById(int id);
}

② 编写测试类

public void selectOrderById() {
    //1.生成SqlSession对象
    SqlSession session = MyBatisUtils.getSession();
    OrdersMapper mapper = session.getMapper(OrdersMapper.class);
    //2.查询id为1的订单信息及订单对应的商品信息
    Orders orders = mapper.selectOrderById(1);
    System.out.println(orders);
    session.close();
}
  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

栈老师不回家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值