MyBatis学习日志三
基于注解的示例
如果实在看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); }
2.在全局配置文件中修改<mappers>
标签,直接指定加载这个类
<?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> <properties resource="properties/db.properties"></properties> <typeAliases> <package name="com.yogurt.po"/> </typeAliases> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${db.driver}"/> <property name="url" value="${db.url}"/> <property name="username" value="${db.user}"/> <property name="password" value="${db.password}"/> </dataSource> </environment> </environments> <mappers> <mapper class="com.yogurt.mapper.PureStudentMapper"/> </mappers> </configuration>
测试代码如下
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); } }
结果如下
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中设置了值,即它做了
注:当使用注解开发时,若需要传入多个参数,可以结合@Param
注解,示例如下
Map<String,Object> map = new HashMap<>(); map.put("name", name); map.put("major",major);
将方法形参中的name
和major
放到了map对象中,所以在@Select
标签中可以用${name}
和${major}
取出map对象中的值。
--------------------(我是分割线)
上面我们见到了在全局配置文件中,两种配置mapper的方式,分别是
<!-- 在mapper接口中使用注解 --> <mappers> <mapper class="com.yogurt.mapper.PureStudentMapper"/> </mappers> <!-- 普通加载xml --> <mappers> <mapper resource="StudentMapper.xml"/> </mappers>
而在实际工作中,一般我们会将一张表的SQL操作封装在一个mapper.xml中,可能有许多张表需要操作,那么我们是不是要在<mappers>
标签下写多个<mapper>
标签呢?其实不用,还有第三种加载mapper的方法,使用<package>
标签
<mappers> <package name="com.yogurt.mapper"/> </mappers>
这样就会自动加载com.yogurt.mapper包下的所有mapper,这种方式需要将mapper接口文件和mapper.xml文件都放在com.yogurt.mapper包下,且接口文件和xml文件的文件名要一致。注意,在IDEA的maven开发环境下,maven中还需配置<resources>标签,否则maven打包不会将java源码目录下的xml文件打包进去,见下文
三种加载mapper的方式总结
<mapper resource="" />
加载普通的xml文件,传入xml的相对路径(相对于类路径)
<mapper class="" />
使用mapper接口的全限定名来加载,若mapper接口采用注解方式,则不需要xml;若mapper接口没有采用注解方式,则mapper接口和xml文件的名称要相同,且在同一个目录
<package name="" />
扫描指定包下的所有mapper,若mapper接口采用注解方式,则不需要xml;若mapper接口没有采用注解方式,则mapper接口和xml文件的名称要相同,且在同一目录
注意:用后两种方式加载mapper接口和mapper.xml映射文件时,可能会报错
仔细检查了一下,mapper接口文件和xml映射文件确实放在了同一个目录下,而且文件名一致,xml映射文件的namespace也和mapper接口的全限定名对的上。
其实是因为,对于src/main/java
源码目录下的文件,maven打包时只会将该目录下的java文件打包,而其他类型的文件都不会被打包进去,去工程目录的target目录下看看maven构建后生成的文件
在pom.xml中的<build>
标签下 添加<resources>
标签,指定打包时要将xml文件打包进去
<build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> </resources> </build>
此时再用maven进行打包,看到对应目录下有了xml映射文件