Mybatis中配置Mapper的方法
我们知道在Mybatis中定义Mapper信息有两种方式,一种是利用xml写一个对应的包含Mapper信息的配置文件;另一种就是定义一个Mapper接口,然后定义一些相应的操作方法,再辅以相应的操作注解。
现假设我有这样一个实体类:
package com.bijian.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;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", 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.bijian.mapper.UserMapper"> <insert id="insertUser" parameterType="User" useGeneratedKeys="true" keyColumn="id"> insert into user_tb(name, age) values(#{name}, #{age}) </insert> <update id="updateUser" parameterType="User"> update user_tb set name=#{name}, age=#{age} where id=#{id} </update> <select id="findById" parameterType="int" resultType="User"> select * from user_tb where id=#{id} </select> <delete id="deleteUser" parameterType="int"> delete from user_tb where id=#{id} </delete> </mapper>
如果使用接口加注解的方式,那么我们的UserMapper接口应该这样定义:
package com.bijian.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.bijian.model.User;
public interface UserMapper {
@Insert("insert into user_tb(name, age) values(#{name}, #{age})")
public void insertUser(User user);
@Update("update user_tb set name=#{name}, age=#{age} where id=#{id}")
public void updateUser(User user);
@Select("select * from user_tb where id=#{id}")
public User findById(int id);
@Delete("delete from user_tb 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/bijian/mapper/UserMapper.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.bijian.mapperinterface.UserMapper"> </mapper>
package com.bijian.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.bijian.model.User;
public interface UserMapper {
@Insert("insert into user_tb(name, age) values(#{name}, #{age})")
public void insertUser(User user);
@Update("update user_tb set name=#{name}, age=#{age} where id=#{id}")
public void updateUser(User user);
@Select("select * from user_tb where id=#{id}")
public User findById(int id);
@Delete("delete from user_tb where id=#{id}")
public void deleteUser(int id);
}
我发现在现在使用的这个Mybatis3.2.1中这个问题已经得到了改善,现在我们在定义基于接口的定义的Mapper时可以通过一个class属性来指定接口。
<mappers> <mapper class="com.bijian.mapperinterface.UserMapper"/> </mappers>
这里的一个package只针对于一个包。当在多个包里面定义有Mapper接口时,我们需要定义对应的多个package元素。
这四种注册Mapper的方式就是我想在这篇文章中表达的。总结一下:
<mappers> <!-- 通过package元素将会把指定包下面的所有Mapper接口进行注册 --> <package name="com.bijian.mapperinterface"/> <!-- 通过mapper元素的resource属性可以指定一个相对于类路径的Mapper.xml文件 --> <mapper resource="com/bijian/mapper/UserMapper.xml"/> <!-- 通过mapper元素的url属性可以指定一个通过URL请求道的Mapper.xml文件 --> <mapper url="file:///E:/UserMapper.xml"/> <!-- 通过mapper元素的class属性可以指定一个Mapper接口进行注册 --> <mapper class="com.bijian.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> <typeAliases> <typeAlias alias="User" type="com.bijian.model.User" /> </typeAliases> <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8" /> <property name="username" value="test" /> <property name="password" value="test" /> </dataSource> </environment> </environments> <mappers> <!-- 通过mapper元素的resource属性可以指定一个相对于类路径的Mapper.xml文件 --> <mapper resource="com/bijian/mapper/UserMapper.xml" /> <!-- 通过package元素将会把指定包下面的所有Mapper接口进行注册 --> <package name="com.bijian.mapperinterface" /> </mappers> </configuration>
Util.java
package com.bijian.util;
import java.io.IOException;
import java.io.Reader;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class Util {
public static SqlSessionFactory getSqlSessionFactory() {
String resource = "configure.xml";
Reader reader = null;
try {
reader = Resources.getResourceAsReader(resource);
} catch (IOException e) {
e.printStackTrace();
}
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
return factory;
}
}
一.对于使用xml方式定义的UserMapper.xml,然后直接使用SqlSession访问定义在其中的statement的测试:
package com.bijian.test;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Before;
import org.junit.Test;
import com.bijian.model.User;
import com.bijian.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.bijian.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.bijian.mapper.UserMapper.updateUser", user);
sqlSession.commit();
} finally {
sqlSession.close();
}
}
@Test
public void testFind() {
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
User user = sqlSession.selectOne("com.bijian.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.bijian.mapper.UserMapper.deleteUser", 2);
sqlSession.commit();
} finally {
sqlSession.close();
}
}
}
二.对于使用Mapper接口加对应的注解来定义的Mapper信息直接使用SqlSession访问Mapper接口中使用注解定义好的statement的测试:
package com.bijian.test;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Before;
import org.junit.Test;
import com.bijian.model.User;
import com.bijian.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.bijian.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.bijian.mapperinterface.UserMapper.updateUser", user);
sqlSession.commit();
} finally {
sqlSession.close();
}
}
@Test
public void testFind() {
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
User user = sqlSession.selectOne("com.bijian.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.bijian.mapperinterface.UserMapper.deleteUser", 3);
sqlSession.commit();
} finally {
sqlSession.close();
}
}
}
三.对于使用Mapper接口加注解定义好的Mapper信息通过SqlSession获取其对应的Mapper接口来操作其中定义好的statement的测试:
package com.bijian.test;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Before;
import org.junit.Test;
import com.bijian.mapperinterface.UserMapper;
import com.bijian.model.User;
import com.bijian.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();
}
}
}