文档引用:http://www.mybatis.cn/archives/678.html

视频参考:https://www.bilibili.com/video/BV1NE411Q7Nx?p=15


注解与xml取舍

在没有注解之前,xml被广泛的应用于描述元数据,xml的维护越来越糟糕。

在需要紧耦合的地方,比xml该容易维护,阅读更方便。

在需要比较多参数设置时,使用xml更方便,而在将某个方法声明为服务时这种紧耦合的情况下,

比较适合注解。

xml是松耦合的,注解是紧耦合的,对于xml和注解的使用,要具体问题具体分析。

例如,这种情况下xml更胜一筹:MyBatis XML配置对抗MyBatis注解的一大杀器:SQL片段,抽取可重用的SQL语句

java的注解没有行为,只能有数据,实际上就是一组键值对而已。

通过解析类(Parse Class)就能把一个注解设置的键值对都找出来。

mybatis 注解与xml配置

因为最初设计时,MyBatis是一个XML驱动的框架。

配置信息是基于XML的,而且映射语句也是定义在XML中的。

而到了MyBatis3,有新的选择了:利用注解实现SQL的映射。

MyBatis3构建在全面而且强大的Java 注解(Java annotation)之上。

注解提供了一种便捷的方式来实现简单SQL映射语句,可以简化编写XML的过程。

MyBatis基于注解的用法,正在变得越来越流行,

但是需要注意的是:注解的方式还没有百分百覆盖所有XML标签,所以还是有一点点不足!


快速入门

新建一个CRUD的Mapper接口

public interface UserAnnotationMapper {

    @Select("SELECT * FROM `user`;")
List<User> getAllUserList();
}

我们不需要再写Mapper接口配置了

直接再核心配置中注册接口即可

测试发生了错误

java.lang.ExceptionInInitializerError
at SqlSessionTest.sqlTest(SqlSessionTest.java:124)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
Caused by: org.apache.ibatis.exceptions.PersistenceException:
### Error building SqlSession.
### The error may exist in cn/dai/mapper/UserAnnotationMapper.java (best guess)
### Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.binding.BindingException: Type interface cn.dai.mapper.UserAnnotationMapper is already known to the MapperRegistry.
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:80)
at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:64)
at cn.dai.util.MybatisUtil.<clinit>(MybatisUtil.java:26)
... 26 more
Caused by: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.binding.BindingException: Type interface cn.dai.mapper.UserAnnotationMapper is already known to the MapperRegistry.
at org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:121)
at org.apache.ibatis.builder.xml.XMLConfigBuilder.parse(XMLConfigBuilder.java:98)
at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:78)
... 28 more
Caused by: org.apache.ibatis.binding.BindingException: Type interface cn.dai.mapper.UserAnnotationMapper is already known to the MapperRegistry.
at org.apache.ibatis.binding.MapperRegistry.addMapper(MapperRegistry.java:63)
at org.apache.ibatis.binding.MapperRegistry.addMappers(MapperRegistry.java:97)
at org.apache.ibatis.binding.MapperRegistry.addMappers(MapperRegistry.java:105)
at org.apache.ibatis.session.Configuration.addMappers(Configuration.java:771)
at org.apache.ibatis.builder.xml.XMLConfigBuilder.mapperElement(XMLConfigBuilder.java:365)
at org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:119)
... 30 more

经过检查发现使用接口注册就不能和包扫描同时使用

    <mappers>
<mapper class="cn.dai.mapper.UserAnnotationMapper" /> <!--<package name="cn.dai.mapper"/>-->
</mappers>

再测试就可行

[SqlSessionTest]-- - - - TESTING - - - -
[org.apache.ibatis.logging.LogFactory]-Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
[org.apache.ibatis.logging.LogFactory]-Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
[org.apache.ibatis.io.VFS]-Class not found: org.jboss.vfs.VFS
[org.apache.ibatis.io.JBoss6VFS]-JBoss 6 VFS API is not available in this environment.
[org.apache.ibatis.io.VFS]-Class not found: org.jboss.vfs.VirtualFile
[org.apache.ibatis.io.VFS]-VFS implementation org.apache.ibatis.io.JBoss6VFS is not valid in this environment.
[org.apache.ibatis.io.VFS]-Using VFS adapter org.apache.ibatis.io.DefaultVFS
[org.apache.ibatis.io.DefaultVFS]-Find JAR URL: file:/C:/Users/Administrator/IdeaProjects/Mybatis/Mybatis02%20-%20Configure/target/classes/cn/dai/pojo
[org.apache.ibatis.io.DefaultVFS]-Not a JAR: file:/C:/Users/Administrator/IdeaProjects/Mybatis/Mybatis02%20-%20Configure/target/classes/cn/dai/pojo
[org.apache.ibatis.io.DefaultVFS]-Reader entry: LimitSqlParam.class
[org.apache.ibatis.io.DefaultVFS]-Reader entry: User.class
[org.apache.ibatis.io.DefaultVFS]-Listing file:/C:/Users/Administrator/IdeaProjects/Mybatis/Mybatis02%20-%20Configure/target/classes/cn/dai/pojo
[org.apache.ibatis.io.DefaultVFS]-Find JAR URL: file:/C:/Users/Administrator/IdeaProjects/Mybatis/Mybatis02%20-%20Configure/target/classes/cn/dai/pojo/LimitSqlParam.class
[org.apache.ibatis.io.DefaultVFS]-Not a JAR: file:/C:/Users/Administrator/IdeaProjects/Mybatis/Mybatis02%20-%20Configure/target/classes/cn/dai/pojo/LimitSqlParam.class
[org.apache.ibatis.io.DefaultVFS]-Reader entry: ���� 1 Q = > ?
[org.apache.ibatis.io.DefaultVFS]-Find JAR URL: file:/C:/Users/Administrator/IdeaProjects/Mybatis/Mybatis02%20-%20Configure/target/classes/cn/dai/pojo/User.class
[org.apache.ibatis.io.DefaultVFS]-Not a JAR: file:/C:/Users/Administrator/IdeaProjects/Mybatis/Mybatis02%20-%20Configure/target/classes/cn/dai/pojo/User.class
[org.apache.ibatis.io.DefaultVFS]-Reader entry: ���� 1 _ H I J K
[org.apache.ibatis.io.ResolverUtil]-Checking to see if class cn.dai.pojo.LimitSqlParam matches criteria [is assignable to Object]
[org.apache.ibatis.io.ResolverUtil]-Checking to see if class cn.dai.pojo.User matches criteria [is assignable to Object]
[org.apache.ibatis.datasource.pooled.PooledDataSource]-PooledDataSource forcefully closed/removed all connections.
[org.apache.ibatis.datasource.pooled.PooledDataSource]-PooledDataSource forcefully closed/removed all connections.
[org.apache.ibatis.datasource.pooled.PooledDataSource]-PooledDataSource forcefully closed/removed all connections.
[org.apache.ibatis.datasource.pooled.PooledDataSource]-PooledDataSource forcefully closed/removed all connections.
[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Opening JDBC Connection
[org.apache.ibatis.datasource.pooled.PooledDataSource]-Created connection 1536471117.
[cn.dai.mapper.UserAnnotationMapper.getAllUserList]-==> Preparing: SELECT * FROM `user`;
[cn.dai.mapper.UserAnnotationMapper.getAllUserList]-==> Parameters:
[cn.dai.mapper.UserAnnotationMapper.getAllUserList]-<== Total: 16
User(user_id=1, user_name=杰哥, user_password=123456)
User(user_id=2, user_name=阿伟, user_password=123456)
User(user_id=3, user_name=空条承太郎, user_password=123456)
User(user_id=4, user_name=乔鲁诺乔巴纳, user_password=123456)
User(user_id=5, user_name=迪奥布兰多, user_password=123456)
User(user_id=6, user_name=乔瑟夫乔斯达, user_password=123456)
User(user_id=7, user_name=乔纳森乔斯达, user_password=123456)
User(user_id=8, user_name=丽萨丽萨, user_password=654321)
User(user_id=9, user_name=东方仗助, user_password=654321)
User(user_id=10, user_name=东方定助, user_password=654321)
User(user_id=11, user_name=花京院典明, user_password=654321)
User(user_id=12, user_name=波鲁纳雷夫, user_password=654321)
User(user_id=13, user_name=吉良吉影, user_password=654321)
User(user_id=14, user_name=布加拉提, user_password=654321)
User(user_id=15, user_name=葛德米斯达, user_password=131313)
User(user_id=18, user_name=哈吉咩, user_password=335577)
[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@5b94b04d]
[org.apache.ibatis.datasource.pooled.PooledDataSource]-Returned connection 1536471117 to pool. Process finished with exit code 0

但是我换了这个之后,也是可行的

    <mappers>
<!--<mapper class="cn.dai.mapper.UserAnnotationMapper" />--> <package name="cn.dai.mapper"/>
</mappers>

也就是说注册过的地方不可以重复注册

最后采用资源引用 + 接口完全限定名,两者都可以使用

    <mappers>
<mapper class="cn.dai.mapper.UserAnnotationMapper" /> <mapper resource="mapper/UserMapper.xml"/>
</mappers>

补全剩下的注解

package cn.dai.mapper;

import cn.dai.pojo.User;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update; import java.util.List; /**
* @author ArkD42
* @file Mybatis
* @create 2020 - 05 - 04 - 13:54
*/
public interface UserAnnotationMapper { @Select("SELECT * FROM `user`;")
List<User> getAllUserList(); @Select("SELECT * FROM `user` WHERE user_id = #{id};")
User getUserById(Integer id); @Insert("INSERT INTO `user` VALUES(#{user_id},#{user_name},#{user_password});")
int addUser(User user); @Update("UPDATE `user` SET user_name = #{user_name},user_password = #{user_password} WHERE user_id = #{user_id}")
int updateUserById(User user); @Delete("DELETE FROM `user` WHERE user_id = #{id};")
int deleteUserById(Integer id);
}

@Param注解类似结果集字段映射,

主要用于多个参数的绑定匹配

要注意的一点是,注解SQL不能和Mapper映射文件同时配置,

要么注解要么XML,不可以两个都配置同一个接口的抽象SQL方法

更多详细:http://www.mybatis.cn/archives/678.html

【Mybatis】11 注解的使用的更多相关文章

  1. Spring+Mybatis基于注解整合Redis

    基于这段时间折腾redis遇到了各种问题,想着整理一下.本文主要介绍基于Spring+Mybatis以注解的形式整合Redis.废话少说,进入正题. 首先准备Redis,我下的是Windows版,下载 ...

  2. Mybatis 常用注解

    Mybatis常用注解对应的目标和标签如表所示: 注解 目标 对应的XML标签 @CacheNamespace 类 <cache> @CacheNamespaceRef 类 <cac ...

  3. SpringBoot入门教程(四)MyBatis generator 注解方式和xml方式

    MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以使用简单的 XML ...

  4. mybatis 使用注解简化xml映射文件

    目录 关于mybatis注解 初次简单使用mybatis注解示例 利用注解实现指定映射 使用注解实现表间关联(1对1) 关于mybatis注解 注解在java中特别常见,mybatis中也支持注解. ...

  5. SpringBoot Mybatis整合(注解版),SpringBoot集成Mybatis(注解版)

    SpringBoot Mybatis整合(注解版),SpringBoot集成Mybatis(注解版) ================================ ©Copyright 蕃薯耀 2 ...

  6. Spring+MyBatis纯注解零XML整合(4)

    不得不说,利用XML作为配置文件是一个非常好的想法,它可以轻松地实现配置集中化,而且修改之后无需再次编译.然而,由于大多数情况下开发者基本都会拿到程序的源码,加之对于各种XML配置文件一般情况下也只有 ...

  7. mybatis的注解功能

    一.mybatis 简单注解 关键注解词 : @Insert : 插入sql , 和xml insert sql语法完全一样 @Select : 查询sql, 和xml select sql语法完全一 ...

  8. mybatis使用注解替代xml配置,动态生成Sql

    mybatis使用注解替代xml配置时,遇到判断条件是否为null或者为空时,@Select很难搞定,不知道怎么办? mybatis3中增加了使用注解来配置Mapper的新特性,使用 SelectPr ...

  9. Spring Boot整合MyBatis(非注解版)

    Spring Boot整合MyBatis(非注解版),开发时采用的时IDEA,JDK1.8 直接上图: 文件夹不存在,创建一个新的路径文件夹 创建完成目录结构如下: 本人第一步习惯先把需要的包结构创建 ...

  10. Spring Boot 实战 —— MyBatis(注解版)使用方法

    原文链接: Spring Boot 实战 -- MyBatis(注解版)使用方法 简介 MyBatis 官网 是这么介绍它自己的: MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过 ...

随机推荐

  1. OOP第一阶段题集总结

    一.前言 知识点:数组,字符串的使用,链表,hashmap,泛型的使用,正则表达式的使用,类的设计,类与类之间的关系,单一职责. 题量:题目数量为5+4+3,数量适中,其中都是前几题较简单,最后一题较 ...

  2. 白话理解和使用DOCKER VOLUME

    Docker使用Volume来管理宿主机和容器内数据的映射  什么是数据卷(Volume)Docker镜像被存储在一系列的只读层中.当我们创建一个容器时,Docker会读取镜像(只读),并在其顶部添加 ...

  3. k8s配置文件管理

    1.为什么要用configMap ConfigMap是一种用于存储应用所需配置信息的资源类型,用于保存配置数据的键值对,可以用来保存单个属性,也可以用来保存配置文件. 通过ConfigMap可以方便的 ...

  4. WebStorm 中自定义文档注释模板

    WebStorm 中自定义文档注释模板 前提 使用WebStrom写HTML,JavaScript,进行头部注释. 减少重复劳动 养成良好的代码习惯,规范化代码,规范的注释便于后续维护. 头部注释内容 ...

  5. 高德地图查询结果返回INVALID_USER_IP错误解决

    高德地图查询结果返回INVALID_USER_IP错误解决 方法是添加白名单.IP白名单出错,发送请求的服务器IP不在IP白名单内开发者在LBS官网控制台设置的IP白名单不正确.白名单中未添加对应服务 ...

  6. 哎,被这个叫做at least once的玩意坑麻了。

    你好呀,我是歪歪. 前几天遇到一个生产问题,同一个数据在数据库里面被插入了两次,导致后续处理出现了一些问题. 当时我们首先检讨了自己,没有做好幂等校验.甚至还发现了一个低级错误:对应的表,针对订单号, ...

  7. c++ 线程使用

    C++中的线程可以通过标准库提供的thread类实现.该类提供了创建和管理线程的方法和函数. 创建线程的方法: #include <thread> ... // 创建一个线程,其执行函数为 ...

  8. Nuxt3页面开发实战探索

    title: Nuxt3页面开发实战探索 date: 2024/6/19 updated: 2024/6/19 author: cmdragon excerpt: 摘要:这篇文章是关于Nuxt3页面开 ...

  9. Web之http学习笔记

    目录 HTTP url http请求 请求行 请求方法 请求头 请求正文 http响应 响应行 状态码 响应头 响应正文 Cookie 定义: 内容: 用途: 生命周期: 隐私和安全性: Sessio ...

  10. Flink状态(一)

    key状态和算子状态 key状态 key状态总是与key有关,只能被用于keyedStream类型的函数与算子.你可以认为key状态是一种被分区的算子状态,每一个key有一个状态分区.每一个key状态 ...