MyBatis的注解开发
基于注解的单表增删改查
在实际开发中,大量的XML配置文件的编写是非常繁琐的,为此,MyBatis提供了更加简便的基于注解的配置方式。
@Select注解
掌握@Select注解,能够使用@Select注解进行查询
演示@Select注解的使用,该案例要求根据员工的id查找员工信息,案例具体实现步骤如下。
-
建表:在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 ); INSERT INTO tb_worker(name,age,sex,worker_id)VALUES('张三',32,'女',1001);
-
创建类:创建持久化类Worker,在Worker类中定义id、员工姓名、年龄、性别、工号等属性以及属性对应的getter/setter方法。
public class Worker { private Integer id; private String name; private Integer age; private String sex; private String worker_id; // 省略getter/setter方法 @Override public String toString() { return "Worker{" + "id=" + id + ", name=" + name + ", age=" + age + ", sex=" + sex + ", worker_id=" + worker_id + '}'; }}
-
编写查询方法:创建WorkerMapper接口,用于编写@Select注解映射的select查询方法。
package com.itheima.dao; import com.itheima.pojo.Worker; import org.apache.ibatis.annotations.Select; public interface WorkerMapper { @Select("select * from tb_worker where id = #{id}") Worker selectWorker(int id); }
-
加载配置文件:在核心配置文件mybatis-config.xml中的元素下引入WorkerMapper接口,将WorkerMapper.java接口加载到核心配置文件中。
<mapper class="com.itheima.dao.WorkerMapper"/>
-
编写测试方法:在测试类MyBatisTest中,编写测试方法findWorkerByIdTest()。
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.toString()); // 3.关闭SqlSession session.close(); }
@Insert注解
掌握@Insert注解,能够使用@Insert注解进行数据插入
演示@Insert注解的使用,要求实现员工信息的插入,案例具体实现步骤如下。
-
添加注解:在WorkerMapper接口中添加向tb_worker数据表插入数据的方法insertWorker(),并在方法上添加@Insert注解。
@Insert("insert into tb_worker(name,age,sex,worker_id)" +"values(#{name},#{age},#{sex},#{worker_id})") int insertWorker(Worker worker);
-
编写测试类:在测试类MyBatisTest中,编写测试方法insertWorkerTest()。
public void insertWorkerTest() { // 1.生成SqlSession对象 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); // 2.插入员工信息 int result = mapper.insertWorker(worker); // 输出语句省略... session.commit(); session.close(); // 3.关闭SqlSession }
@Update注解
掌握@Update注解,能够使用@Update注解进行数据更新
-
添加注解:在WorkerMapper接口中添加更新tb_worker表中数据的方法,并在方法上添加@Update注解。
@Update("update tb_worker set name = #{name},age = #{age} " +"where id = #{id}") int updateWorker(Worker worker);
-
编写测试类:测试类MyBatisTest中,编写测试方法updateWorkerTest()。
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); // 输出语句省略... session.commit(); session.close(); // 3.关闭SqlSession }
@Delete注解
掌握@Delete注解,能够使用@Delete注解删除数据
-
添加注解:在WorkerMapper接口中添加删除数据库中数据的方法,并在方法上添加@Delete注解。
@Delete("delete from tb_worker where id = #{id}") int deleteWorker(int id);
-
编写测试类:在测试类MyBatisTest中,编写测试方法deleteWorkerTest()。
public void deleteWorkerTest() { SqlSession session = MyBatisUtils.getSession(); // 1.生成SqlSession对象 WorkerMapper mapper = session.getMapper(WorkerMapper.class); // 2.删除员工信息 int result = mapper.deleteWorker(4); if(result>0){ System.out.println("成功删除"+result+"条数据"); }else { System.out.println("删除数据失败");} session.commit(); session.close(); // 3.关闭SqlSession }
@Param注解
-
添加注解:在WorkerMapper接口中添加多条件查询的方法。
@Select("select * from tb_worker where id = #{param01} and name = #{param02}") Worker selectWorkerByIdAndName(@Param("param01") int id, @Param("param02") String name);
-
编写测试类:在测试类MyBatisTest中,编写测试方法selectWorkerByIdAndNameTest()。
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.toString()); session.close(); }
基于注解的关联查询
一对一查询
基于注解@One实现tb_idcard和tb_person数据表之间的一对一关联查询
-
创建持久化类:创建dCard类和Person类作为持久类。
null
-
编写接口方法:(1)创建IdCardMapper接口,在该接口中编写selectIdCardById()方法,通过id查询人员对应的身份证信息。
package com.itheima.dao; import com.itheima.pojo.IdCard; import org.apache.ibatis.annotations.Select; public interface IdCardMapper { @Select("select * from tb_idcard where id=#{id}") IdCard selectIdCardById(int id); }
-
编写接口方法:(2)在项目的com.itheima.dao包下创建PersonMapper接口,在该接口中编写selectPersonById(),通过id查询人员信息。
package com.itheima.dao; public interface PersonMapper { @Select("select * from tb_person where id=#{id}") @Results({@Result(column = "card_id",property = "card", one = @One(select = "com.itheima.dao.IdCardMapper.selectIdCardById"))}) Person selectPersonById(int id); }
@Result注解的三个属性及含义:
(1)property属性用来指定关联属性,这里为card。
(2)column属性用来指定关联的数据库表中的字段,这里为card_id。
(3)one属性用来指定数据表之间属于哪种关联关系,通过@One注解表明数据表tb_idcard和tb_person之间是一对一关联关系。
-
引入接口:在核心配置文件mybatis-config.xml中的元素下引入IdCardMapper和PersonMapper接口。
<mapper class="com.itheima.dao.IdCardMapper"/> <mapper class="com.itheima.dao.PersonMapper"/>
元素引入XML文件顺序:
由于mybatis-config.xml文件中的扫描方式是从上往下扫描,所以元素下引入IdCardMapper和PersonMapper接口的位置,必须在引入IdCardMapper.xml和PersonMapper.xml文件位置前面,否则程序将会首先读取到引入的IdCardMapper.xml和PersonMapper.xml文件,程序将会报错。
-
编写测试类:在测试类MyBatisTest中,编写测试方法selectPersonByIdTest()。
public void selectPersonByIdTest() { // 1.通过工具类生成SqlSession对象 SqlSession session = MyBatisUtils.getSession(); PersonMapper mapper = session.getMapper(PersonMapper.class); // 2.查询id为1的人员的信息 Person person = mapper.selectPersonById(2); System.out.println(person.toString()); session.close(); // 3.关闭SqlSession }
一对多查询
-
创建持久化类:创建Users类和Orders类作为持久类。
null
-
编写接口方法:(1)创建OrdersMapper接口,在该接口中编写selectOrdersByUserId()方法,通过user_id查询用户对应的订单信息。
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") }) List<Orders> selectOrdersByUserId(int user_id); }
-
编写接口方法:(2)创建UsersMapper接口,在该接口中编写selectUserById()方法,通过id查询用户信息。
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.itheima.dao.OrdersMapper.selectOrdersByUserId"))}) Users selectUserById(int id); }
-
引入接口:在核心配置文件mybatis-config.xml中的元素下引入UsersMapper和OrdersMapper接口。
<mapper class="com.itheima.dao.UsersMapper"/> <mapper class="com.itheima.dao.OrdersMapper"/>
元素引入XML文件顺序:
由于mybatis-config.xml文件中的扫描方式是从上往下扫描,所以元素下引入UsersMapper和OrdersMapper接口的位置,必须在引入UsersMapper.xml和OrdersMapper.xml文件位置前面,否则程序将会首先读取到引入的UsersMapper.xml和OrdersMapper.xml文件,程序将会报错。
-
编写测试类:在测试类MyBatisTest中,编写测试方法selectUserByIdTest()。
public void selectUserByIdTest() { // 1.通过工具类生成SqlSession对象 SqlSession session = MyBatisUtils.getSession(); UsersMapper mapper = session.getMapper(UsersMapper.class); // 2.查询id为1的人的信息 Users users = mapper.selectUserById(1); System.out.println(users.toString()); session.close(); }
多对多查询
多对多关联使用中间表:
在数据库中,表与表之间的多对多关联关系通常使用一个中间表来维护,以4.4节中使用的订单表tb_orders和商品表tb_product为例,这两个表之间的关联关系使用了一个中间表tb_ordersitem来维护,订单表tb_orders和商品表tb_product,都与中间表tb_ordersitem形成了一对多关联关系,即中间表tb_ordersitem将订单表tb_orders和商品表tb_product拆分成了两个一对多的关联关系。
-
在订单持久化类(Orders.java)中增加商品集合的属性及其对应的getter/setter方法,并修改Orders类和Product类中的toString()方法。
@Override public String toString() {return "Orders{" + "id=" + id + ", number=" + number + ", productList=" + productList + '}’;} @Override public String toString() {return "Product{" + "id=" + id + ", name=" + name +", price=" + price + '}'; }
-
(1)创建ProductMapper接口,在该接口中编写selectProductByOrdersId()方法,通过user_id查询用户对应的订单信息。
public interface ProductMapper {
@Select("select * from tb_product where id in
(select product_id from tb_ordersitem where orders_id = #{id} )")
List<Product> selectProductByOrdersId(int orders_id);
}
- (2)在OrdersMapper接口中添加selectOrdersById()方法,该方法用于通过id查询订单信息。
@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.itheima.dao.ProductMapper.selectProductByOrdersId"))})
Orders selectOrdersById(int id);
- 在核心配置文件mybatis-config.xml中的元素下引入ProductMapper和OrdersMapper接口,将这两个接口加载到核心配置文件中。
<mapper class="com.itheima.dao.ProductMapper"/>
<mapper class="com.itheima.dao.OrdersMapper "/>
元素引入XML文件的顺序:
注意:由于mybatis-config.xml文件中的扫描方式是从上往下扫描,所以元素下引入ProductMapper和OrdersMapper接口的位置,必须在引入ProductMapper.xml和OrdersMapper.xml文件位置前面,否则程序将会首先读取到引入的ProductMapper.xml和OrdersMapper.xml文件,程序将会报错。
-
在测试类MyBatisTest中,编写测试方法selectOrdersByIdTest(),查询id为3的订单的信息。
public void selectOrdersByIdTest() { // 1.通过工具类生成SqlSession对象 SqlSession session = MyBatisUtils.getSession(); OrdersMapper mapper = session.getMapper(OrdersMapper.class); // 2.查询id为3的订单的信息 Orders orders = mapper.selectOrdersById(3); System.out.println(orders.toString()); session.close(); }