mybits基于注解的示例

44 阅读4分钟

基于注解的示例

如果实在看xml配置文件不顺眼,则可以考虑使用注解的开发方式,不过注解的开发方式,会将SQL语句写到代码文件中,后续的维护性和扩展性不是很好(如果想修改SQL语句,就得改代码,得重新打包部署,而如果用xml方式,则只需要修改xml,用新的xml取替换旧的xml即可)

使用注解的开发方式,也还是得有一个全局配置的xml文件,不过mapper.xml就可以省掉了,具体操作只用2步,如下

创建一个Mapper接口

package com.yogurt.mapper; import com.yogurt.po.Student; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Select; import java.util.List;

public interface PureStudentMapper {

@Select("SELECT * FROM student")
List<Student> findAll();

@Insert("INSERT INTO student (name,age,score,gender) VALUES (#{name},#{age},#{score},#{gender})")
int insert(Student student);

}

在全局配置文件中修改标签,直接指定加载这个类

<mappers>
    <mapper class="com.yogurt.mapper.PureStudentMapper"/>
</mappers>

测试代码如下

public class PureMapperTest {

    private SqlSessionFactory sqlSessionFactory;

        @Before
        public void init() throws IOException {
                InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        }

        @Test
        public void test() {
                SqlSession sqlSession = sqlSessionFactory.openSession();
                PureStudentMapper mapper = sqlSession.getMapper(PureStudentMapper.class);
                mapper.insert(new Student(10,"Tomcat",120,60,0));
        sqlSession.commit();
                List<Student> studentList = mapper.findAll();
                studentList.forEach(System.out::println);
      }
}

注:当使用注解开发时,若需要传入多个参数,可以结合@Param注解,示例如下

package org.mybatis.demo.mapper;

import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import org.mybatis.demo.po.Student;

import java.util.List;

public interface PureStudentMapper {

@Select("SELECT * FROM student WHERE name like '%${name}%' AND major like '%${major}%'")
List<Student> find(@Param("name") String name, @Param("major") String major);

}

@Param标签会被mybatis处理并封装成一个Map对象,比如上面的示例中,实际传入的参数是一个Map对象,@Param标签帮忙向Map中设置了值,即它做了

Map<String,Object> map = new HashMap<>(); map.put("name", name); map.put("major",major); 1 2 3 将方法形参中的name和major放到了map对象中,所以在@Select标签中可以用name{name}和{major}取出map对象中的值。 --------------------(我是分割线)

上面我们见到了在全局配置文件中,两种配置mapper的方式,分别是

而在实际工作中,一般我们会将一张表的SQL操作封装在一个mapper.xml中,可能有许多张表需要操作,那么我们是不是要在标签下写多个标签呢?其实不用,还有第三种加载mapper的方法,使用标签

这样就会自动加载com.yogurt.mapper包下的所有mapper,这种方式需要将mapper接口文件和mapper.xml文件都放在com.yogurt.mapper包下,且接口文件和xml文件的文件名要一致。注意,在IDEA的maven开发环境下,maven中还需配置标签,否则maven打包不会将java源码目录下的xml文件打包进去,见下文

三种加载mapper的方式总结

加载普通的xml文件,传入xml的相对路径(相对于类路径)

使用mapper接口的全限定名来加载,若mapper接口采用注解方式,则不需要xml;若mapper接口没有采用注解方式,则mapper接口和xml文件的名称要相同,且在同一个目录

扫描指定包下的所有mapper,若mapper接口采用注解方式,则不需要xml;若mapper接口没有采用注解方式,则mapper接口和xml文件的名称要相同,且在同一目录

注意:用后两种方式加载mapper接口和mapper.xml映射文件时,可能会报错

仔细检查了一下,mapper接口文件和xml映射文件确实放在了同一个目录下,而且文件名一致,xml映射文件的namespace也和mapper接口的全限定名对的上。为什么会这样呢?

其实是因为,对于src/main/java 源码目录下的文件,maven打包时只会将该目录下的java文件打包,而其他类型的文件都不会被打包进去,去工程目录的target目录下看看maven构建后生成的文件

我们需要在pom.xml中的 标签下 添加 标签,指定打包时要将xml文件打包进去

src/main/java **/*.xml

此时再用maven进行打包,看到对应目录下有了xml映射文件(特别注意,这里配置了pom.xml下的resource标签后,可能会引发一些问题,例如原本src/main/resources资源目录下的文件没有被打包进来,参考我的这篇文章maven打包时的资源文件问题)

此时再运行单元测试,就能正常得到结果了