项目——通过自动回复机器人学Mybatis(自己添加ajax代码优化)(三)

时间:2021-08-01 21:41:45

为了监控Mybatis执行的sql语句,我们可以利用日志打印执行的语句


应用log4j调试动态SQL

首先添加log4j的jar包到lib下 添加log4j的配置文件,配置文件在mybatis的演示代码中也有,直接就添加在src目录下就好了 log4j.properties:
log4j.rootLogger=DEBUG,Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.org.apache=INFO

properties文件中数据格式:key=value

log4j.rootLogger=DEBUG,Console==>针对整个工程输出日志的级别(DEBUG)和输出位置(Console,可随便取名)
log4j.appender.Console=org.apache.log4j.ConsoleAppender==>定义输出位置在控制台
log4j.appender.Console.layout=org.apache.log4j.PatternLayout==>输出内容的布局
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n==>自定义输出格式:%d是产生日志的时间,%t是产生日志的线程的名称,%p是产生日志的级别,%c是输出日志所在的包名和类名,%m是输出语句的附加信息,%n是换行符
log4j.logger.org.apache=INFO==>指定某个包的输出日志级别为INFO(个性化)


这样就全部配置好了,可是只是添加了jar包和配置文件就能用了?Mybatis怎么启用log4j的呢? 打开Mybatis的源码org.apache.ibatis.logging包下的LogFactory.class
public final class LogFactory {

/**
* Marker to be used by logging implementations that support markers
*/
public static final String MARKER = "MYBATIS";

private static Constructor<? extends Log> logConstructor;

static {
tryImplementation(new Runnable() {
@Override
public void run() {
useSlf4jLogging();
}
});
tryImplementation(new Runnable() {
@Override
public void run() {
useCommonsLogging();
}
});
tryImplementation(new Runnable() {
@Override
public void run() {
useLog4J2Logging();
}
});
tryImplementation(new Runnable() {
@Override
public void run() {
useLog4JLogging();
}
});
tryImplementation(new Runnable() {
@Override
public void run() {
useJdkLogging();
}
});
tryImplementation(new Runnable() {
@Override
public void run() {
useNoLogging();
}
});
}

private LogFactory() {
// disable construction
}
.................................

上面都是Mybatis支持的日志,可以看到有log4j,在org.apache.ibatis.logging.log4j包下还有log4j的实现类,定义了打印信息的形式

控制台打印示例:
项目——通过自动回复机器人学Mybatis(自己添加ajax代码优化)(三)
第二句sql中的?替换的就是#{},Total为返回结果数



实现单条信息删除

首先在Message.xml中添加删除sql语句

<delete id="deleteOne" parameterType="int">
delete from MESSAGE where ID = #{_parameter}
</delete>
#{}中的取值写法可以视为和OGNL相同,因此填写_parameter


在MessageDao中添加删除代码:

public void deleteOne(int id){
DBAccess dbAccess = new DBAccess();
SqlSession sqlSession=null;
try {
sqlSession=dbAccess.getSqlSession();
//通过sqlSession执行SQL语句
sqlSession.delete("Message.deleteOne",id);
} catch (Exception e) {
e.printStackTrace();
}finally{
if(sqlSession!=null){
sqlSession.close();
}

}
}


在service包下添加MaintainService:

public class MaintainService {

public void deleteOne(String id){
if(id!=null&&!"".equals(id)){
MessageDao messageDao=new MessageDao();
messageDao.deleteOne(Integer.valueOf(id));
}
}
}
Service中主要负责的就是这些,类型转换啊,判断参数null啊等等

新建一个deleteOneServlet:

public class deleteOneServlet extends HttpServlet {

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
//设置编码
req.setCharacterEncoding("UTF-8");

String id=req.getParameter("id");

MaintainService maintainService = new MaintainService();
maintainService.deleteOne(id);

req.getRequestDispatcher("/list.action").forward(req,resp);
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
this.doGet(req, resp);
}

}

注意req.getRequestDispatcher("/list.action").forward(req,resp);


list.jsp修改:

<a href="${basePath}del_One.action?id=${message.id}">删除</a>

最后别忘了在web.xml中注册deleteOneServlet

完成执行,可是并没有删掉,删除sql日志倒是打印出来了,这是因为增删改都是要修改数据库的,有事务控制,这是mybatis,如果是jdbc的connection倒不用(因为它是自动提交的),所以我们要手动提交
public void deleteOne(int id){
DBAccess dbAccess = new DBAccess();
SqlSession sqlSession=null;
try {
sqlSession=dbAccess.getSqlSession();
//通过sqlSession执行SQL语句
sqlSession.delete("Message.deleteOne",id);
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
}finally{
if(sqlSession!=null){
sqlSession.close();
}

}
}



看似做完了,可还是有几个问题:

1.删除成功的提示 2.当你查询命令"测试“时,出现若干数据,删除其中一个,此时列表页面竟跳回了查询之前的页面,不过数据的确是少了一条,删除操作是没问题的,问题是它居然跳回去了,我们希望的肯定是它还留在查询"测试"的页面下,究其原因是我们用了get提交(<a href="${basePath}del_One.action?id=${message.id}">删除</a>),没有提交表单数据即查询条件

综合以上,我决定用ajax的post请求来实现