MyBatis接口映射

来源:互联网 发布:王者荣耀用户数据分析 编辑:程序博客网 时间:2024/05/21 04:43

MyBatis接口映射这个机制是通过面向接口编程,来代替传统的使用SqlSession调用

insert、select这种方式实现CRUD,MyBatis接口映射有两种实现方式,一种基于XML,另一种是基于注解。

 

基于XML:优点是可维护性、可拓展性高,SQL改动不需要动源代码,改配置文件即可,缺点是编写配置文件较为繁琐,需要定义大量的节点标签。

 

基于注解:优点是简洁,易用,开发速度快。不需要定义映射文件,缺点也显而易见,不利于改动,SQL语句的改动需要修改源代码,改动就意味着需要重新编译部署源代码。不过现在有个原则:规范大于约束。基于这个原则,改动的可能性并不大。

 

两种方式都有优缺点,按实际需求来决定使用哪种吧。


一。基于XML的接口映射

接口定义:

import java.util.List;import java.util.Map;public interface FoodMapper {                public Map<String, String> selectFoodById(String foodId);        public List<Map<String, String>> selectFoodsByName(String foodName);                public List<Map<String, String>> selectFoodsByPrice( String lowerLimit , String upperLimit);}

核心配置文件:

    这里就不贴全了,只贴映射声明:

    <mappers>            <!-- 还是老样子,映射XML的全路径 -->            <mapper resource="cn/et/lesson02/exer/xml/FoodMapper.xml"/>    </mappers>

映射文件:

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  <!--           接口绑定:将接口中的方法和对应的SQL进行绑定          命名空间使用映射的接口的全路径,对应的SQL声明的Id          则对应方法名。          --><mapper namespace="cn.et.lesson02.exer.xml.FoodMapper">  <select id="selectFoodById" resultType="java.util.Map">    select * from food where FOODID = #{param1}  </select>    <select id="selectFoodsByPrice" resultType="java.util.Map">          select * from food where PRICE between #{0} and #{1}  </select>    <select id="selectFoodsByName" resultType="java.util.Map">    select * from food where FOODNAME = #{0}  </select></mapper>

SQL语句如果需要参数,还是使用#{key}的方式,不过key并不是接口方法声明中的参数名了,而是参数的位置(下标),从0开始偏移。不过这些参数实际上是有名字的,默认是 'param1'、 'param2'...,如果现在上边的语句改成:

select * from food where PRICE between #{param1} and #{param2}

也是完全O几把K的。


如果要使用自定义的参数名,需要在方法的参数上加@Param注解:

@Param("自定义的参数名(key)")

like this:

@Param("lowerLimit") String lowerLimit ,@Param("upperLimit") String upperLimit

那么使用的时候就不能用0 1 或者 param1 param2的了,要这么写:

select * from food where PRICE between #{lowerLimit} and #{upperLimit}

这里还是用 0 1的方式吧。

注意:下标 0  1 或者 param1这种方式只能够用  #{key} 这种形式,不能用  ${key}这种。


测试方法:

@Testpublic void selectByName() throws IOException{        FoodMapper mapper = getSession().getMapper(FoodMapper.class);        System.out.println(mapper.selectFoodsByPrice("10", "55"));}

getSession是自己封装的一个方法,是用来获取SqlSession实例的。再通过SqlSession.getMapper,传入接口的.class,即可获取接口的实现类。这个实现类是

MyBatis自动实现的。

基于XML接口映射的原理是:

1.通过核心配置文件中的Mapper节点找到对应的Mapper.xml

2.再通过Mapper.xml命名空间中的接口全路径名获取找到该接口,创建该接口的实现类。

3.通过SQL声明的Id值找到对应的方法。这意味着接口中不能有重载,否则会报错。

其他insert、delete语句也是同理,举一反三即可。


二。基于注解的接口映射

接口:

import java.util.List;import java.util.Map;import org.apache.ibatis.annotations.Insert;import org.apache.ibatis.annotations.Select;public interface FoodMapper {                @Select("select * from food where FOODID = #{0}")        public Map<String, String> selectFoodById(String foodId);                @Select("select * from food where FOODNAME = #{0}")        public List<Map<String, String>> selectFoodsByName(String foodName);                @Select("select * from food where PRICE between #{0} and #{1}")        public List<Map<String, String>> selectFoodsByPrice( String lowerLimit , String upperLimit);                @Insert("insert into food values(FOOD_SEC.NEXTVAL , #{param1} , #{param2})")        public void insertFood(String foodName , String price);}

核心配置文件:

<mappers>        <mapper class="cn.et.lesson02.exer.anno.FoodMapper"/></mappers>

因为基于注解实现的接口映射省去了映射文件,所以mapper节点不再使用resource属性,而是使用class属性指向映射的接口


测试:

@Test        public void selectByPrice() throws IOException{        FoodMapper mapper = getSession().getMapper(FoodMapper.class);        System.out.println(mapper.selectFoodsByPrice("10", "55"));}

OK.








原创粉丝点击