mapper动态代理实现crud 约定优于配置
目录
前言
mybatis官方不支持通过硬编码的方式实现CRUD,通常要求使用配置.基础环境与XML文件配置不再赘述,动态代理模式与普通方式的不同在于 定位SQL语句 一般使用 mapper_namespace+id 进行字符串拼接,传入session.select()等方法中。现在通过 约定 的方式定位到该SQL语句,暨使用该接口全类名映射mapper文件的namespace,就可以通过接口方法名找到mapper文件SQL标签ID。
一、约定 的实现方式
建立接口,进行如下约定:(接口方法默认为public abstract 修饰,可写可不写)
- 约定 接口中的方法名要和mapper文件中的标签ID值相同
- 约定 该方法的输入参数和mapper文件中的标签的parameterType一致
- 约定 该方法 的输出参数(返回值)和mapper文件中的标签的resultType一致
二、使用步骤
1.基于接口(动态代理)实现mybatis的crud
代码如下(示例):
首先,将一些重复的代码写成一个utils
package priv.practie.mapper;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class SqlSessionFactoryUtils {
private static SqlSessionFactory FACTORY = null;
private static String SOURCE = "mybatis-config.xml";
public static SqlSessionFactory getInstance() throws IOException {
InputStream reader = Resources.getResourceAsStream(SOURCE) ;
FACTORY=new SqlSessionFactoryBuilder().build(reader);
return FACTORY;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
以后获取 SqlSessionFactory,就可以直接调用以上的类直接获取。
之后在同一个包下创建名称相同的mapper.xml文件和接口。接口的方法与xml文件中的SQL标签一一对应,既(mapper.xml没有parameterType接口方法就不传参数,mapper.xml没有resultType接口方法就为void方法):
- 约定 接口中的方法名要和mapper文件中的标签ID值相同
- 约定 该方法的输入参数和mapper文件中的标签的parameterType一致
- 约定 该方法 的输出参数(返回值)和mapper文件中的标签的resultType一致
2.相关具体设置
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="priv.practie.mapper.UserMapper">
<select id="selectById" parameterType="int" resultType="priv.practice.orm.User">
<!-- priv.practie.mapper.UserMapper.selectById -->
select * from user where id = #{id}
</select><insert id="addUser" parameterType="priv.practice.orm.User" >
<!-- priv.practice.orm.Mapper.addUser -->
insert into user(name,pwd) values (#{name},#{pwd})
</insert><!-- deleteUser -->
<delete id="deleteUser" parameterType="String">
<!-- priv.practice.orm.Mapper.deleteUser -->
delete from user where name=#{name}
</delete><!-- select ALL Users -->
<select id="selectAllUsers" resultType="priv.practice.orm.User">
select * from user
</select></mapper>
对应的接口代码如下 :
package priv.practie.mapper;
import java.util.List;
import priv.practice.orm.User;
public interface UserMapper {
User selectById(int id);
void addUser(User user);
void deleteUser(String name);
List<User> selectAllUsers();
}
之后通过 UserMapper userMapper = session.getMapper(UserMapper.class); 方式调用该接口中的方法,即可定位到对应的mapper.xml文件中的SQL标签。
package priv.practice.orm;
import java.io.IOException;
import java.util.List;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import priv.practie.mapper.*;
public class ProxyApply {
public static void query() throws IOException {
String source = "mybatis-config.xml";
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build
(Resources.getResourceAsReader(source) );
SqlSession session=factory.openSession();
String querySql ="priv.practie.mapper.UserMapper.selectById";
User user=(User) session.selectOne(querySql, 5);
user.toString();
}
public static void queryProxy(int id) throws IOException {
SqlSessionFactoryUtils utils = new SqlSessionFactoryUtils();
SqlSessionFactory factory = utils.getInstance();
SqlSession session=factory.openSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
User user= userMapper.selectById(id);
user.toString();
session.close();
}
// add user addUser(user) name + pwd
public static void addUser(User user) throws IOException {
SqlSessionFactory utils = new SqlSessionFactoryUtils().getInstance();
SqlSession session = utils.openSession();
UserMapper adduser = session.getMapper(UserMapper.class);
adduser.addUser(user);
session.commit();
session.close();
}
//delete User
public static void deleteUser(String name) throws IOException {
SqlSessionFactory factory = new SqlSessionFactoryUtils().getInstance();
SqlSession session = factory.openSession();
UserMapper dUser = session.getMapper(UserMapper.class);
dUser.deleteUser(name);
session.commit();
session.close();
}
// selectAllUsers
public static List<User> getAllUsers() throws IOException {
SqlSessionFactory factory = new SqlSessionFactoryUtils().getInstance();
SqlSession session = factory.openSession();
UserMapper allUsers =session.getMapper(UserMapper.class) ;
List<User> users =allUsers.selectAllUsers();
System.out.println(users);
session.close();
return users;
}
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
// query() ;
// queryProxy(1) ;
// User adduser = new User("ET","aliens");//"me","ffff"
// addUser(adduser);
// queryProxy(12) ;
//
//delete User
// deleteUser("me");
getAllUsers();
}
}
总结
重点是注意 mapper.xml文件 & 接口 的一一对应关系。
通过与mapper.xml文件 路径与名称相同的接口,以反射的方式调用接口方法就是调用xml文件的SQL标签,从而实现CRUD。
UserMapper userMapper = session.getMapper(UserMapper.class);