01_MyBatis注解开发

mybatis注解开发 - 图1这几年来注解开发越来越流行,MyBatis也可以使用注解开发方式,这样就可以减少编写
Mapper映射文件了。
mybatis注解开发 - 图2MyBatis常用注解
mybatis注解开发 - 图3@Insert:实现新增
mybatis注解开发 - 图4@Update:实现更新@Delete:实现删除
mybatis注解开发 - 图5@Select:实现查询
mybatis注解开发 - 图6@Result:实现结果集封装
mybatis注解开发 - 图7@Results:可以与@Result 一起使用,封装多个结果集
mybatis注解开发 - 图8@One:实现一对一结果集封装
mybatis注解开发 - 图9@Many:实现一对多结果集封装

02_MyBatis注解操作CRUD

mybatis注解开发 - 图10@Insert、@Update、@Delete、@Select
mybatis注解开发 - 图11DAO接口

  1. public interface IEmployeeDao {
  2. @Select("select * from tb_employee")
  3. List < Employee > selectEmployeeList();
  4. @Insert("insert into tb_employee(ename,salary,dno) values(#{ename},#{salary},#
  5. {dno})")
  6. int insertEmployee(Employee employee);
  7. @Delete("delete from tb_employee where eid = #{eid}")
  8. int deleteEmployeeById(Long id);
  9. @Update("update tb_employee set ename = #{ename} where eid = #{eid}")
  10. int updateEmployee(Employee employee);
  11. }

mybatis注解开发 - 图12代码测试

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. @ContextConfiguration(locations = {
  3. "classpath:/spring.xml"}
  4. )
  5. public class IEmployeeDaoTest {
  6. @Resource
  7. private IEmployeeDao employeeDao;
  8. @Test
  9. public void selectEmployeeList() {
  10. List<Employee> employeeList = employeeDao.selectEmployeeList();
  11. System.out.println(employeeList);
  12. }
  13. @Test
  14. public void insertEmployee() {
  15. Employee employee = new Employee();
  16. employee.setEname("邱邱");
  17. employee.setSalary(10000.0);
  18. employee.setDno(1L);
  19. int i = employeeDao.insertEmployee(employee);
  20. System.out.println(i);
  21. }
  22. @Test
  23. public void deleteEmployeeById() {
  24. int i = employeeDao.deleteEmployeeById(0L);
  25. System.out.println(i);
  26. }
  27. @Test
  28. public void updateEmployee() {
  29. Employee employee = new Employee();
  30. employee.setEid(2L);
  31. employee.setEname("qzw");
  32. int i = employeeDao.updateEmployee(employee);
  33. System.out.println(i);
  34. }
  35. }

03_复杂关系映射注解说明

mybatis注解开发 - 图13实现复杂关系映射之前我们可以在映射文件中通过配置来实现, 在使用注解开发时我们需要借助@Results 注解, @Result 注解, @One 注解, @Many 注解。
mybatis注解开发 - 图14复杂关系映射的注解说明
mybatis注解开发 - 图15@Results 注解
mybatis注解开发 - 图16代替的是标签
mybatis注解开发 - 图17该注解中可以使用单个@Result 注解,也可以使用@Result 集合@Results({@Result(), @Result() })或@Results(@Result())
mybatis注解开发 - 图18@Result 注解
mybatis注解开发 - 图19代替了 标签和标签
mybatis注解开发 - 图20@Result 中 属性介绍:
mybatis注解开发 - 图21id 是否是主键字段
mybatis注解开发 - 图22column 数据库的列名
mybatis注解开发 - 图23property 需要装配的属性名

  1. ![](https://cdn.nlark.com/yuque/0/2020/png/8396355/1608199187036-3cb8135f-03c5-49cf-ba83-2663c6548ef1.png#align=left&display=inline&height=19&margin=%5Bobject%20Object%5D&originHeight=19&originWidth=4&status=done&style=none&width=4)one 需要使用的@One 注解(@Result(one=@One)()))<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/8396355/1608199187036-3cb8135f-03c5-49cf-ba83-2663c6548ef1.png#align=left&display=inline&height=19&margin=%5Bobject%20Object%5D&originHeight=19&originWidth=4&status=done&style=none&width=4)many 需要使用的@Many 注解(@Result(many=@many)()))<br />![](https://cdn.nlark.com/yuque/0/2020/png/8396355/1608199186795-50acb273-8b08-4539-b0a9-824d141979f6.png#align=left&display=inline&height=19&margin=%5Bobject%20Object%5D&originHeight=19&originWidth=4&status=done&style=none&width=4)@One 注解(一对一)<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/8396355/1608199185772-1df04ffe-531b-437c-a5fc-1b3096b31175.png#align=left&display=inline&height=15&margin=%5Bobject%20Object%5D&originHeight=19&originWidth=5&status=done&style=none&width=4)代替了<assocation>标签,是多表查询的关键,在注解中用来指定子查询返回单一对象。<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/8396355/1608199185772-1df04ffe-531b-437c-a5fc-1b3096b31175.png#align=left&display=inline&height=15&margin=%5Bobject%20Object%5D&originHeight=19&originWidth=5&status=done&style=none&width=4)@One 注解属性介绍:<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/8396355/1608199187036-3cb8135f-03c5-49cf-ba83-2663c6548ef1.png#align=left&display=inline&height=19&margin=%5Bobject%20Object%5D&originHeight=19&originWidth=4&status=done&style=none&width=4)select 指定用来多表查询的 sqlmapper<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/8396355/1608199187036-3cb8135f-03c5-49cf-ba83-2663c6548ef1.png#align=left&display=inline&height=19&margin=%5Bobject%20Object%5D&originHeight=19&originWidth=4&status=done&style=none&width=4)![](https://cdn.nlark.com/yuque/0/2020/png/8396355/1608199186174-d3ad0513-922b-4014-a5da-6696177f8df8.png#align=left&display=inline&height=15&margin=%5Bobject%20Object%5D&originHeight=19&originWidth=5&status=done&style=none&width=4)fetchType 会覆盖全局的配置参数 lazyLoadingEnabled。<br />。使用格式:<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/8396355/1608199187036-3cb8135f-03c5-49cf-ba83-2663c6548ef1.png#align=left&display=inline&height=19&margin=%5Bobject%20Object%5D&originHeight=19&originWidth=4&status=done&style=none&width=4)@Result(column=" ",property="",one=@One(select=""))<br />![](https://cdn.nlark.com/yuque/0/2020/png/8396355/1608199186795-50acb273-8b08-4539-b0a9-824d141979f6.png#align=left&display=inline&height=19&margin=%5Bobject%20Object%5D&originHeight=19&originWidth=4&status=done&style=none&width=4)@Many 注解(多对一)<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/8396355/1608199185772-1df04ffe-531b-437c-a5fc-1b3096b31175.png#align=left&display=inline&height=15&margin=%5Bobject%20Object%5D&originHeight=19&originWidth=5&status=done&style=none&width=4)代替了<Collection>标签,是是多表查询的关键,在注解中用来指定子查询返回对象集合。<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/8396355/1608199187217-d1684e22-fd29-4394-8124-c5e1be4b378e.png#align=left&display=inline&height=15&margin=%5Bobject%20Object%5D&originHeight=19&originWidth=5&status=done&style=none&width=4)注意:聚集元素用来处理“一对多”的关系。需要指定映射的 Java 实体类的属性,属性的javaType (一般为 ArrayList)但是注解中可以不定义;<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/8396355/1608199185980-58a1b934-7a2d-4607-a706-d11286e372e3.png#align=left&display=inline&height=15&margin=%5Bobject%20Object%5D&originHeight=19&originWidth=5&status=done&style=none&width=4)使用格式:<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/8396355/1608199187036-3cb8135f-03c5-49cf-ba83-2663c6548ef1.png#align=left&display=inline&height=19&margin=%5Bobject%20Object%5D&originHeight=19&originWidth=4&status=done&style=none&width=4)@Result(property="",column="",many=@Many(select=""))

04_注解实现一对一延迟加载

mybatis注解开发 - 图24一个订单属于一个用户
mybatis注解开发 - 图25IOrderDao代码

  1. @Select("select * from tb_orders")
  2. @Results(id = "resultMap",value = {
  3. @Result(id = true , property = "customerId" ,column = "customerId",javaType = Long.class),
  4. @Result(property = "name" , column = "name" ,javaType = String.class ),
  5. @Result(property = "address" ,column = "address",javaType = String.class),
  6. @Result(property = "customer", javaType = Customer.class,
  7. one = @One(select = "com.qzw.dao.ICustomerDao.selectCustomerById",
  8. fetchType = FetchType.EAGER), column = "customerNo")
  9. })
  10. List<Order> selectOrderList();

mybatis注解开发 - 图26ICustomerDao代码

  1. @Select(value = "select * from tb_customer where customerId = #{customerId}")
  2. Customer selectCustomerById(Long customerId);


05_注解实现一对多延迟加载

mybatis注解开发 - 图27一个用户有多个订单
mybatis注解开发 - 图28ICustomerDao代码

  1. @Select(value = "select * from tb_customer") @Results(id = "resultMap",
  2. value = {
  3. @Result(id = true,property = "orderId",column = "orderId",javaType = Long.class),
  4. @Result(property = "state",column = "state",javaType = String.class),
  5. @Result(property = "orderList",column = "customerId", many = @Many(select="com.qzw.dao.IOrderDao.selectOrderListByCustomerId",fetchType = FetchType.LAZY))
  6. }
  7. )
  8. List<Customer> selectCustomerList();

mybatis注解开发 - 图29IOrderDao代码

  1. @Select("select * from tb_orders where customerNo = #{customerNo}")
  2. List<Order> selectOrderListByCustomerId(Long customerId);

06_ @lazy注解

1、@Lazy注解是什么

@Lazy注解用于标识bean是否需要延迟加载,源码如下:

  1. @Target({
  2. ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.FIELD
  3. })@ Retention(RetentionPolicy.RUNTIME)@ Documented
  4. public@ interface Lazy {
  5. /**
  6. * Whether lazy initialization should occur.
  7. */
  8. boolean value() default true;
  9. }

只有一个参数,默认是true,也就是说只要加了这个注解就会延迟加载

2、@Lazy注解怎么使用

没加注解之前主要容器启动就会实例化bean,如下:
AnnotationConfigApplicationContext applicationContext2 = new AnnotationConfigApplicationContext(MainConfig.class);
而加上@Lazy注解则必须在第一次调用的时候才会加载如下:

  1. /**
  2. * 定义一个bean对象
  3. * @return
  4. */
  5. @Scope@ Lazy@ Bean(value = "user0", name = "user0", initMethod = "initUser", destroyMethod = "destroyUser")
  6. public User getUser() {
  7. System.out.println("创建user实例");
  8. return new User("张三", 26);
  9. }

@Lazy注解注解的作用主要是减少springIOC容器启动的加载时间

解决循环依赖冲突

07_@dependsOn注解

指定在注入一个bean之后再注入此bean

注解在@Bean定义方法上

该例子使用方法方式定义了一个bean entityManager,并指出它依赖于bean transactionManager。虽然bean entityManager实例化过程中没有通过属性或者构造函数参数方式依赖于bean transactionManager,但是其过程中会牵涉到对transactionManager的使用,如果此时transactionManager没有被实例化,entityManager的实例化过程会失败。这就是一种典型的不通过属性或者构造方法参数方式依赖,但是实际上存在依赖的情况,这种情况正是注解@DependsOn的用武之地。

  1. @Bean(name = "entityManager")@ DependsOn("transactionManager")
  2. public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws Throwable {
  3. LocalContainerEntityManagerFactoryBean entityManager =
  4. new LocalContainerEntityManagerFactoryBean();
  5. // 省略无关的实现部分
  6. // ...
  7. return entityManager;
  8. }