Mybatis 框架总结(二) :增删改查
上一章利用的session的selectList等方法来调用Book.xmld的sql语句,这次在不借助session的情况下来完成增删改查
首先开发一个dao接口,里面有调用方法,不过接口方法的名字要和sql的id一致
package sdibt.lxj.dao;
import java.util.List;
import java.util.Map;
public interface IBookDao {
public void insert1(Map map);
public void delete1(int id);
public void update1(Map map);
public List
Book.xml namespace必须绑定该dao
Mapper元素只有一个属性namespace,它有两个作用:一是用于区分不同的mapper(在不同的mapper文件里,子元素的id可以相同,mybatis通过namespace和子元素的id联合区分),二是与接口关联(应用程序通过接口访问mybatis时,mybatis通过接口的完整名称查找对应的mapper配置,因此namespace的命名务必小心一定要某接口同名)
insert into book(book_name,book_price,book_page) values(#{bookName},#{bookPrice},#{bookPage})
delete from book where id=#{id}
update book set book_page=#{bookPage} where id=#{id}
update book
book_name=#{bookName},
book_price=#{bookPrice},
where id=#{id}
测试:
package sdibt.lxj.test;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.session.SqlSession;
import sdibt.lxj.dao.IBookDao;
import sdibt.lxj.util.MybatisUtils;
public class TestMybatis {
public static void main(String[] args) throws ClassNotFoundException {
SqlSession session = MybatisUtils.getSession();
IBookDao dao = session.getMapper(IBookDao.class);
List
分析一下是怎么执行sql的
IBookDao dao = session.getMapper(IBookDao.class); 采用动态代理机制获取dao的代理对象 代理模式
既然要创建代理对象,handler切面是不可少了,看一下mybatis的切面,貌似这里只提到了缓存
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (Object.class.equals(method.getDeclaringClass())) {
try {
return method.invoke(this, args);
} catch (Throwable t) {
throw ExceptionUtil.unwrapThrowable(t);
}
}
final MapperMethod mapperMethod = cachedMapperMethod(method);
return mapperMethod.execute(sqlSession, args);
}
既然有了handler,就可以获取代理对象了
获取完代理对象,看看代理对象是怎么执行方法的,肯定要调用切面的invoke方法,接下来会执行方法
public Object execute(SqlSession sqlSession, Object[] args) {
Object result;
if (SqlCommandType.INSERT == command.getType()) {
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.insert(command.getName(), param));
} else if (SqlCommandType.UPDATE == command.getType()) {
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.update(command.getName(), param));
} else if (SqlCommandType.DELETE == command.getType()) {
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.delete(command.getName(), param));
} else if (SqlCommandType.SELECT == command.getType()) {
if (method.returnsVoid() && method.hasResultHandler()) {
executeWithResultHandler(sqlSession, args);
result = null;
} else if (method.returnsMany()) {
result = executeForMany(sqlSession, args);
} else if (method.returnsMap()) {
result = executeForMap(sqlSession, args);
} else {
Object param = method.convertArgsToSqlCommandParam(args);
result = sqlSession.selectOne(command.getName(), param);
}
} else {
throw new BindingException("Unknown execution method for: " + command.getName());
}
if (result == null && method.getReturnType().isPrimitive() && !method.returnsVoid()) {
throw new BindingException("Mapper method '" + command.getName()
+ " attempted to return null from a method with a primitive return type (" + method.getReturnType() + ").");
}
return result;
}
现在调用的是select方法
private Object executeForMany(SqlSession sqlSession, Object[] args) {
List result;
Object param = method.convertArgsToSqlCommandParam(args);
if (method.hasRowBounds()) {
RowBounds rowBounds = method.extractRowBounds(args);
result = sqlSession.selectList(command.getName(), param, rowBounds);
} else {
result = sqlSession.selectList(command.getName(), param);
}
// issue #510 Collections & arrays support
if (!method.getReturnType().isAssignableFrom(result.getClass())) {
if (method.getReturnType().isArray()) {
return convertToArray(result);
} else {
return convertToDeclaredCollection(sqlSession.getConfiguration(), result);
}
}
return result;
}
这句话,还是调用了xml中的id