Spring整合MyBatis案例练习笔记
需求:
用户登录
技术需求:
Servlet+Spring+Mybatis+MVC+jsp+css+html+jquery
数据库设计:
用户表
Sql语句设计:
select * from t_user where uname=#{0} and pwd=#{1}
实现:
mapper层
package com.bjsxt.mapper; import com.bjsxt.pojo.User; public interface UserMapper { //用户登录 User selUser(String uname,String pwd); }
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.bjsxt.mapper.UserMapper"> <!-- 用户登录sql配置 --> <select id="selUser" resultType="com.bjsxt.pojo.User"> select * from t_user where uname=#{arg0} and pwd=#{arg1} </select> </mapper>
pojo层
package com.bjsxt.pojo; /** * 用户实体类 * @author Yancy * */ public class User { private int uid;//用户ID private String uname;//用户名称 private String pwd;//用户密码 public int getUid() { return uid; } public void setUid(int uid) { this.uid = uid; } public String getUname() { return uname; } public void setUname(String uname) { this.uname = uname; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } public User(int uid, String uname, String pwd) { super(); this.uid = uid; this.uname = uname; this.pwd = pwd; } @Override public String toString() { return "User [uid=" + uid + ", uname=" + uname + ", pwd=" + pwd + "]"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((pwd == null) ? 0 : pwd.hashCode()); result = prime * result + uid; result = prime * result + ((uname == null) ? 0 : uname.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; User other = (User) obj; if (pwd == null) { if (other.pwd != null) return false; } else if (!pwd.equals(other.pwd)) return false; if (uid != other.uid) return false; if (uname == null) { if (other.uname != null) return false; } else if (!uname.equals(other.uname)) return false; return true; } public User() { super(); // TODO Auto-generated constructor stub } }
service层
package com.bjsxt.service; import com.bjsxt.pojo.User; public interface UserService { //用户登录 User checkUserInfoService(String uname,String pwd); }
service.impl层
package com.bjsxt.service.impl; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.bjsxt.mapper.UserMapper; import com.bjsxt.pojo.User; import com.bjsxt.service.UserService; public class UserServiceImpl implements UserService { private UserMapper um; public UserMapper getUm() { return um; } public void setUm(UserMapper um) { this.um = um; } //用户登录 @Override public User checkUserInfoService(String uname, String pwd) { //使用对象完成数据库操作 return um.selUser(uname, pwd); } }
servlet层
package com.bjsxt.servlet; import java.io.IOException; import javax.servlet.ServletException;import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; import com.bjsxt.pojo.User; import com.bjsxt.service.UserService; public class UserServlet extends HttpServlet{ UserService us; @Override public void init() throws ServletException { //传统方式 // //获取Spring容器对象 // ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); // //获取业务层对象 // us = (UserService) ac.getBean("us"); //优化方式 ApplicationContext ac=WebApplicationContextUtils.getWebApplicationContext(this.getServletContext()); us = (UserService) ac.getBean("us"); } @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //请求编码格式 req.setCharacterEncoding("utf-8"); //设置响应编码格式 resp.setCharacterEncoding("utf-8"); resp.setContentType("text/html;charset=utf-8"); //获取请求信息 String uname=req.getParameter("uname"); String pwd=req.getParameter("pwd"); //处理请求信息 //调用方法处理请求 User u = us.checkUserInfoService(uname, pwd); //处理响应结果 if(u!=null) { resp.sendRedirect(req.getContextPath()+"/success.jsp"); } } }
配置文件src目录下
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd"> <!-- 配置数据源 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/mybatis"></property> <property name="username" value="root"></property> <property name="password" value="123456"></property> </bean> <!-- 配置工厂bean --> <bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 配置mapper扫描bean --> <bean id="mapper" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="sqlSessionFactory" ref="factory"></property> <property name="basePackage" value="com.bjsxt.mapper"></property> </bean> <!-- 配置业务层bean --> <bean id="us" class="com.bjsxt.service.impl.UserServiceImpl"> <property name="um" ref="userMapper"></property> </bean> </beans>
log4j.properties
# Global logging configuration log4j.rootLogger=ERROR, stdout # MyBatis logging configuration... log4j.logger.com.bjsxt=DEBUG # Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
web.xml在WEB-INF下
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <!-- 配置Spring文件路径 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <!-- 配置监听器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 配置Servlet --> <servlet> <servlet-name>user</servlet-name> <servlet-class>com.bjsxt.servlet.UserServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>user</servlet-name> <url-pattern>/user</url-pattern> </servlet-mapping> </web-app>
整合问题及其解决方案:
问题一:
传统方式是在service层直接通过mybatis对象完成数据的操作,业务层和mapper层的耦合性非常高.
解决一:
使用SpringIOC技术和service层和mapper层进行解耦.
方案一:
直接从Spring容器对象中获取Mapper对象
--->Spring容器还管理SqlSession对象
--->Spring容器还管理DataSource对象
实现一:
参照配置文件
问题二:
如果在Servlet层中直接new创建业务层对象,虽然可以正常使用,但是会造成Servlet层和业务层的耦合性较高,不易于后期的的迭代升级.
解决二:
使用SpringIOC将Servlet层和service层进行解耦.
实现二:
将Service对象配置成bean,交由Spring容器管理.在Servlet中通过Spring容器对象获取业务层对象
问题三:
我们实现的登录代码,如果放在高并发环境,我们发现Spring容器对象一个线程中会被创建两次,这样造成占据的内存过多.
解决三:
①在service层中我们使用Spring容器对象获取Mapper接口对象,Mapper接口对象本身就在Spring容器中,但是我们把Service也配置成bean了,那么是不是可以使用依赖注入呢.直接在Spring的配置文件中通过依赖注入将Mapper对象注入给service对象
②使用init方法,将获取us对象的动作放到服务器启动是完成.
问题四:
Spring容器在获取的代码的路径在init方法中耦合性较高.
解决四:
将Spring容器相关路径信息配置到web.xml中
实现四:
在web.xml中配置全局参数表明Spring路径
配置Spring监听器