Spring Boot学习笔记----mybatis注解(一)

淡淡的烟草味﹌ 2022-06-04 06:54 306阅读 0赞

之前使用jpa,感觉不错。不用涉及sql便可完成对数据库的增删改查。但项目组要求使用mybatis进行开发,也就用了。两者的区别在于,后者需要进行SQL语句的注解绑定。

网上搜到的mybatis资料,繁琐复杂,多是使用各种配置文件。这对不怎么用XML的开发者来说,简直是头大。因此,还是喜欢注解的方式来解决问题。尽管mybatis官网并不推荐这种方式。官网对于注解的方式,也只是星星点点,躲躲闪闪。

废话不再多说,奔主题。

mybatis如何进行数据库操作呢。需要以下5个步骤。(本文以MAVEN工程为例,开发环境为IDEA,数据库为MySql)
(1)添加Dependence
(2)创建数据库表实例entity。
(3)创建Dao接口,将SQL与方法进行绑定
(4)设置遍历Dao的地址(包名)
(5)使用Dao

我们通过一个实例来看一下整个过程。基于angular的阴影,我们以hero为例。

(1)添加Dependence

  1. <dependency>
  2. <groupId>org.mybatis.spring.boot</groupId>
  3. <artifactId>mybatis-spring-boot-starter</artifactId>
  4. <version>1.3.1</version>
  5. </dependency>

(2)创建数据库及其表

这是mybatis的硬伤。当然,网上也有博文讲解如何自动生成对应表,类似转基因了,暂且放下,之后再看。

在Application.properties中配置数据库链接,内容如下

  1. spring.datasource.url=jdbc:mysql://127.0.0.1:3306/db_hero
  2. spring.datasource.username=root
  3. spring.datasource.password=hero
  4. spring.datasource.driver-class-name=com.mysql.jdbc.Driver

创建语句如下

  1. CREATE SCHEMA `db_hero` ;
  2. CREATE TABLE `db_hero`.`hero` ( `id` INT NOT NULL AUTO_INCREMENT, `name` VARCHAR(45) NOT NULL, `age` INT NOT NULL, PRIMARY KEY (`id`));

(3)创建实体类

之前的博文中,有关于IDEA如何自动生成实体类的相关描述,这里不再啰嗦。

(4)创建Dao接口

从代码角度来看,Dao只是一个虚拟接口,但其作用至关重要。它是绑定数据库表,实体类,以及实务操作的枢纽。也是使用注解的关键所在。

先来看最简单的普通查询。使用最简单的增删改查注解。

  1. @Select()
  2. @Insert()
  3. @Update()
  4. @Delete()
  5. @Result()

我们来看个简单的例子

  1. package com.breakloop.mybatis.mapper;
  2. import com.breakloop.mybatis.entity.Hero;
  3. import org.apache.ibatis.annotations.*;
  4. import java.util.List;
  5. @Mapper
  6. public interface HeroMapper {
  7. @Insert("Insert into hero(name,age) values(#{name},#{age})")
  8. @Options(useGeneratedKeys=true, keyColumn="id", keyProperty="id")
  9. void addHero(Hero hero);
  10. @Update("update hero set name=#{name},age=#{age} where id=#{id}")
  11. void updateHero(Hero hero);
  12. @Select("select * from hero where name=#{name}")
  13. List<Hero> selectHeroByName(String name);
  14. @Select("select * from hero where age=#{age}")
  15. List<Hero> selectHeroByAge(int age);
  16. @Select("select * from hero where id=#{id}")
  17. List<Hero> selectHeroById(Long id);
  18. @Select("select * from hero")
  19. List<Hero> selectAll();
  20. @Delete("delete from hero where name=#{name}")
  21. void deleteHeroByName(String name);
  22. @Delete("delete from hero where age=#{age}")
  23. void deleteHeroByAge(int age);
  24. @Delete("delete from hero where id=#{id}")
  25. void deleteHeroById(Long id);
  26. //@Delete("delete from hero where name=#{name} and age=#{age}")
  27. //void deleteHero(Hero hero);
  28. @Delete("delete from hero where name=#{aa} and age=#{bb}")
  29. void deleteHero(@Param("aa") String name,@Param("bb") int age);
  30. @Delete("delete from hero")
  31. void deleteAll();
  32. }

需要注意的是

(a)需要使用#{实体类成员属性}跟列名进行绑定

(b)在添加数据时,对于自增列需要进行注解

  1. @Options(useGeneratedKeys=true, keyColumn="id", keyProperty="id")

(c)如果列名跟实体类成员属性名不同,对于Select,需要对结果进行绑定,使用@Result。

例如,Hero实体类中,sName对应name列,nAge代表age列。
那么,以selectHeroByName为例

  1. @Select("select * from hero where name=#{
  2. sName}")
  3. @Results( {
  4. @Result(id = true, property = "id", column = "id"), @Result(property = "nAge",column = "age"), @Result(property = "sName",column = "name") } ) List<Hero> selectHeroByName(String name);

(d)如果绑定的sql语句相同,将会报错。

这也是代码中屏蔽void deleteHero(Hero hero)方法的原因。该方法与void deleteHero(String sName,int nAge)方法所绑定的sql语句一致。

(e)对于@Param要多说几句。

如果传参不是实体类,或者参数数量大于1,则需要@Param。
如果不用@Param,即使传参名称与实体类属性名(或列名)一致,也会报错(执行方法时)。
错误案例如下

  1. @Delete("delete from hero where name=#{sName} and age=#{nAge}")
  2. void deleteHero(String sName,int nAge);

  1. @Delete("delete from hero where name=#{name} and age=#{age}")
  2. void deleteHero(String name,int age);

注:参考了博文
https://www.cnblogs.com/whisper527/p/6568028.html,但发现$的方式不被识别。不知道是什么原因。有知道的童鞋,还望指点。

(5)标记Dao所在Package

Dao既然如此重要,那么Application该如何找到它呢?有两种方式
(1)在每个Mapper Interface上添加@Mapper
(2)在Application类上添加@MapperScan(“com.breakloop.mybatis.mapper”),其中com.breakloop.mybatis.mapper为mapper所在包。
若存在多个,则可以使用数组的方式@MapperScan({“com.breakloop.mybatis.mapper”,”com.breakloop.mybatis.entity”})
建议使用第二种方式,不用逐个添加@Mapper

(6)使用Dao

在这里,我们只是简单的在controller中使用Dao,在Logger里打印结果。

  1. package com.breakloop.mybatis.controller;
  2. import com.breakloop.mybatis.entity.Hero;
  3. import com.breakloop.mybatis.mapper.HeroMapper;
  4. import org.slf4j.Logger;
  5. import org.slf4j.LoggerFactory;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.web.bind.annotation.RequestMapping;
  8. import org.springframework.web.bind.annotation.RestController;
  9. import java.util.List;
  10. @RestController
  11. public class HeroController {
  12. Logger logger= LoggerFactory.getLogger(HeroController.class);
  13. @Autowired
  14. HeroMapper mapper;
  15. @RequestMapping("/ShowLogger")
  16. public void ShowInLogger(){
  17. InsertCase();
  18. SelectCase();
  19. UpdateCase();
  20. DeleteCase();
  21. }
  22. public void InsertCase(){
  23. String name;
  24. for (int i = 0; i < 9; i++) {
  25. Hero hero=new Hero();
  26. hero.setAge(i);
  27. name="hero"+i;
  28. hero.setName(name);
  29. mapper.addHero(hero);
  30. logger.info("Insert Hero, Hero Name = "+name+", Age = "+i);
  31. }
  32. }
  33. public void SelectCase(){
  34. List<Hero> heroes=mapper.selectAll();
  35. int age=0;
  36. String name="hero1";
  37. Long id=2l;
  38. for (Hero item :
  39. heroes) {
  40. logger.info("Select All, Hero Name "+item.getName()+", Age = "+item.getAge());
  41. }
  42. heroes=mapper.selectHeroByAge(age);
  43. if(heroes.size()!=0){
  44. for (Hero item :
  45. heroes) {
  46. logger.info("Select Hero by Age = "+age+", Hero Name "+item.getName()+", Age = "+item.getAge());
  47. }
  48. }
  49. heroes=mapper.selectHeroByName(name);
  50. if(heroes.size()!=0){
  51. for (Hero item :
  52. heroes) {
  53. logger.info("Select Hero by Name = "+name+", Hero Name "+item.getName()+", Age = "+item.getAge());
  54. }
  55. }
  56. }
  57. public void UpdateCase(){
  58. List<Hero> heroes;
  59. Long id=0L;
  60. int age=10;
  61. String name="hero"+age;
  62. Hero hero=new Hero();
  63. hero.setAge(age);
  64. hero.setName(name);
  65. hero.setId(id);
  66. mapper.updateHero(hero);
  67. logger.info("Update Hero by Id = "+id+", Hero Name "+hero.getName()+", Age = "+hero.getAge());
  68. heroes=mapper.selectHeroById(id);
  69. if(heroes.size()!=0){
  70. for (Hero item :
  71. heroes) {
  72. logger.info("Select Hero by Id = "+id+", Hero Name "+item.getName()+", Age = "+item.getAge());
  73. }
  74. }
  75. }
  76. public void DeleteCase(){
  77. Long id=1l;
  78. String name="hero2";
  79. int age=3;
  80. List<Hero> heroes;
  81. Hero hero;
  82. mapper.deleteHeroById(id);
  83. logger.info("Delete Hero by Id = "+id);
  84. mapper.deleteHeroByName(name);
  85. logger.info("Delete Hero by Name = "+name);
  86. mapper.deleteHeroByAge(age);
  87. logger.info("Delete Hero by Age = "+age);
  88. //hero=new Hero();
  89. //hero.setName("hero4");
  90. //hero.setAge(4);
  91. //mapper.deleteHero(hero);
  92. //logger.info("Delete Hero by Age = 4 and Name = hero4");
  93. mapper.deleteHero("hero5",5);
  94. logger.info("Delete Hero by Age = 5 and Name = hero5");
  95. heroes=mapper.selectAll();
  96. if(heroes.size()!=0){
  97. for (Hero item :
  98. heroes) {
  99. logger.info("Select All, Hero Name "+item.getName()+", Age = "+item.getAge());
  100. }
  101. }
  102. mapper.deleteAll();
  103. heroes=mapper.selectAll();
  104. if(heroes.size()!=0){
  105. for (Hero item :
  106. heroes) {
  107. logger.info("Select All, Hero Name "+item.getName()+", Age = "+item.getAge());
  108. }
  109. }else {
  110. logger.info("No Hero");
  111. }
  112. }
  113. }

执行结果如下:

  1. 2017-12-08 14:08:01.312 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : Insert Hero, Hero Name = hero0, Age = 0
  2. 2017-12-08 14:08:01.318 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : Insert Hero, Hero Name = hero1, Age = 1
  3. 2017-12-08 14:08:01.327 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : Insert Hero, Hero Name = hero2, Age = 2
  4. 2017-12-08 14:08:01.333 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : Insert Hero, Hero Name = hero3, Age = 3
  5. 2017-12-08 14:08:01.340 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : Insert Hero, Hero Name = hero4, Age = 4
  6. 2017-12-08 14:08:01.345 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : Insert Hero, Hero Name = hero5, Age = 5
  7. 2017-12-08 14:08:01.352 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : Insert Hero, Hero Name = hero6, Age = 6
  8. 2017-12-08 14:08:01.357 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : Insert Hero, Hero Name = hero7, Age = 7
  9. 2017-12-08 14:08:01.365 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : Insert Hero, Hero Name = hero8, Age = 8
  10. 2017-12-08 14:08:01.375 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : Select All, Hero Name hero0, Age = 0
  11. 2017-12-08 14:08:01.375 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : Select All, Hero Name hero1, Age = 1
  12. 2017-12-08 14:08:01.375 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : Select All, Hero Name hero2, Age = 2
  13. 2017-12-08 14:08:01.375 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : Select All, Hero Name hero3, Age = 3
  14. 2017-12-08 14:08:01.375 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : Select All, Hero Name hero4, Age = 4
  15. 2017-12-08 14:08:01.375 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : Select All, Hero Name hero5, Age = 5
  16. 2017-12-08 14:08:01.375 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : Select All, Hero Name hero6, Age = 6
  17. 2017-12-08 14:08:01.375 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : Select All, Hero Name hero7, Age = 7
  18. 2017-12-08 14:08:01.375 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : Select All, Hero Name hero8, Age = 8
  19. 2017-12-08 14:08:01.378 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : Select Hero by Age = 0, Hero Name hero0, Age = 0
  20. 2017-12-08 14:08:01.381 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : Select Hero by Name = hero1, Hero Name hero1, Age = 1
  21. 2017-12-08 14:08:01.384 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : Update Hero by Id = 0, Hero Name hero10, Age = 10
  22. 2017-12-08 14:08:01.409 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : Delete Hero by Id = 1
  23. 2017-12-08 14:08:01.416 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : Delete Hero by Name = hero2
  24. 2017-12-08 14:08:01.422 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : Delete Hero by Age = 3
  25. 2017-12-08 14:08:01.429 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : Delete Hero by Age = 5 and Name = hero5
  26. 2017-12-08 14:08:01.432 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : Select All, Hero Name hero1, Age = 1
  27. 2017-12-08 14:08:01.432 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : Select All, Hero Name hero4, Age = 4
  28. 2017-12-08 14:08:01.432 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : Select All, Hero Name hero6, Age = 6
  29. 2017-12-08 14:08:01.432 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : Select All, Hero Name hero7, Age = 7
  30. 2017-12-08 14:08:01.432 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : Select All, Hero Name hero8, Age = 8
  31. 2017-12-08 14:08:01.440 INFO 8684 --- [nio-8080-exec-6] c.b.mybatis.controller.HeroController : No Hero

参考文献

官方文档
http://www.mybatis.org/mybatis-3/zh/java-api.html#sqlSessions
MyBatis使用注解实现增删改查
http://blog.csdn.net/x_iya/article/details/72983906
java 中MyBatis注解映射的实例详解
http://www.jb51.net/article/122942.htm
使用注解配置Mapper
http://blog.csdn.net/kingice1014/article/details/70263148

发表评论

表情:
评论列表 (有 0 条评论,306人围观)

还没有评论,来说两句吧...

相关阅读