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

  • 相关阅读:
    Nim or not Nim? hdu3032 SG值打表找规律
    Maximum 贪心
    The Super Powers
    LCM Cardinality 暴力
    Longge's problem poj2480 欧拉函数,gcd
    GCD hdu2588
    Perfect Pth Powers poj1730
    6656 Watching the Kangaroo
    yield 小用
    wpf DropDownButton 源码
  • 原文地址:https://www.cnblogs.com/mindzone/p/12826345.html
Copyright © 2011-2022 走看看