发表于: 2017-12-07 01:17:19
1 685
今天完成的事情:
完成了mybatis + spring + servlet 一个小框架的搭建
明天计划的事情:
买一个阿里云服务器,部署上去,完全没弄过。
遇到的问题:
1、在姓名进行模糊查询的时候,有如下配置
<select id="findByName" parameterType="java.lang.String" resultType="com.rabbit.model.Student">
select * from tab_student where s_name LIKE '%${_parameter}%';//此处大括号里面的参数不能写其他的,只能写_parameter
</select>
查了一下,并没有搞清楚为什么。
收获:
小项目使用了mybatis和spring,完成了学员的增加,姓名模糊查询、id精确查询,在进行两个框架整合的时候遇到不少问题,记录梳理如下。
1、spring对servlet的管理需要采用代理的方式:
最初的时候想当然的把servlet和struts2的action一样理解,将servlet同样交给spring容器管理,一直报错,网上查询后才意识到两者并不一样,
servlet在整个web中只会执行一次init()方法,每次访问的时候都是同一个servlet。在项目中应该采用servlet的代理类交给spring管理。代码如下:
servlet代理类:
public class DelegateServletProxy extends GenericServlet {
private String targetBean;// 保存url中servlet的名字
private Servlet proxy;//生成的servlet实例
//调用servlet实例的service方法,完成真正的servlet的工作
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
proxy.service(servletRequest,servletResponse);}
//代理类的init()方法
public void init() throws ServletException{
//获取访问的servlet的名字
this.targetBean = getServletName();
//创建webapplicatinContext
WebApplicationContext webApplicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
//根据servlet的名字生成servlet实例
this.proxy = (Servlet) webApplicationContext.getBean(targetBean);
//初始化servlet实例
proxy.init(getServletConfig());
}
}
代码的本质其实就是在每次访问servlet代理对象的时候,生成一个新的servlet,调用新生成的servlet完成工作。
相应的在web.xml中关于servlet的配置也要修改如下:
<servlet><servlet-name>studentServlet</servlet-name>
//这里的servlet指向的是代理servlet,他更像是一个servlet生成器。
<servlet-class>com.rabbit.servlet.DelegateServletProxy</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>studentServlet</servlet-name>
<url-pattern>/studentServlet</url-pattern>
</servlet-mapping>
2、用一个servlet完成所有的增删改查工作。
思路就是在调用servlet的时候多传一个参数,在doGet或者doPost方法里面更具传入的参数做判断,调用service的具体哪个方法,即可完成该功能。
3、关于使用mybatis的时候,在插入操作后返回插入数据的自增主键。
实现代码如下:
@Insert("insert into tab_student (s_name,s_QQ) values(#{s_name},#{s_QQ})")
//这条注解的意思为获得主键的值,并将其赋予到属性“s_id”上。
@Options(useGeneratedKeys = true,keyProperty = "s_id",keyColumn = "s_id")int add(Student student);
//完成以上操作后需要代码显性的查询获得主键值,而非自动返回。比如在service层中完成插入后
//此为service层的add方法,返回的就是自增主键。
public int add(Student student){
studentDao.add(student);
//此处不能直接写 return studentDao.add(student); 这样的返回自一直是1,具体什么原理没有往深入查。
return student.getS_id()
}
由此我也回顾一下关于sql中返回自增主键的方式:
sql = "INSERT INTO …………";//insert 语句
//关键在于Statement.RETURN_GENERATE_KEYS的参数设定
PreparedStatement pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
pstmt.setString(1, ……);
pstmt.executeUpdate();
//检索由于执行此 Statement 对象而创建的所有自动生成的键
ResultSet rs = pstmt.getGeneratedKeys();
if (rs.next()) {
//知其仅有一列,故获取第一列 ,获得
int id = rs.getInt(1);
}
4、request在获取参数的时候,传给后台数据库,中文老师乱码。
这个问题在于servlet中的httprequest和httpresponse中保存的参数都是默认以 iso-8859-1的编码形式存储的,我自己的web设置的全局编码为utf-8,需要对request的编码进行修改,查了一下好像对于post和get方式提交的参数,设置的方法不一样,get方式提交的麻烦一些,所以我就把所有的提交方式都用post提交。具体代码如下:
httpServletRequest.setCharacterEncoding("utf-8");
将这句代码加在doPost方法的方法体内第一句,提交过来的doPost方法里面的request编码方式就不会有问题了。
评论