zoukankan      html  css  js  c++  java
  • 【Mybatis】11 注解的使用

    文档引用: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

  • 相关阅读:
    获取网站注册中发送验证信息的链接
    SSH hibernate 使用时最好添加访问数据库的编码
    hibernate 数据行数统计 count(*)
    【转】Java自动装箱、拆箱、缓冲池
    struts2文件下载 火狐浏览器的文件名乱码问题
    struts2 action中传递两个参数到url
    IText 生成简单表格(报表)doc文档 单元居中
    IText 生成横向的doc文档
    IText PdfPTable表格 单元的居中显示
    IText 中文字体解决方案 生成doc文档
  • 原文地址:https://www.cnblogs.com/mindzone/p/12826345.html
Copyright © 2011-2022 走看看