2.3 mybatis配置篇-mapper注解形式

一、注解大全

注解使用对象XML等价形式描述
@CacheNamespace<cache>为给定的命名空间(比如类)配置缓存
@CacheNamespaceRef<cacheRef>引用另外一个命名空间的缓存以供使用
@PropertyN/A指定参数值或占位符(placeholder)(该占位符能被 mybatis-config.xml 内的配置属性替换)。属性:name、value。(仅在 MyBatis 3.4.2 以上可用)
@ConstructorArgs方法<constructor>收集一组结果以传递给一个结果对象的构造方法
@ArgN/A<arg><idArg>ConstructorArgs 集合的一部分,代表一个构造方法参数。属性:id、column、javaType、jdbcType、typeHandler、select、resultMap。id 属性和 XML 元素 相似,它是一个布尔值,表示该属性是否用于唯一标识和比较对象。从版本 3.5.4 开始,该注解变为可重复注解。
@CaseN/A<case>表示某个值的一个取值以及该取值对应的映射。属性:value、type、results,results 属性是一个 Results 的数组,因此这个注解实际上和 ResultMap 很相似,由下面的 Results 注解指定。
@Results方法<resultMap>一组结果映射,指定了对某个特定结果列,映射到某个属性或字段的方式。
@ResultN/A<result><id>在列和属性或字段之间的单个结果映射。属性:id、column、javaType、jdbcType、typeHandler、one、many。id 属性和 XML 元素 相似,它是一个布尔值,表示该属性是否用于唯一标识和比较对象。one 属性是一个关联,和 类似,而 many 属性则是集合关联,和 类似。这样命名是为了避免产生名称冲突。
@OneN/A<association>复杂类型的单个属性映射。属性: select,指定可加载合适类型实例的映射语句(也就是映射器方法)全限定名; fetchType,指定在该映射中覆盖全局配置参数 lazyLoadingEnabled; resultMap(available since 3.5.5), which is the fully qualified name of a result map that map to a single container object from select result; columnPrefix(available since 3.5.5), which is column prefix for grouping select columns at nested result map. 提示 注解 API 不支持联合映射。这是由于 Java 注解不允许产生循环引用。
@ManyN/A<collection>复杂类型的集合属性映射。属性: select,指定可加载合适类型实例集合的映射语句(也就是映射器方法)全限定名; fetchType,指定在该映射中覆盖全局配置参数 lazyLoadingEnabled resultMap(available since 3.5.5), which is the fully qualified name of a result map that map to collection object from select result; columnPrefix(available since 3.5.5), which is column prefix for grouping select columns at nested result map. 提示 注解 API 不支持联合映射。这是由于 Java 注解不允许产生循环引用。
@MapKey方法供返回值为 Map 的方法使用的注解。它使用对象的某个属性作为 key,将对象 List 转化为 Map
@Options方法映射语句的属性该注解允许你指定大部分开关和配置选项,它们通常在映射语句上作为属性出现。与在注解上提供大量的属性相比,Options 注解提供了一致、清晰的方式来指定选项。属性:useCache=true、flushCache=FlushCachePolicy.DEFAULT、resultSetType=DEFAULT、statementType=PREPARED、fetchSize=-1、timeout=-1、useGeneratedKeys=false、keyProperty=""、keyColumn=""、resultSets="", databaseId=""。注意,Java 注解无法指定 null 值。因此,一旦你使用了 Options 注解,你的语句就会被上述属性的默认值所影响。要注意避免默认值带来的非预期行为。 The databaseId(Available since 3.5.5), in case there is a configured DatabaseIdProvider, the MyBatis use the Options with no databaseId attribute or with a databaseId that matches the current one. If found with and without the databaseId the latter will be discarded.
@Insert,@Update,@Delete,@Select方法<insert>,<update>,<delete>,<select>每个注解分别代表将会被执行的 SQL 语句
@Param参数如果你的映射方法接受多个参数,就可以使用这个注解自定义每个参数的名字。否则在默认情况下,除 RowBounds 以外的参数会以 “param” 加参数位置被命名。例如 #{param1}, #{param2}。如果使用了 @Param(“person”),参数就会被命名为 #{person}。
@SelectKey方法<selectKey>这个注解的功能与 标签完全一致。该注解只能在 @Insert 或 @InsertProvider 或 @Update 或 @UpdateProvider 标注的方法上使用,否则将会被忽略。如果标注了 @SelectKey 注解,MyBatis 将会忽略掉由 @Options 注解所设置的生成主键或设置(configuration)属性。属性:statement 以字符串数组形式指定将会被执行的 SQL 语句,keyProperty 指定作为参数传入的对象对应属性的名称,该属性将会更新成新的值,before 可以指定为 true 或 false 以指明 SQL 语句应被在插入语句的之前还是之后执行。resultType 则指定 keyProperty 的 Java 类型。statementType 则用于选择语句类型,可以选择 STATEMENT、PREPARED 或 CALLABLE 之一,
@ResultMap方法这个注解为 @Select 或者 @SelectProvider 注解指定 XML 映射中 元素的 id。这使得注解的 select 可以复用已在 XML 中定义的 ResultMap。如果标注的 select 注解中存在 @Results 或者 @ConstructorArgs 注解,这两个注解将被此注解覆盖。
@ResultType方法在使用了结果处理器的情况下,需要使用此注解。由于此时的返回类型为 void,所以 Mybatis 需要有一种方法来判断每一行返回的对象类型。如果在 XML 有对应的结果映射,请使用 @ResultMap 注解。如果结果类型在 XML 的 元素中指定了,就不需要使用其它注解了。否则就需要使用此注解。比如,如果一个标注了 @Select 的方法想要使用结果处理器,那么它的返回类型必须是 void,并且必须使用这个注解(或者 @ResultMap)。这个注解仅在方法返回类型是 void 的情况下生效。

二、项目准备

项目目录结构

在这里插入图片描述

maven的pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.tadpole.learn</groupId>
    <artifactId>mybatis</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.0</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.30</version>
        </dependency>
    </dependencies>
    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>
    </build>
</project>

create.sql

CREATE SCHEMA `mybatis_learn` ;
CREATE TABLE `item_order` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `order_id` varchar(45) DEFAULT NULL,
  `name` varchar(45) DEFAULT NULL,
  `price` bigint(20) DEFAULT NULL,
  `item_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `order_id` (`order_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='订单表';


INSERT INTO `mybatis_learn`.`item_order` (`order_id`, `name`, `price`,`item_id`) VALUES ('1', '123', '苹果', '20', '1');
INSERT INTO `mybatis_learn`.`item_order` (`order_id`, `name`, `price`,`item_id`) VALUES ('2', '456', '葡萄', '30', '2');



CREATE TABLE `mybatis_learn`.`item` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `item_name` VARCHAR(45) NULL,
  PRIMARY KEY (`id`))
COMMENT = '商品';

INSERT INTO `mybatis_learn`.`item` (`id`, `item_name`) VALUES ('1', '苹果');
INSERT INTO `mybatis_learn`.`item` (`id`, `item_name`) VALUES ('2', '香蕉');

mybatis.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis_learn?useUnicode=true&amp;characterEncoding=utf-8&amp;zeroDateTimeBehavior=convertToNull&amp;useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <package name="com.tadpole.itemorder"/>
    </mappers>
</configuration>

三、注解示例

1、@CacheNamespace,@CacheNamespaceRef

@CacheNamespace注解主要用于mybatis二级缓存,等同于属性

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface CacheNamespace {
    //缓存实现类,默认是PerpetualCache.class
  Class<? extends org.apache.ibatis.cache.Cache> implementation() default PerpetualCache.class;
  //缓存回收策略,默认LruCache.class(最近最少使用)
  Class<? extends org.apache.ibatis.cache.Cache> eviction() default LruCache.class;
  //刷新间隔。可被设置为任意的正整数,单位毫秒。默认不设置。
  long flushInterval() default 0;
  //	引用数目。可被设置为任意正整数,缓存的对象数目等于运行环境的可用内存资源数目。默认是1024。
  int size() default 1024;
  //只读,true或false。只读的缓存会给所有的调用者返回缓存对象的相同实例。默认是false。
  boolean readWrite() default true;
  //是否使用BlockingCache,BlockingCache 是阻塞版本的缓存装饰器,它保证只有一个线程到数据库中查找指定key对应的数据。
  boolean blocking() default false;
}

直接在对应的mapper接口中加上以上注释就好了

import org.apache.ibatis.annotations.CacheNamespace;
import org.apache.ibatis.cache.decorators.LruCache;
import org.apache.ibatis.cache.impl.PerpetualCache;
@CacheNamespace(implementation = PerpetualCache.class, eviction = LruCache.class)
@CacheNamespaceRef(value = ItemOrderMapper.class)//引用另一个命名空间的缓存
public interface ItemOrderMapper {
}

2、@ConstructorArgs,@Arg,@Results,@Select,@Insert,@Update,@Delete,@Param,@SelectKey,@ResultMap,@ResultType,@MapKey,@One,@Case

在注解上不能直接使用动态的SQL,需要在其前后加入 <script>
有以下bean

package com.tadpole.itemorder;
public class Item {
    private int id;
    private String itemName;
    public int getId() {return id;}
    public void setId(int id) {this.id = id; }
    public String getItemName() {return itemName;}
    public void setItemName(String itemName) {this.itemName = itemName;}
}
package com.tadpole.itemorder;
import java.util.List;
public class ItemOrder {
    private int id;
    private String orderId;
    private String name;
    private long price;
    private int itemId;
    private Item item;
    private List<Item> items;
    public int getItemId() {return itemId; }
    public void setItemId(int itemId) {this.itemId = itemId; }
    public Item getItem() {return item;}
    public void setItem(Item item) {this.item = item;}
    public List<Item> getItems() {return items;}
    public void setItems(List<Item> items) {this.items = items;}
    public int getId() {return id;}
    public void setId(int id) {this.id = id;}
    public String getOrderId() {return orderId;}
    public void setOrderId(String orderId) {this.orderId = orderId; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public long getPrice() { return price; }
    public void setPrice(long price) {this.price = price;}
}
package com.tadpole.itemorder;
public class ItemOrder2 {
    private int id;
    private String orderId;
    private String name;
    public ItemOrder2(Integer id, String orderId, String name) {this.id = id;this.orderId = orderId;this.name = name;}
    public int getId() { return id;}
    public void setId(int id) {this.id = id;}
    public String getOrderId() {return orderId; }
    public void setOrderId(String orderId) {this.orderId = orderId;}
    public String getName() {return name;}
    public void setName(String name) {this.name = name;}
}
package com.tadpole.itemorder;

public class ItemOrderParam {
    private int otherId;
    private String orderId;
    private String name;
    private int price;
    private int itemId;
    public ItemOrderParam() {}
    public ItemOrderParam(int id, String orderId, String name, int price, int itemId) {
        this.otherId = id;
        this.orderId = orderId;
        this.name = name;
        this.price = price;
        this.itemId = itemId;
    }
    public int getOtherId() {return otherId;}
    public void setOtherId(int otherId) { this.otherId = otherId;}
    public String getOrderId() {return orderId; }
    public void setOrderId(String orderId) {this.orderId = orderId;}
    public String getName() { return name;}
    public void setName(String name) {this.name = name; }
    public int getPrice() {return price;}
    public void setPrice(int price) {this.price = price;}
    public int getItemId() {return itemId;}
    public void setItemId(int itemId) { this.itemId = itemId; }
}


ItemMapper

package com.tadpole.itemorder;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface ItemMapper {
    @Select(" select * from  item where id = #{id}")
    @Results( id = "item",value = {
            @Result(column = "id",property = "id"),
            @Result(column = "item_name",property = "itemName")
    })
    Item selectById(@Param(value = "id") int id);

    @Select(" select * from  item where id >= #{id}")
    @ResultMap("item")
    List<Item> selectBiggerIdById(@Param(value = "id") int id);
}
package com.tadpole.itemorder;

import org.apache.ibatis.annotations.*;
import org.apache.ibatis.cache.impl.PerpetualCache;
import org.apache.ibatis.mapping.FetchType;

@CacheNamespace(implementation = PerpetualCache.class)
@CacheNamespaceRef(value = ItemOrderMapper.class)
@Mapper
public interface ItemOrderMapper {
    //定义查询的sql语句@Select,如果需要写动态sql则加上标签<script></script>
    @Select({"<script>"," select * from  item_order " +
            "<if test=\"id != null\">where id = #{id}</if>" +
            "","</script>"})
    //定义结果映射器,这里定义的id可以提供给其他地方使用
    @Results( id = "itemOrder",value = {
            @Result(column = "id",property = "id"),//@Result定义了字段映射
            @Result(column = "name",property = "name"),
            @Result(column = "order_id",property = "orderId"),
            @Result(column = "price",property = "price"),
            @Result(column = "item_id",property = "itemId"),
            //@One定义该item属性的填充使用com.tadpole.itemorder.ItemMapper.selectById这个查询语句查询回填,并且是懒加载,当方法被调用时才去查询数据库
            @Result(column = "item_id",property = "item", one = @One(select = "com.tadpole.itemorder.ItemMapper.selectById", fetchType = FetchType.LAZY)),
            //@Many定义该items属性的填充使用com.tadpole.itemorder.ItemMapper.selectBiggerIdById查询回填,也是懒加载,当使用get方法时才会加载执行查询语句
            @Result(column = "item_id",property = "items", many = @Many(select = "com.tadpole.itemorder.ItemMapper.selectBiggerIdById", fetchType = FetchType.LAZY))
    })
    ItemOrder selectById(@Param(value = "id")/**这里给变量名声明名称,可在sql语句中使用#{id}引用*/ int id);

    @Results(id = "itemOrder2")//定义结果映射器itemOrder2,使用以下的ConstructorArgs构造器映射
    //按照构造函数的顺序
    @ConstructorArgs({
            @Arg(column = "id",javaType = Integer.class, id = true),
            @Arg(column = "order_id",javaType = String.class),
            @Arg(column = "name",javaType = String.class),
    })
    @Select(" select id,order_id,name from  item_order where id = #{id}")
    ItemOrder2 selectItemOrder2ById(@Param(value = "id") int id);

    @Select(" select * from  item_order where id = #{id}")
    @ResultMap("itemOrder")//直接使用上面定义的itemOrder,
    ItemOrder selectById1(int id);

    @Insert("INSERT INTO`item_order` (`order_id`, `name`, `price`,`item_id`) VALUES ( #{orderId}, #{name}, #{price}, #{itemId}) ")
    //options 选项返回id字段,回填到otherId属性中,Options还有其他的用法:使用缓存,超时时间等
    @Options(useGeneratedKeys = true, keyColumn = "id", keyProperty = "otherId")
    //返回影响的行数
    int insert(ItemOrderParam itemOrderParam);

    @Insert("INSERT INTO`item_order` (`order_id`, `name`, `price`,`item_id`) VALUES ( #{orderId}, #{name}, #{price}, #{itemId}) ")
    //返回影响的行数
    //SelectKey效果跟上面options一致
    @SelectKey(statement = "SELECT LAST_INSERT_ID()", keyColumn = "id",keyProperty = "otherId", before = false, resultType = int.class)
    int insertReturnKeyId(ItemOrderParam itemOrderParam);

    @Delete("delete from item_order where id = #{id}")
    //返回影响的行数
    int deleteById(@Param("id")int id);

    @Delete("update  item_order set price = price + 1 where id >= #{id}")
    //返回影响的行数
    int updateAddBiggerIdById(@Param("id")int id);
    
    
    @Select(" select * from  item_order where id = #{id}")
    @MapKey(value = "id")//使用id字段做为map的key,value则是resultMap的类型
    @ResultMap("itemOrder")//直接使用上面定义的itemOrder,
    Map<Integer, ItemOrder> selectMapById(int id);

}

MyBatisStart

package com.tadpole;

import com.tadpole.itemorder.Item;
import com.tadpole.itemorder.ItemOrder;
import com.tadpole.itemorder.ItemOrderMapper;
import com.tadpole.itemorder.ItemOrderParam;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

public class MyBatisStart {
    public static void main(String[] args) throws IOException {
        InputStream is = Resources.getResourceAsStream("mybatis.xml");
        //1、初始化sqlSession链接工厂
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        //2、获取SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //3、获取对应的Mapper执行sql
        ItemOrderMapper abcMapper = sqlSession.getMapper(ItemOrderMapper.class);
        ItemOrder itemOrder = abcMapper.selectById1(1);

        System.out.println("id为1的商品订单:名字:" + itemOrder.getName() + ",支付金额:" + itemOrder.getPrice() + ",itemOrder,getOrderId" + itemOrder.getOrderId() + "itemOrder.itemid=" + itemOrder.getItemId());

        System.out.println(itemOrder.getItem().getItemName());
        System.out.println("id为1的商品订单关联商品id比该订单大的商品名");
        for (Item item : itemOrder.getItems()) {
            System.out.println(item.getItemName());
        }
        System.out.println("构造函数映射结果:abcMapper.selectItemOrder2ById(1).getName" + abcMapper.selectItemOrder2ById(1).getName());
        System.out.println("删除abcMapper返回影响条数=" + abcMapper.deleteById(3));
        ItemOrderParam itemOrderParam = new ItemOrderParam(3, "9999", "你好", 132, 465);
        System.out.println("插入abcMapper,并且回填id字段。影响数量" + abcMapper.insert(itemOrderParam) + ",itemOrderParam.id=" + itemOrderParam.getOtherId());

        ItemOrderParam insertReturnKeyIdParam = new ItemOrderParam(3, "789456", "你好", 132, 465);
        int id = abcMapper.insertReturnKeyId(insertReturnKeyIdParam);
        System.out.println("插入abcMapper。并且回填id字段,insertReturnKey影响数量" + id +",insertReturnKeyIdParam.id=" + insertReturnKeyIdParam.getOtherId());
        System.out.println("删除abcMapper。delete影响数量=" + abcMapper.deleteById(itemOrderParam.getOtherId()));
        System.out.println("删除abcMapper。delete影响数量=" + abcMapper.deleteById(insertReturnKeyIdParam.getOtherId()));
        System.out.println("删除abcMapper。update影响数量=" + abcMapper.updateAddBiggerIdById(1));
        Map<Integer, ItemOrder> integerItemOrderMap = abcMapper.selectMapById(1);
        for (Map.Entry<Integer, ItemOrder> integerItemOrderEntry : integerItemOrderMap.entrySet()) {
            System.out.println("查询。selectMapById,key=" + integerItemOrderEntry.getKey() + ",value=" + integerItemOrderEntry.getValue().getName());
        }
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值