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&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的开发方式。