当前位置: 首页 > news >正文

【Java_EE】Day05 MyBatis注解开发

Day05 MyBatis注解开发

基于注解的单表增删改查

除了前四节我们使用XML的映射方式进行开发,其实我们更常用的方式是通过Mybatis的注解实现POJO实体对象和数据表,一般我们直接把他写在接口上。这样的好处在于相对来讲更简单,而且不会增加开销。MyBatis提供了@Select@Insert@Update@Delete以及@Param等用于增删改查,以及传递参数的常用注解。

@Select注解

@Select注解用于映射查询语句,下面通过根据员工id查找员工信息的案例来演示一下如何使用注解进行开发。

  1. mybatis数据库中创建名称为tb_worker的数据表,同时预先插入三条测试数据,具体语句如下所示:
USE mybatis;
# 创建一个名称为tb_worker的表
CREATE TABLE tb_worker(id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(32),age INT,sex VARCHAR(8),worker_id INT UNIQUE
);
# 插入3条数据
INSERT INTO tb_worker (name,age,sex,worker_id)
VALUES ('张三', 32, '女', 1001),('李四', 29, '男', 1002),('王五', 26, '男', 1003);
  1. 在项目pojo包下创建持久化实体类Worker.java,并在其中定义表中所有属性以及getter/setter方法、toString()方法:
package com.itheima.pojo;/*** 员工持久化类* @author Zhang*/
public class Worker {private Integer id;private String name;private Integer age;private String sex;// 这里为了符合java命名规范,我们使用小驼峰命名法// 但是要记住,我们永久类中的属性名必须和数据库中的字段名保持一致// 所以我们要在一会给他一个别名private String workerId;@Overridepublic String toString() {return "Worker{" +"id=" + id +", name='" + name + '\'' +", age=" + age +", sex='" + sex + '\'' +", workerId='" + workerId + '\'' +'}';}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public String getWorkerId() {return workerId;}public void setWorkerId(String workerId) {this.workerId = workerId;}
}
  1. 在项目的src/main/java包下创建一个com.itheima.dao包,并在该包下创建WorkerMapper接口,用于编写@Select注解映射的select查询方法。代码如下:
package com.itheima.dao;import com.itheima.pojo.Worker;
import org.apache.ibatis.annotations.Select;/*** @author Zhang*/
public interface WorkerMapper {// 当程序调用selectWorker方法时, 就会自动执行@Select注解中的语句了@Select("select * from mybatis.tb_worker where id=#{id}")Worker selectWorker (int id);
}
  1. 在核心配置文件mybatis-config.xml中的<mappers>元素下引入WorkerMapper接口,将WorkerMapper.java接口加载到核心配置文件中,具体代码添加如下:
        <mapper class="com.itheima.dao.WorkerMapper"/>
  1. 为了验证上述配置,在测试类MybatisTest中编写测试方法findWorkerByIdTest(),具体代码如下:
    @Testpublic void findWorkerByIdTest() {SqlSession session = MyBatisUtils.getSession();WorkerMapper mapper = session.getMapper(WorkerMapper.class);// 使用WorkerMapper对象查询id为1的员工信息Worker worker = mapper.selectWorker(1);System.out.println(worker.toString());session.close();}
  1. 运行结果应该是如下:
2024-10-08 23:56:08,084 [main] DEBUG [com.itheima.dao.WorkerMapper.selectWorker] - ==>  Preparing: SELECT * FROM mybatis.tb_worker WHERE id=?
2024-10-08 23:56:08,116 [main] DEBUG [com.itheima.dao.WorkerMapper.selectWorker] - ==> Parameters: 1(Integer)
2024-10-08 23:56:08,135 [main] DEBUG [com.itheima.dao.WorkerMapper.selectWorker] - <==      Total: 1
Worker{id=1, name='张三', age=32, sex='女', worker_id='1001'}

@Insert注解

@Insert注解用于映射插入语句,下面通过实现员工信息的插入案例来演示,具体步骤如下:

  1. WorkerMapper接口中添加向tb_worker数据表插入数据的方法insertWorker(),并在方法上添加@Insert注解,具体实现代码如下:
@Insert("INSERT INTO mybatis.tb_worker(name,sex,age,worker_id) " +"VALUES(#{name},#{sex},#{age},#{worker_id})")int insertWorker(Worker worker);
  1. 为了验证上述配置,我们在测试类中编写测试方法insertWorkerTest(),具体代码如下:
    @Testpublic void insertWorkerTest() {SqlSession 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);// 插入员工信息int result = mapper.insertWorker(worker);if (result > 0) {System.out.println("插入成功");} else {System.out.println("插入失败");}System.out.println(worker.toString());// 提交当前会话,将所有待处理的变更持久化到数据库中session.commit();session.close();}
  1. 插入成功应该会在控制台返回如下内容:
2024-10-09 00:09:20,309 [main] DEBUG [com.itheima.dao.WorkerMapper.insertWorker] - ==>  Preparing: INSERT INTO mybatis.tb_worker(name,sex,age,worker_id) VALUES(?,?,?,?)
2024-10-09 00:09:20,338 [main] DEBUG [com.itheima.dao.WorkerMapper.insertWorker] - ==> Parameters: 赵六(String),(String), 36(Integer), 1004(String)
2024-10-09 00:09:20,340 [main] DEBUG [com.itheima.dao.WorkerMapper.insertWorker] - <==    Updates: 1
插入成功
Worker{id=4, name='赵六', age=36, sex='女', worker_id='1004'}

@Update注解

@Update注解用于映射更新语句,下面通过实现员工信息的修改案例来说一说这个注解该如何使用。

  1. WorkerMapper接口中添加更新tb_worker表中数据的方法,并在方法上添加@Update注解,具体代码如下:
@Update("UPDATE mybatis.tb_worker SET name=#{name} WHERE id=#{id}")int updateWorker(Worker worker);
  1. 为了验证上述配置,在测试类MyBatisTest中添加测试方法updateWorkerTest()方法,具体代码如下:
    @Testpublic void updateWorkerTest() {SqlSession session = MyBatisUtils.getSession();Worker worker = new Worker();worker.setId(4);worker.setName("李华");worker.setAge(28);WorkerMapper mapper = session.getMapper(WorkerMapper.class);// 更新员工信息int result = mapper.updateWorker(worker);if (result > 0) {System.out.println("更新成功");System.out.println("成功更新"+result+"条数据!");} else {System.out.println("更新失败");}System.out.println(worker.toString());// 提交事务session.commit();// 关闭sessionsession.close();}
  1. 输出结果应该是这样的:
2024-10-09 02:00:51,237 [main] DEBUG [com.itheima.dao.WorkerMapper.updateWorker] - ==>  Preparing: UPDATE mybatis.tb_worker SET name=? WHERE id=?
2024-10-09 02:00:51,262 [main] DEBUG [com.itheima.dao.WorkerMapper.updateWorker] - ==> Parameters: 李华(String), 4(Integer)
2024-10-09 02:00:51,268 [main] DEBUG [com.itheima.dao.WorkerMapper.updateWorker] - <==    Updates: 1
更新成功
成功更新1条数据!
Worker{id=4, name='李华', age=28, sex='null', worker_id='null'}

@Delete注解

@Delete注解用于映射删除语句,实现数据库信息的删除,为具体演示,我们通过实现员工信息删除的案例如下:

  1. WorkerMapper接口中添加删除数据库中数据的方法,并在方法上添加@Delete注解标注的deleteWorker()方法时,@Delete注解中映射的删除语句将会被执行:
@Delete("DELETE FROM mybatis.tb_worker WHERE id=#{id}")int deleteWorker(int id);
  1. 为了验证上述配置,我们在测试类中编写方法deleteWorkerTest()方法,具体代码如下:
@Testpublic void deleteWorkerTest() {SqlSession session = MyBatisUtils.getSession();WorkerMapper mapper = session.getMapper(WorkerMapper.class);// 删除员工信息int result = mapper.deleteWorker(4);if (result > 0) {System.out.println("删除成功");System.out.println("成功删除"+result+"条数据!");} else {System.out.println("删除失败");}// 提交事务session.commit();//关闭sessionsession.close();}
  1. 输出结果应该是这样的:
2024-10-09 02:18:22,753 [main] DEBUG [com.itheima.dao.WorkerMapper.deleteWorker] - ==>  Preparing: DELETE FROM mybatis.tb_worker WHERE id=?
2024-10-09 02:18:22,783 [main] DEBUG [com.itheima.dao.WorkerMapper.deleteWorker] - ==> Parameters: 4(Integer)
2024-10-09 02:18:22,785 [main] DEBUG [com.itheima.dao.WorkerMapper.deleteWorker] - <==    Updates: 1
删除成功
成功删除1条数据!

@Param注解

@Param注解的功能是指定SQL语句中的参数,通常用于SQL语句中参数比较多的情况。下面通过根据员工的id和姓名查询员工信息的案例来具体演示一下:

  1. WorkerMapper接口中添加多条件查询的方法,具体代码如下:
@Select("SELECT * FROM mybatis.tb_worker WHERE id=#{param01} AND name=#{param02}")Worker selectWorkerByWorkerId(@Param("param01") int id, @Param("param02") String name);
  1. 编写测试方法selectWorkerByWorkerIdTest(),具体代码如下:
@Testpublic void selectWorkerByWorkerIdTest() {SqlSession session = MyBatisUtils.getSession();WorkerMapper mapper = session.getMapper(WorkerMapper.class);// 查询id为3且姓名为王五的员工信息Worker worker = mapper.selectWorkerByWorkerId(3, "王五");System.out.println(worker.toString());session.close();}
  1. 正确输出结果应如下:
2024-10-09 02:28:12,311 [main] DEBUG [com.itheima.dao.WorkerMapper.selectWorkerByWorkerId] - ==>  Preparing: SELECT * FROM mybatis.tb_worker WHERE id=? AND name=?
2024-10-09 02:28:12,336 [main] DEBUG [com.itheima.dao.WorkerMapper.selectWorkerByWorkerId] - ==> Parameters: 3(Integer), 王五(String)
2024-10-09 02:28:12,351 [main] DEBUG [com.itheima.dao.WorkerMapper.selectWorkerByWorkerId] - <==      Total: 1
Worker{id=3, name='王五', age=26, sex='男', worker_id='1003'}

基于注解的关联查询

MyBatis提供了@Results、@Result、@One和@Many等注解用于表之间的关联查询。

一对一查询

MyBatis中使用@One注解实现数据表的一对一关联查询,一下通过已有的tb_idcardtb_person数据表为例,感受基于@One注解实现tb_person数据表之间的一对一关联查询。

  1. 在项目的com.itheima.dao包下创建IdCardMapper接口,并再该接口中编写一个selectIdCardById()方法,用于通过id查询人员对应的身份证信息,具体代码如下:
package com.itheima.dao;import com.itheima.pojo.IdCard;
import org.apache.ibatis.annotations.Select;/*** @author Zhang*/
public interface IdCardMapper {@Select("select * from mybatis.tb_idcard where id = #{id}")IdCard findIdCardById(int id);
}
  1. 在项目的com.itheima.dao包下创建PersonMapper接口,再改接口中编写selectPersonById()方法,通过id查询人员信息。具体代码如下:
package com.itheima.dao;import com.itheima.pojo.Person;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;/*** @author Zhang*/
public interface PersonMapper {@Select("select * from mybatis.tb_person where id = #{id}")// 配置结果映射,将数据库查询结果映射到实体类属性@Results({@Result(// 指定表中的列名,数据库中的名字column = "card_id",// 指定POJO类中的属性名,属性名,如果起了别名要匹配POJO的属性名property = "card",// 配置一对一关联关系,指定关联属性card的值是通过哪个方法获得的one = @One(select = "com.itheima.dao.IdCardMapper.selectIdCardById"))})Person selectPersonById(int id);
}
  1. 在核心配置文件中引入这两个Mapper接口,具体引入代码如下:
<mapper class="com.itheima.dao.PersonMapper"/>
<mapper class="com.itheima.dao.IdCardMapper"/>
  1. 为了验证上述配置,我们在测试类中编写测试方法selectPersonByIdTest(),具体代码如下:
	@Testpublic void selectPersonByIdTest() {SqlSession session = MyBatisUtils.getSession();PersonMapper mapper = session.getMapper(PersonMapper.class);// 查询id为1的人员信息Person person = mapper.selectPersonById(1);System.out.println(person.toString());session.close();}
  1. 正确结果应该输出如下信息:
2024-10-09 15:51:19,147 [main] DEBUG [com.itheima.dao.PersonMapper.selectPersonById] - ==>  Preparing: select * from mybatis.tb_person where id = ?
2024-10-09 15:51:19,175 [main] DEBUG [com.itheima.dao.PersonMapper.selectPersonById] - ==> Parameters: 1(Integer)
2024-10-09 15:51:19,226 [main] DEBUG [com.itheima.dao.PersonMapper.selectPersonById] - <==      Total: 1
2024-10-09 15:51:19,228 [main] DEBUG [com.itheima.dao.IdCardMapper.selectIdCardById] - ==>  Preparing: select * from mybatis.tb_idcard where id = ?
2024-10-09 15:51:19,228 [main] DEBUG [com.itheima.dao.IdCardMapper.selectIdCardById] - ==> Parameters: 1(Integer)
2024-10-09 15:51:19,230 [main] DEBUG [com.itheima.dao.IdCardMapper.selectIdCardById] - <==      Total: 1
Person{id=1, name='Rose', age=22, sex='女', card=IdCard{id=1, code='152221198711020624'}}

一对多查询

MyBatis使用@Many注解实现数据表的一对多关联查询,以tb_usertb_orders数据表为例,讲解基于@Many注解配置实现tb_usertb_orders数据表之间的一对多关联查询。

  1. 在项目的com.itheima.dao包下创建OrdersMapper接口,并编写selectOrdersByUserId()方法,通过user_id查询用户对应订单信息,具体代码如下:
package com.itheima.dao;import com.itheima.pojo.Orders;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;import java.util.List;/*** @author Zhang*/
public interface OrdersMapper {@Select("select * from mybatis.tb_orders where user_id = #{id}")// id属性表示是否为主键, 主键为true, 否则不用写或为false@Results({@Result(id = true, column = "id", property = "id"),@Result(column = "number", property = "number")})List<Orders> selectOrdersByUserId(int user_id);
}
  1. 在项目的com.itheima.dao包下创建UsersMapper接口,并编写selectUserById()方法,通过id查询用户信息,具体代码如下:
package com.itheima.dao;import com.itheima.pojo.Users;
import org.apache.ibatis.annotations.Many;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;/*** @author Zhang*/
public interface UsersMapper {@Select("select * from mybatis.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.itheima.dao.OrdersMapper.selectOrdersByUserId"))})Users selectUserById(int id);
}
  1. 将这两个Mapper引入到核心加载配置文件中,代码如下:
        <mapper class="com.itheima.dao.OrdersMapper"/><mapper class="com.itheima.dao.UsersMapper"/>
  1. 为了验证上述配置,我们在测试类中添加selectUserByIdTest()方法,代码如下:
	@Testpublic void selectUserByIdTest() {SqlSession session = MyBatisUtils.getSession();UsersMapper mapper = session.getMapper(UsersMapper.class);// 查询id为1的人的信息Users users = mapper.selectUserById(1);System.out.println(users.toString());session.close();}
  1. 正确的查询结果应如下:
2024-10-10 05:01:32,472 [main] DEBUG [com.itheima.dao.UsersMapper.selectUserById] - ==>  Preparing: select * from mybatis.tb_user where id = ?
2024-10-10 05:01:32,501 [main] DEBUG [com.itheima.dao.UsersMapper.selectUserById] - ==> Parameters: 1(Integer)
2024-10-10 05:01:32,563 [main] DEBUG [com.itheima.dao.UsersMapper.selectUserById] - <==      Total: 1
2024-10-10 05:01:32,565 [main] DEBUG [com.itheima.dao.OrdersMapper.selectOrdersByUserId] - ==>  Preparing: select * from mybatis.tb_orders where user_id = ?
2024-10-10 05:01:32,565 [main] DEBUG [com.itheima.dao.OrdersMapper.selectOrdersByUserId] - ==> Parameters: 1(Integer)
2024-10-10 05:01:32,571 [main] DEBUG [com.itheima.dao.OrdersMapper.selectOrdersByUserId] - <==      Total: 2
Users{id=1, username='小明', address='北京', ordersList=[Orders{id=1, number='1000011', productList=null}, Orders{id=2, number='1000012', productList=null}]}

多对多查询

在数据库中,表与表之间的多对多关联关系通常使用一个中间表来维护,以订单表tb_orders和商品表tb_product为例,这两个表之间的关联关系使用了一个中间表tb_ordersitem来维护,订单表tb_orders和商品表tb_product都与中间表tb_ordersitem形成了一对多关系。

下面基于Orders类、Product类,以订单表tb_orders、商品表tb_product和中间表tb_ordersitem为例,详细讲解tb_orderstb_product数据表之间基于注解的多对多关联查询,具体步骤如下:

  1. 在项目的com.itheima.dao包下创建ProductMapper接口,在该接口编写selectProductByOrdersId()方法,通过user_id查询用户对应的订单信息。ProductMapper接口的具体代码如下所示:
package com.itheima.dao;import com.itheima.pojo.Product;
import org.apache.ibatis.annotations.Select;import java.util.List;/*** @author Zhang*/
public interface ProductMapper {@Select("SELECT * " +"FROM mybatis.tb_product " +"WHERE id IN (" +"SELECT mybatis.tb_ordersitem.product_id " +"FROM tb_ordersitem " +"WHERE orders_id = #{id})")List<Product> selectProductByOrdersId(int orders_id);
}
  1. 在项目的com.itheima.dao包下OrdersMapper接口里,添加selectOrdersById()方法,该方法用于通过id查询订单信息。selectOrdersById()方法具体代码如下:
	@Select("select * from mybatis.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.itheima.dao.ProductMapper.selectProductByOrdersId"))})Orders selectOrdersById(int id);
  1. 在核心配置文件中引入ProductMapper接口,由于OrdersMapper已经引入过了,所以无需再次引入,具体代码如下:
<mapper class="com.itheima.dao.ProductMapper"/>
  1. 为了验证上述配置,我们在测试类中编写selectOrdersByIdTest()方法,具体代码如下:
	@Testpublic void selectOrdersByIdTest() {SqlSession session = MyBatisUtils.getSession();OrdersMapper mapper = session.getMapper(OrdersMapper.class);// 查询id为3的订单信息Orders orders = mapper.selectOrdersById(3);System.out.println(orders.toString());session.close();}
  1. 查询结果应如下所示:
2024-10-10 05:37:53,947 [main] DEBUG [com.itheima.dao.OrdersMapper.selectOrdersById] - ==>  Preparing: select * from mybatis.tb_orders where id = ?
2024-10-10 05:37:53,976 [main] DEBUG [com.itheima.dao.OrdersMapper.selectOrdersById] - ==> Parameters: 3(Integer)
2024-10-10 05:37:54,024 [main] DEBUG [com.itheima.dao.OrdersMapper.selectOrdersById] - <==      Total: 1
2024-10-10 05:37:54,026 [main] DEBUG [com.itheima.dao.ProductMapper.selectProductByOrdersId] - ==>  Preparing: SELECT * FROM mybatis.tb_product WHERE id IN (SELECT mybatis.tb_ordersitem.product_id FROM tb_ordersitem WHERE orders_id = ?)
2024-10-10 05:37:54,027 [main] DEBUG [com.itheima.dao.ProductMapper.selectProductByOrdersId] - ==> Parameters: 3(Integer)
2024-10-10 05:37:54,035 [main] DEBUG [com.itheima.dao.ProductMapper.selectProductByOrdersId] - <==      Total: 1
Orders{id=3, number='1000013', productList=[Product{id=3, name='SSM框架整合实践入门', price=50.0, orders=null}]}

案例:基于MyBatis注解的学生管理程序

现在有一个学生表s_student和一个班级表c_class,其中,班级表c_class和学生表s_student是一对多的关系。学生表s_student和班级表c_class分别如下所示:

学生id(id)学生姓名(name)学生年龄(age)所属班级(cid)
1张三181
2李四182
3王五192
4赵六201
班级id(id)班级名称(classname)
1一班
2二班

需求如下,请使用MyBatis注解完成以下要求:

  1. MyBatis注解实现查询操作。根据上表在数据库分别创建一个学生表s_student和一个班级表c_class,并查询id为2的学生信息。

  2. MyBatis注解实现修改操作。将id为4的学生姓名修改为李雷,年龄修改为21。

  3. MyBatis注解实现一对多查询。查询出二班所有学生的信息。

代码实现:

需求如下,请使用MyBatis注解完成以下要求:

  1. MyBatis注解实现查询操作。根据上表在数据库分别创建一个学生表s_student和一个班级表c_class,并查询id为2的学生信息。
USE mybatis;
# 根据上表在数据库分别创建一个学生表`s_student`和一个班级表`c_class`
CREATE TABLE s_student(id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(32),age INT,cid INT
);CREATE TABLE c_class(id INT PRIMARY KEY AUTO_INCREMENT,classname VARCHAR(32)
);# 插入数据
INSERT INTO s_student VALUES ('1', '张三', 18, '1'),('2', '李四', 18, '2'),('3', '王五', 19, '2'),('4', '赵六', 20, '1');INSERT INTO c_class VALUES ('1', '一班'),('2', '二班');

com.itheima.pojo包下创建持久化类SStudentCClass,并添加数据库所有属性以及getter/settertoString()方法。

SStudent.java

package com.itheima.pojo;/*** @author Zhang*/
public class SStudent {private Integer id;private String name;private Integer age;private Integer cid;@Overridepublic String toString() {return "SStudent{" +"id=" + id +", name='" + name + '\'' +", age=" + age +", cid=" + cid +'}';}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public Integer getCid() {return cid;}public void setCid(Integer cid) {this.cid = cid;}
}

CClass.java

package com.itheima.pojo;/*** @author Zhang*/
public class CClass {private Integer id;private String classname;@Overridepublic String toString() {return "CClass{" +"id=" + id +", classname='" + classname + '\'' +'}';}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getClassname() {return classname;}public void setClassname(String classname) {this.classname = classname;}
}

设计DAO层接口,分别在com.itheima.dao下创建SStudentMapper,并在其中创建findStudentById()方法,为了后续使用,同时创建CClassMapper接口,代码如下:

SStudentMapper.java

package com.itheima.dao;import com.itheima.pojo.SStudent;
import org.apache.ibatis.annotations.Select;/*** @author Zhang*/
public interface SStudentMapper {@Select("SELECT * FROM mybatis.s_student WHERE id = #{id}")SStudent findStudentById(int id);
}

CClassMapper.java

package com.itheima.dao;/*** @author Zhang*/
public interface CClassMapper {
}

在核心配置文件中引入这两个Mapper,代码如下:

		<mapper class="com.itheima.dao.SStudentMapper"/><mapper class="com.itheima.dao.CClassMapper"/>

为了检查上述代码可行性,我们在测试类中编写findStudentByIdTest()方法,如下代码:

	@Testpublic void findStudentByIdTest() {SqlSession session = MyBatisUtils.getSession();SStudentMapper mapper = session.getMapper(SStudentMapper.class);// 查询id为2的学生信息SStudent student = mapper.findStudentById(2);System.out.println(student.toString());session.close();}

输出结果应该如下:

2024-10-10 06:32:23,491 [main] DEBUG [com.itheima.dao.SStudentMapper.findStudentById] - ==>  Preparing: SELECT * FROM mybatis.s_student WHERE id = ?
2024-10-10 06:32:23,523 [main] DEBUG [com.itheima.dao.SStudentMapper.findStudentById] - ==> Parameters: 2(Integer)
2024-10-10 06:32:23,543 [main] DEBUG [com.itheima.dao.SStudentMapper.findStudentById] - <==      Total: 1
SStudent{id=2, name='李四', age=18, cid=2}
  1. MyBatis注解实现修改操作。将id为4的学生姓名修改为李雷,年龄修改为21。

SStudentMapper接口中定义一个updateStudentById()方法,代码如下:

    @Update("UPDATE mybatis.s_student " +"SET name = #{name}, age = #{age} " +"WHERE id = #{id}")int updateStudentById(SStudent student);

为了验证上述配置是否生效,我们在测试类中编写updateStudentByIdTest()测试方法,代码如下:

    @Testpublic void updateStudentByIdTest() {SqlSession session = MyBatisUtils.getSession();SStudentMapper mapper = session.getMapper(SStudentMapper.class);// 更新id为4的学生信息SStudent student = new SStudent();student.setId(4);student.setName("李雷");student.setAge(21);int result = mapper.updateStudentById(student);if (result > 0) {System.out.println("更新成功");} else {System.out.println("更新失败");}System.out.println(student.toString());session.commit();session.close();}

结果应当如下:

2024-10-10 06:43:47,484 [main] DEBUG [com.itheima.dao.SStudentMapper.updateStudentById] - ==>  Preparing: UPDATE mybatis.s_student SET name = ?, age = ? WHERE id = ?
2024-10-10 06:43:47,512 [main] DEBUG [com.itheima.dao.SStudentMapper.updateStudentById] - ==> Parameters: 李雷(String), 21(Integer), 4(Integer)
2024-10-10 06:43:47,513 [main] DEBUG [com.itheima.dao.SStudentMapper.updateStudentById] - <==    Updates: 1
更新成功
SStudent{id=4, name='李雷', age=21, cid=null}
  1. MyBatis注解实现一对多查询。查询出二班所有学生的信息。

要查询二班所有学生信息,需要让s_student表中的c_id去链接c_class表中的id项。

我们先在SStudentMapper接口中写一个selectStudentByCid()方法,代码如下:

	@Select("SELECT * FROM mybatis.s_student WHERE cid = #{cid}")@Results({@Result(id = true, column = "id", property = "id"),@Result(column = "name", property = "name"),@Result(column = "age", property = "age")})List<SStudent> selectStudentByCid(int cid);

然后在CClassMapper接口中写一个selectStudentByClassname()方法,代码如下:

package com.itheima.dao;import com.itheima.pojo.CClass;
import org.apache.ibatis.annotations.Many;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;/*** @author Zhang*/
public interface CClassMapper {@Select("SELECT * FROM mybatis.c_class WHERE classname = #{classname}")@Results({@Result(column = "classname", property = "classname"),@Result(column = "id", property = "sStudentList",many = @Many(select = "com.itheima.dao.SStudentMapper.selectStudentByCid"))})CClass selectStudentByClassname(String classname);
}

随后在CClass的POJO持久化类中增加List<SStudent>以方便操作接收到的SStudent表中的数据,完整CClass.java内容如下:

package com.itheima.pojo;import java.util.List;/*** @author Zhang*/
public class CClass {private Integer id;private String classname;private List<SStudent> sStudentList;@Overridepublic String toString() {return "CClass{" +"id=" + id +", classname='" + classname + '\'' +", sStudentList=" + sStudentList +'}';}public List<SStudent> getsStudentList() {return sStudentList;}public void setsStudentList(List<SStudent> sStudentList) {this.sStudentList = sStudentList;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getClassname() {return classname;}public void setClassname(String classname) {this.classname = classname;}
}

为了检验我们上述方法是否可以实现需求,我们在测试类中增加selectStudentByClassnameTest()方法,代码如下:

    @Testpublic void selectStudentByClassnameTest() {SqlSession session = MyBatisUtils.getSession();CClassMapper mapper = session.getMapper(CClassMapper.class);// 查询班级名为"二班"的学生信息CClass cClass = mapper.selectStudentByClassname("二班");System.out.println(cClass.toString());session.close();}

输出结果应该是这样的:

2024-10-10 07:23:44,138 [main] DEBUG [com.itheima.dao.CClassMapper.selectStudentByClassname] - ==>  Preparing: SELECT * FROM mybatis.c_class WHERE classname = ?
2024-10-10 07:23:44,169 [main] DEBUG [com.itheima.dao.CClassMapper.selectStudentByClassname] - ==> Parameters: 二班(String)
2024-10-10 07:23:44,219 [main] DEBUG [com.itheima.dao.CClassMapper.selectStudentByClassname] - <==      Total: 1
2024-10-10 07:23:44,221 [main] DEBUG [com.itheima.dao.SStudentMapper.selectStudentByCid] - ==>  Preparing: SELECT * FROM mybatis.s_student WHERE cid = ?
2024-10-10 07:23:44,221 [main] DEBUG [com.itheima.dao.SStudentMapper.selectStudentByCid] - ==> Parameters: 2(Integer)
2024-10-10 07:23:44,223 [main] DEBUG [com.itheima.dao.SStudentMapper.selectStudentByCid] - <==      Total: 2
CClass{id=null, classname='二班', sStudentList=[SStudent{id=2, name='李四', age=18, cid=2}, SStudent{id=3, name='王五', age=19, cid=2}]}

本章小结

本章主要讲解了MyBatis的注解开发。首先介绍了基于注解的单表操作数据库的常用注解,包括@Insert、@Update、@Select、@Delete以及@Param注解等;然后讲解了基于注解的关联查询,包括一对一查询@One、一对多查询以及多对多查询@Many,在MyBatis框架中,这些注解十分的重要,熟练地掌握他们可以大大的提高开发的效率。


http://www.mrgr.cn/news/46942.html

相关文章:

  • Redis复制(replica)
  • 单体 vs 微服务 怎么选?
  • 稀疏子空间聚类 SSC(Sparse Subspace Clustering)
  • OPT: Open Pre-trained Transformer语言模型
  • Vue 常用指令详解(附代码实例)
  • Web前端界面开发
  • Python | Leetcode Python题解之第467题环绕字符串中唯一的子字符串
  • Dockerfile搭建环境案例
  • npm install报错一堆sass gyp ERR!
  • 解决html2canvas图片模糊不清,超出一页长截图问题
  • python爬虫 - 数据提取
  • 【无人水面艇路径跟随控制10】(Matlab)USV代码阅读:testUSV仿真无人水面艇在一定时间内的运动,使用欧拉法对状态进行积分,并绘制仿真结果
  • Day2 IDEA
  • C#中,虚方法(virtual) 和 抽象方法(abstract)的应用说明
  • Elasticsearch 索引备份
  • python xml的读取和写入
  • 【centos 虚拟机】kvm权限报错解决 gid:107
  • Unity3D 动画回调函数详解
  • 怎么把mov格式的视频转换mp4?视频格式转换就看这5招!(值得收藏)
  • 喜讯!华秋电子宣布完成新一轮3.1亿元融资
  • 引领数字化转型新潮流:The Open Group 2024生态系统架构·可持续发展年度大会邀您共襄盛举
  • 从零开始搭建一个node.js后端服务项目
  • 二叉树搜索
  • 解决 MySQL 连接数过多导致的 SQLNonTransientConnectionException 问题
  • 负载均衡(Load Balancing)
  • 华为OD机试真题-最佳对手-2024年OD统一考试(E卷)