Mapper XML的开发方式: 有更好的维护性,我们不用修改java代码,可以让我们在XML中对SQL进行灵活的修改。这种开发方式更适合大型的,需要团队合作的项目。

注解开发方式: 更好的程序编码体验。这种方式适合小型,敏捷开发的工程。

本篇内容仅供了解,因为,现在mybatis很少使用注解的方式开发;

在Mybatis中注解的主要作用是,替代原有xml的各种标签,在程序中利用对应的注解来进行开发,进而简化程序的配置过程,简化程序开发;

注解可以理解为,把【原先放在xml中的配置信息和SQL语句】放在java程序中书写。注解开发的优点:可以有更好的开发体验,可以让程序开发的更快。

目录

一:预备工作:创建一使用Maven管理依赖的mybatis项目

GoodsDTO类:

Goods类:

MyBatisUtils类:

logback.xml:

mybatis-config.xml:

pom.xml:

二:注解开发案例:查询

(1)创建dao包,创建***DAO接口,编写SQL

(2)在mybatis-config.xml中配置接口

(3)实际调用

三:注解开发案例:插入

(1)在GoodsDAO接口增加insert方法

(2)实际调用

四:结果映射(使用***DTO类【数据传输对象类】去承接存储查询结果)

(1)情况说明

(2)在GoodsDAO接口增加演示的方法

(3)实际调用


一:预备工作:创建一使用Maven管理依赖的mybatis项目

这个mybatis项目很简单,仅仅用于演示Mybatis注解的使用方式。

GoodsDTO类:

Goods类:

MyBatisUtils类:

package com.imooc.mybatis.utils;

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.Reader;

/**
 * MyBatis工具类
 * (1)创建全局唯一的SqlSessionFactory对象;(2)获取SqlSession的方法;(3)关闭SqlSession的方法;
 */
public class MyBatisUtils {
    //sqlSessionFactory对象设置成静态的,这个对象属于类的;
    private static SqlSessionFactory sqlSessionFactory = null;
    static{
        try {
            Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        } catch (IOException e) {
            e.printStackTrace();
            // 如果出现了异常,除了上面打印异常,还需要将这个异常向上抛,让使用这个类的程序也知道这儿报错了;
            // 这儿主动抛了ExceptionInInitializerError,即在类的初始化过程中产生了错误;即调用者捕获了这个异常,就能够明白,
            // mybatis在初始化的时候产生了错误,
            throw new ExceptionInInitializerError(e);
        }
    }

    /**
     * 获得SqlSession对象的方法;;;;
     * 在其他地方调用这个方法获得SqlSession对象后,后续就可以利用SqlSession完成数据表的增删改查了;
     * 说明:工具类中的方法,一般使用static进行描述,这样以后通过类名就能直接调用了;
     * @return
     */
    public static SqlSession openSession(){
        return sqlSessionFactory.openSession();
    }

    /**
     * 关闭SqlSession的方法;
     * @param sqlSession
     */
    public static void closeSession(SqlSession sqlSession){
        if (sqlSession != null){
            sqlSession.close();
        }
    }
}

logback.xml:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="consolehaha" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>[%thread] %d{HH:mm:ss:SSS} %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    <root level="debug">
        <appender-ref ref="consolehaha"></appender-ref>
    </root>
</configuration>

mybatis-config.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>
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    <environments default="dev">
        <environment id="dev">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/babytun?useUnicode=true&amp;characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="12345"/>
            </dataSource>
        </environment>
    </environments>
</configuration>

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>org.example</groupId>
    <artifactId>mybatis-annotation</artifactId>
    <version>1.0-SNAPSHOT</version>

    <repositories>
        <repository>
            <id>aliyun</id>
            <name>aliyun</name>
            <url>https://maven.aliyun.com/repository/public</url>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.1</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
    </dependencies>

</project>

二:注解开发案例:查询

利用注解开发的时候,是不需要写Mapper XML文件的。而是创建一个名字是dao的包,在这个包中创建一系列的接口;利用【接口+注解】来替代原有的Mapper XML文件;

(1)创建dao包,创建***DAO接口,编写SQL

GoodsDAO接口:

package com.imooc.mybatis.dao;

import com.imooc.mybatis.entity.Goods;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface GoodsDAO {

    @Select("select * from t_goods where current_price between #{min} and #{max} order by current_price limit 0,#{limt}")
    public List<Goods> selectByPriceRange(@Param("min") Float minhaha, @Param("max") Float maxhaha, @Param("limt") Integer limthaha);

}

说明:

(1) 简单说明

(2) selectByPriceRange()方法的返回值类型,就对对应了上面@Select注解中的SQL语句的返回值。因为,我们已经添加了Goods实体类并设置了驼峰命名,所以Mybatis在执行@Select注解中的SQL语句后,会自动帮我们把返回值的类型包装成Goods实体类对象;

(2)在mybatis-config.xml中配置接口

上面写的GoodsDAO,Mybatis并不知道这个接口的用途,需要在mybatis-config.xml中进行配置说明:

    <mappers>
<!--        <mapper class="com.imooc.mybatis.dao.GoodsDAO"/>-->
        <package name="com.imooc.mybatis.dao"/>
    </mappers>

说明:

(1) 简单说明

(3)实际调用

package com.imooc.mybatis;

import com.imooc.mybatis.dao.GoodsDAO;
import com.imooc.mybatis.entity.Goods;
import com.imooc.mybatis.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

/**
 * JUnit测试类
 */
public class MyBatisTestor {
    @Test
    public void testSelectByPriceRange() throws Exception {
        SqlSession session = null;
        try {
            session = MyBatisUtils.openSession();
            GoodsDAO goodsDAO = session.getMapper(GoodsDAO.class);
            List<Goods> list = goodsDAO.selectByPriceRange(100f, 500f, 20);
            System.out.println(list.size());
        } catch (Exception e) {
            throw e;
        }finally {
            MyBatisUtils.closeSession(session);
        }
    }
}

说明:

(1) 采用注解的方式时:session.getMapper():得到映射器;

(2) 在执行【GoodsDAO goodsDAO = session.getMapper(GoodsDAO.class);】时,虽然返回值类型GoodsDAO,但是在实际运行的时候,session对象就会根据GoodsDAO接口中的【如@Select这些注解的配置信息】来动态的生成GoodsDAO接口的实现类。。。。

(3) 然后,使用goodsDAO对象直接去调用方法就可以了;

(4) 运行结果:

(5)

注解这种开发方式,不是什么新鲜的东西,其就是把原本写在Mapper XML中的配置放在java代码中,让我们开发起来更加顺畅些。


三:注解开发案例:插入

(1)在GoodsDAO接口增加insert方法

package com.imooc.mybatis.dao;

import com.imooc.mybatis.entity.Goods;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.SelectKey;

import java.util.List;

public interface GoodsDAO {

    @Insert("insert into t_goods(title,sub_title,original_cost,current_price,discount,is_free_delivery,category_id) values(#{title},#{subTitle},#{originalCost},#{currentPrice},#{discount},#{isFreeDelivery},#{categoryId})")
    @SelectKey(statement = "select last_insert_id()",before = false,keyProperty = "goodsId",resultType = Integer.class)
    public int insert(Goods goods);


}

说明:

(1) @Insert()注解标签中的参数,是一个标准的SQL语句;

(2) @SelectKey注解标签: statement属性 @SelectKey注解要执行的SQL语句是什么。【statement=“select last_insert_id()”】,在插入操作以后,回去并回填新插入的主键的编号,,,,和以前在Mapper XML中的子标签作用一样。

(3) @SelectKey注解标签: before属性 ,【before = false】意思是在@Insert()注解中的语句执行完了之后,再执行@SelectKey注解中的语句。。。。。。。当然【before = true】就是在@Insert()注解中的语句执行之前,就执行@SelectKey注解中的语句。。。

(4) @SelectKey注解标签: keyProperty属性 ,说明使用哪个属性对应着主键。【keyProperty=“goodsId”】就是指Goods对象中的goodsId属性对应着数据表中的主键字段;

(5) @SelectKey注解标签:resultType属性,说明@SelectKey注解标签中的SQL语句返回的主键的类型是什么。【resultType = Integer.class】就是指goods_id的数据是整形的;

(2)实际调用

package com.imooc.mybatis;

import com.imooc.mybatis.dao.GoodsDAO;
import com.imooc.mybatis.entity.Goods;
import com.imooc.mybatis.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

/**
 * JUnit测试类
 */
public class MyBatisTestor {

    @Test
    public void testInsert() throws Exception {
        SqlSession session = null;
        try {
            session = MyBatisUtils.openSession();
            Goods goods = new Goods();
            goods.setTitle("测试商品");goods.setSubTitle("测试子标题");goods.setOriginalCost(200f);
            goods.setCurrentPrice(100f);goods.setDiscount(0.5f);goods.setIsFreeDelivery(1);
            goods.setCategoryId(42);
            GoodsDAO goodsDAO = session.getMapper(GoodsDAO.class);
            int num = goodsDAO.insert(goods);
            session.commit();
            System.out.println(num);
        } catch (Exception e) {
            if (session != null) {
                session.rollback();
            }
            throw e;
        }finally {
            MyBatisUtils.closeSession(session);
        }
    }
}

运行结果:


四:结果映射(使用***DTO类【数据传输对象类】去承接存储查询结果)

(1)情况说明

但是,我们依旧想让GoodsDTO类对象去承载和存储【查询t_goods表的结果】,就需要结果映射了。

注:还是那句话,如果编写实体类的时候,严格按照驼峰命名规则和表的类名去编写实体类的属性,其 可以不手动去指定结果映射。。。。否则的话,就需要手动去指定结果映射。

(2)在GoodsDAO接口增加演示的方法

package com.imooc.mybatis.dao;

import com.imooc.mybatis.dto.GoodsDTO;
import com.imooc.mybatis.entity.Goods;
import org.apache.ibatis.annotations.*;

import java.util.List;

public interface GoodsDAO {

    @Select("select * from t_goods")
    @Results({
            @Result(column = "goods_id",property = "goodsId",id = true),
            @Result(column = "title",property = "title"),
            @Result(column = "current_price",property = "currentPrice")

    })
    public List<GoodsDTO> selectAll();


}

说明:

(1) @Results注解标签,就对应了在Mapper XML中的标签。@Results({})的大括号,代表里面是一个数组;

(2)

(3)实际调用

package com.imooc.mybatis;

import com.imooc.mybatis.dao.GoodsDAO;
import com.imooc.mybatis.dto.GoodsDTO;
import com.imooc.mybatis.entity.Goods;
import com.imooc.mybatis.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

/**
 * JUnit测试类
 */
public class MyBatisTestor {

    @Test
    public void testSelectAll() throws Exception {
        SqlSession session = null;
        try {
            session = MyBatisUtils.openSession();
            GoodsDAO goodsDAO = session.getMapper(GoodsDAO.class);
            List<GoodsDTO> list = goodsDAO.selectAll();
            System.out.println(list.size());
        } catch (Exception e) {
            throw e;
        }finally {
            MyBatisUtils.closeSession(session);
        }
    }
}

运行结果:

打断点可以看到返回结果:


Mapper XML的开发方式: 有更好的维护性,我们不用修改java代码,可以让我们在XML中对SQL进行灵活的修改。这种开发方式更适合大型的,需要团队合作的项目。

注解开发方式: 更好的程序编码体验。这种方式适合小型,敏捷开发的工程。

So,注解开发方式仅供了解,主要还是采用XML的开发方式。