Mybatis中配置Mapper的方法
在這篇文章中我主要想講一下Mybatis配置文件中mappers元素的配置。關於基礎部分的內容可以參考http://haohaoxuexi.iteye.com/blog/1333271。
我們知道在Mybatis中定義Mapper信息有兩種方式,一種是利用xml寫一個對應的包含Mapper信息的配置文件;另一種就是定義一個Mapper接口,然後定義一些相應的操作方法,再輔以相應的操作註解。
現假設我有這樣一個實體類:
- package com.tiantian.mybatis.model;
- public class User {
- private int id;
- private String name;
- private int age;
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- }
它對應的數據庫表結構是這樣的:
然後我要利用Mybatis對它做一個簡單的增刪改查操作,那麼如果利用xml配置Mapper的方式來定義的話,我對應的UserMapper.xml文件會是這樣:
- <?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">
- <mapper namespace="com.tiantian.mybatis.mapper.UserMapper">
- <insert id="insertUser" parameterType="User" useGeneratedKeys="true" keyColumn="id">
- insert into t_user(name, age) values(#{name}, #{age})
- </insert>
- <update id="updateUser" parameterType="User">
- update t_user set name=#{name}, age=#{age} where id=#{id}
- </update>
- <select id="findById" parameterType="int" resultType="User">
- select * from t_user where id=#{id}
- </select>
- <delete id="deleteUser" parameterType="int">
- delete from t_user where id=#{id}
- </delete>
- </mapper>
如果使用接口加註解的方式,那麼我們的UserMapper接口應該這樣定義:
- package com.tiantian.mybatis.mapperinterface;
- import org.apache.ibatis.annotations.Delete;
- import org.apache.ibatis.annotations.Insert;
- import org.apache.ibatis.annotations.Select;
- import org.apache.ibatis.annotations.Update;
- import com.tiantian.mybatis.model.User;
- public interface UserMapper {
- @Insert("insert into t_user(name, age) values(#{name}, #{age})")
- public void insertUser(User user);
- @Update("update t_user set name=#{name}, age=#{age} where id=#{id}")
- public void updateUser(User user);
- @Select("select * from t_user where id=#{id}")
- public User findById(int id);
- @Delete("delete from t_user where id=#{id}")
- public void deleteUser(int id);
- }
注意看這裏我故意把UserMapper接口的namespace也就是它的包名置爲與UserMapper.xml的namespace屬性不一樣。這主要是爲了要更好的講以下的內容。
接下來要做的就是把Mapper信息註冊到Mybatis的配置中,告訴Mybatis我們定義了哪些Mapper信息。這主要是在Mybatis的配置文件中通過mappers元素來進行的。在以前版本的Mybatis中我們在Mybatis的配置文件中需要這樣定義Mapper信息資源的位置。
- <mappers>
- <mapper resource="com/tiantian/mybatis/mapper/UserMapper1.xml"/>
- <mapper url="file:///E:/UserMapper.xml"/>
- </mappers>
這主要是通過mapper元素的resource和url屬性來指定的,resource屬性指定的是相對於跟類路徑下的資源,url屬性指定的是通過URL可以獲取到的資源。這有一點不好的地方,當我們使用Mapper接口加註解來定義當前Mapper的操作信息時,我們還需要定義一個與它對應的Mapper.xml文件。如:
- <?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">
- <mapper namespace="com.tiantian.mybatis.mapperinterface.UserMapper">
- </mapper>
- package com.tiantian.mybatis.mapperinterface;
- import org.apache.ibatis.annotations.Delete;
- import org.apache.ibatis.annotations.Insert;
- import org.apache.ibatis.annotations.Select;
- import org.apache.ibatis.annotations.Update;
- import com.tiantian.mybatis.model.User;
- public interface UserMapper {
- @Insert("insert into t_user(name, age) values(#{name}, #{age})")
- public void insertUser(User user);
- @Update("update t_user set name=#{name}, age=#{age} where id=#{id}")
- public void updateUser(User user);
- @Select("select * from t_user where id=#{id}")
- public User findById(int id);
- @Delete("delete from t_user where id=#{id}")
- public void deleteUser(int id);
- }
我發現在現在使用的這個Mybatis3.2.1中這個問題已經得到了改善,現在我們在定義基於接口的定義的Mapper時可以通過一個class屬性來指定接口。
除了通過class屬性指定Mapper接口外,Mybatis還爲我們提供了一個可以同時指定多個Mapper接口的方法。在現在的Mybatis版本中我們可以在mappers元素下面定義一個package子元素,用以指定Mapper接口所在的包,這樣Mybatis就會把這個包下面的所有Mapper接口都進行註冊。
這裏的一個package只針對於一個包。當在多個包裏面定義有Mapper接口時,我們需要定義對應的多個package元素。
這四種註冊Mapper的方式就是我想在這篇文章中表達的。總結一下:
- <mappers>
- <!-- 通過package元素將會把指定包下面的所有Mapper接口進行註冊 -->
- <package name="com.tiantian.mybatis.mapperinterface"/>
- <!-- 通過mapper元素的resource屬性可以指定一個相對於類路徑的Mapper.xml文件 -->
- <mapper resource="com/tiantian/mybatis/mapper/UserMapper.xml"/>
- <!-- 通過mapper元素的url屬性可以指定一個通過URL請求道的Mapper.xml文件 -->
- <mapper url="file:///E:/UserMapper.xml"/>
- <!-- 通過mapper元素的class屬性可以指定一個Mapper接口進行註冊 -->
- <mapper class="com.tiantian.mybatis.mapperinterface.UserMapper"/>
- </mappers>
當使用mapper元素進行Mapper定義的時候需要注意:mapper的三個屬性resource、url和class對於每個mapper元素只能指定一個,要麼指定resource屬性,要麼指定url屬性,要麼指定class屬性,不能都指定,也不能都不指定。
下面將對上面的代碼給出一些對應的測試代碼。先貼出測試對應的Mybatis的配置文件:
- <?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="config/jdbc.properties"></properties>
- <typeAliases>
- <package name="com.tiantian.mybatis.model"/>
- </typeAliases>
- <environments default="development">
- <environment id="development">
- <transactionManager type="JDBC" />
- <dataSource type="POOLED">
- <property name="driver" value="${jdbc.driver}" />
- <property name="url" value="${jdbc.url}" />
- <property name="username" value="${jdbc.username}" />
- <property name="password" value="${jdbc.password}" />
- </dataSource>
- </environment>
- </environments>
- <mappers>
- <mapper resource="com/tiantian/mybatis/mapper/UserMapper.xml"/>
- <package name="com.tiantian.mybatis.mapperinterface"/>
- </mappers>
- </configuration>
1.對於使用xml方式定義的UserMapper.xml,然後直接使用SqlSession訪問定義在其中的statement的測試:
- package com.tiantian.mybatis.test;
- import org.apache.ibatis.session.SqlSession;
- import org.apache.ibatis.session.SqlSessionFactory;
- import org.junit.Before;
- import org.junit.Test;
- import com.tiantian.mybatis.model.User;
- import com.tiantian.mybatis.util.Util;
- /**
- *
- * 這個類主要用來測試直接使用SqlSession訪問定義在UserMapper.xml文件中的statement
- *
- */
- public class UserMapperTest {
- SqlSessionFactory sqlSessionFactory = null;
- @Before
- public void before() {
- sqlSessionFactory = Util.getSqlSessionFactory();
- }
- @Test
- public void testInsert() {
- SqlSession sqlSession = sqlSessionFactory.openSession();
- try {
- User user = new User();
- user.setName("張三");
- user.setAge(30);
- sqlSession.insert("com.tiantian.mybatis.mapper.UserMapper.insertUser", user);
- sqlSession.commit();
- } finally {
- sqlSession.close();
- }
- }
- @Test
- public void testUpdate() {
- SqlSession sqlSession = sqlSessionFactory.openSession();
- try {
- User user = new User();
- user.setId(1);
- user.setName("李四");
- user.setAge(34);
- sqlSession.update("com.tiantian.mybatis.mapper.UserMapper.updateUser", user);
- sqlSession.commit();
- } finally {
- sqlSession.close();
- }
- }
- @Test
- public void testFind() {
- SqlSession sqlSession = sqlSessionFactory.openSession();
- try {
- User user = sqlSession.selectOne("com.tiantian.mybatis.mapper.UserMapper.findById", 1);
- System.out.println(user.getId() + "--" + user.getName() + "--" + user.getAge());
- } finally {
- sqlSession.close();
- }
- }
- @Test
- public void testDelele() {
- SqlSession sqlSession = sqlSessionFactory.openSession();
- try {
- sqlSession.delete("com.tiantian.mybatis.mapper.UserMapper.deleteUser", 2);
- sqlSession.commit();
- } finally {
- sqlSession.close();
- }
- }
- }
2.對於使用Mapper接口加對應的註解來定義的Mapper信息直接使用SqlSession訪問Mapper接口中使用註解定義好的statement的測試:
- package com.tiantian.mybatis.test;
- import org.apache.ibatis.session.SqlSession;
- import org.apache.ibatis.session.SqlSessionFactory;
- import org.junit.Before;
- import org.junit.Test;
- import com.tiantian.mybatis.model.User;
- import com.tiantian.mybatis.util.Util;
- /**
- *
- *這個類是測試直接使用SqlSession訪問UserMapper接口中使用註解定義好的statement
- *
- */
- public class UserMapperTest2 {
- SqlSessionFactory sqlSessionFactory = null;
- @Before
- public void before() {
- sqlSessionFactory = Util.getSqlSessionFactory();
- }
- @Test
- public void testInsert() {
- SqlSession sqlSession = sqlSessionFactory.openSession();
- try {
- User user = new User();
- user.setName("張三");
- user.setAge(30);
- sqlSession.insert("com.tiantian.mybatis.mapperinterface.UserMapper.insertUser", user);
- sqlSession.commit();
- } finally {
- sqlSession.close();
- }
- }
- @Test
- public void testUpdate() {
- SqlSession sqlSession = sqlSessionFactory.openSession();
- try {
- User user = new User();
- user.setId(1);
- user.setName("李四");
- user.setAge(34);
- sqlSession.update("com.tiantian.mybatis.mapperinterface.UserMapper.updateUser", user);
- sqlSession.commit();
- } finally {
- sqlSession.close();
- }
- }
- @Test
- public void testFind() {
- SqlSession sqlSession = sqlSessionFactory.openSession();
- try {
- User user = sqlSession.selectOne("com.tiantian.mybatis.mapperinterface.UserMapper.findById", 1);
- System.out.println(user.getId() + "--" + user.getName() + "--" + user.getAge());
- } finally {
- sqlSession.close();
- }
- }
- @Test
- public void testDelele() {
- SqlSession sqlSession = sqlSessionFactory.openSession();
- try {
- sqlSession.delete("com.tiantian.mybatis.mapperinterface.UserMapper.deleteUser", 3);
- sqlSession.commit();
- } finally {
- sqlSession.close();
- }
- }
- }
3.對於使用Mapper接口加註解定義好的Mapper信息通過SqlSession獲取其對應的Mapper接口來操作其中定義好的statement的測試:
- package com.tiantian.mybatis.test;
- import org.apache.ibatis.session.SqlSession;
- import org.apache.ibatis.session.SqlSessionFactory;
- import org.junit.Before;
- import org.junit.Test;
- import com.tiantian.mybatis.mapperinterface.UserMapper;
- import com.tiantian.mybatis.model.User;
- import com.tiantian.mybatis.util.Util;
- /**
- *
- *這個類是測試使用SqlSession獲取UserMapper接口來執行使用註解定義在UserMapper接口中的statement
- *
- */
- public class UserMapperTest3 {
- SqlSessionFactory sqlSessionFactory = null;
- @Before
- public void before() {
- sqlSessionFactory = Util.getSqlSessionFactory();
- }
- @Test
- public void testInsert() {
- SqlSession sqlSession = sqlSessionFactory.openSession();
- try {
- User user = new User();
- user.setName("張三");
- user.setAge(30);
- UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
- userMapper.insertUser(user);
- sqlSession.commit();
- } finally {
- sqlSession.close();
- }
- }
- @Test
- public void testUpdate() {
- SqlSession sqlSession = sqlSessionFactory.openSession();
- try {
- User user = new User();
- user.setId(1);
- user.setName("李四");
- user.setAge(34);
- UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
- userMapper.updateUser(user);
- sqlSession.commit();
- } finally {
- sqlSession.close();
- }
- }
- @Test
- public void testFind() {
- SqlSession sqlSession = sqlSessionFactory.openSession();
- try {
- UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
- User user = userMapper.findById(1);
- System.out.println(user.getId() + "--" + user.getName() + "--" + user.getAge());
- } finally {
- sqlSession.close();
- }
- }
- @Test
- public void testDelele() {
- SqlSession sqlSession = sqlSessionFactory.openSession();
- try {
- UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
- userMapper.deleteUser(5);
- sqlSession.commit();
- } finally {
- sqlSession.close();
- }
- }
- }