659 login case database creation web project construction login page creation
Use Servlet+MVC+Mybatis+Jsp to complete user login
① Create t in mysql_ User user information table (id,name,pwd)
② Use idea to create a new web project named 01 spring IOC mybatis login
③ Import relevant jar packages in the web project (spring IOC jar+Mybatis jar+mysql jar)
④ Create login. In the web project JSP login page and send login request
Set jsp template!
<% String path=request.getContextPath(); String basePath=request.getScheme()+"://"+request.getServerName()+":"+request .getServerPort()+path+"/"; %> ... <base href="<%=basePath%>">
<form action="userLogin" method="post"> user name:<input type="text" name="uname" value=""><br/> password:<input type="password" name="pwd" value=""><br/> <input type="submit" value="Sign in"> </form>
660 complete implementation of login function
⑤ Create UserServlet in the web project and improve the code to handle login requests
package com.bjsxt.controller; import com.bjsxt.pojo.User; import com.bjsxt.service.UserService; import com.bjsxt.service.impl.UserServiceImpl; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; @WebServlet("/userLogin") public class UserServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //Format request encoding req.setCharacterEncoding("utf-8"); //Set response encoding format resp.setCharacterEncoding("utf-8"); resp.setContentType("text/html;charset=utf-8"); //Request data String uname = req.getParameter("uname"); String pwd = req.getParameter("pwd"); //Processing requests //Create business tier objects UserService userService = new UserServiceImpl(); //Calling business layer methods User user = userService.userLoginService(uname, pwd); //Response results //Get session object HttpSession session = req.getSession(); if(user!=null){ session.setAttribute("user",user); resp.sendRedirect(req.getContextPath()+"/main.jsp");//Login succeeded }else { session.setAttribute("flag","loginFail"); resp.sendRedirect(req.getContextPath()+"/login.jsp");//Login failed } } }
⑥ Create UserService business in web project and improve code processing login business
package com.bjsxt.service; import com.bjsxt.pojo.User; import java.io.IOException; public interface UserService { User userLoginService(String uname, String pwd) throws IOException; }
package com.bjsxt.service.impl; import com.bjsxt.mapper.UserMapper; import com.bjsxt.pojo.User; import com.bjsxt.service.UserService; 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 java.io.IOException; import java.io.InputStream; public class UserServiceImpl implements UserService { @Override public User userLoginService(String uname, String pwd) throws IOException { //Get sqlSession object InputStream is = Resources.getResourceAsStream("mybatis.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); SqlSession sqlSession = sqlSessionFactory.openSession(true); //Get mapper interface instantiation object UserMapper mapper = sqlSession.getMapper(UserMapper.class); //Complete database query User user = mapper.userLoginMapper(uname, pwd); //return return user; } }
⑦ Create UserMapper in the web project and improve the code to query user information according to user name and password
package com.bjsxt.mapper; import com.bjsxt.pojo.User; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; public interface UserMapper { //User login @Select("select * from t_user where uname=#{uname} and pwd=#{pwd}") User userLoginMapper(@Param("uname") String uname, @Param("pwd") String pwd); }
login.jsp
<% String path = request.getContextPath(); String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request .getServerPort() + path + "/"; %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>Title</title> <base href="<%=basePath%>"> </head> <body> <h3>Welcome to class 502</h3> <hr/> <c:if test="${sessionScope.flag=='loginFail'}"> <font size="20px" color="red">Wrong user name or password</font> </c:if> <c:remove var="flag" scope="session"/> <form action="userLogin" method="post"> user name:<input type="text" name="uname" value=""><br/> password:<input type="password" name="pwd" value=""><br/> <input type="submit" value="Sign in"> </form> </body> </html>
661 mybatis bottom layer analysis spring configuration data source bean
Question:
At present, in the process of developing functions, we will manually create SQLSession objects in the service layer and use SQLSession objects to obtain the instantiation objects of Mapper interface, but we really use the objects of Mapper interface. The current coding method greatly affects the development efficiency, and the coupling between mybatis layer and service layer is very high
solve:
Use Spring IOC technology to decouple the service layer and mybatis layer: in other words, let the Spring container help us obtain the instantiated object of Mapper layer interface, and we can directly obtain it from the Spring container for use
realization:
① Import the jar package of spring IOC
② Create and configure the Spring configuration file under src
mybatis.xml file content – io stream – > becomes a Configuration object - > Configuration has two stores 1 Database data 2 Mapper package scan path
DefaultSqlSessionFactory gets sqlSession from Configuration object!!!
Configure the bean of the DataSource data source
<!--To create a data source bean--> <!-- spring Rewritten dataSource because dataSource It's an interface--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/502?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true"></property> <property name="username" value="root"></property> <property name="password" value="123456"></property> </bean>
662 applicationcontext configuration file configuration factory bean configuration mapper scan bean
Guide package mybatis-spring-2.0.2 The SQLSessionFactory jar is not mybatis, but a bridge between mybatis and spring
Configure the factory bean of SQLSessionFactory (the bean of datasource)
<!--establish SqlSessionFactory of bean--> <bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> </bean>
Configure mapper to scan bean object (SQLSessionFactory object, scan path)
③ Create a Spring container object and obtain the instantiated object of Mapper interface to complete the database operation
<!-- to configure mapper scanning bean--> <bean id="mapper" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.bjsxt.mapper"></property> <property name="sqlSessionFactory" ref="factory"></property> </bean>
package com.bjsxt.test; import javafx.application.Application; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; //After the spring container object completes the creation of mybatis related objects, it will automatically call its //After completing the mapper layer scanning, the scanning results will be displayed //That is, the instantiated object of the interface is stored in spring again //Resource key name in container object: the first letter of the default mapper class is lowercase!!! public class TestSpring { public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext( "applicationcontext.xml"); //Returns the names of all key s in the spring container String[] names = ac.getBeanDefinitionNames(); for(String name:names){ System.out.println(name); } } } dataSource factory mapper userMapper org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory Process finished with exit code 0
663 servlet and decoupling implementation
The Controller layer uses Spring to decouple the service layer
Question:
It is implemented after the business layer uses the Spring container object to obtain the Mapper interface instantiation object
The service layer and mybatis layer are decoupled, but in the controller layer, we are still in the Servlet
Creating Service objects directly in is too coupling
solve:
Configure the service object as a bean object, and extract it from the Spring container in the Servlet
Get the Service object and complete the function development
realization:
① In ApplicationContext Configure the bean of the service in the XML file
<bean id="us" class="com.bjsxt.service.impl.UserServiceImpl" ></bean>
② Create a Spring container object in the service method in the servlet
③ Get the service object from the Spring container in the service method in the servlet
④ Use the service object to complete function processing
ApplicationContext ac = new ClassPathXmlApplicationContext( "applicationcontext.xml"); UserService userService = (UserService) ac.getBean("us"); //Calling business layer methods User user = userService.userLoginService(uname, pwd);
Analysis of resource proportion in 664 SM integration
Question:
In the current integration, after receiving the request, tomcat service will create a thread to process the request, and each thread runs independently of each other The process is as follows:
① The browser initiates a login request
② The tomcat server obtains the request and creates a new thread to process the request
③ Call the service method in the requested Servlet object
If 10 users initiate a login request, tomcat will create 10 threads to process the request Each thread needs to call the service method of UserServlet, and the method call depends on the instantiation object of UserServlet. Then each thread creates a UserServlet object, or is there only one UserServlet object, but it is shared and used by 10 threads?
If we operate in a single thread and call the service method of UserServlet object for 10 consecutive times, the code is as follows:
UserServlet us=new UserServlet()
us.service();
us.service();
us.service();
us.service();
...
In this code, we can declare 10 threads, and each thread runs us independently service(). It is concluded that when tomcat creates a thread to process a request, the Servlet object will only be created once, and the Servlet object is shared by multiple threads So when was the Servlet created?
By default, it is created at the first request and will not be re created in the future. If loadOnStartUp is configured, the initialization creation will be completed when the server starts
④ The service method in the Servlet is executed and the service method is put on the stack
Then create the spring container object, and a spring container object s1 will appear in the memory heap. When s1 is created, the spring configuration file will be loaded and the object (dataSource,factory,mapper,us) will be created according to the configuration file
⑤ Get the business layer object us in the Spring container
⑥ Calling the login business method of the us object
⑦ Logging in to the business method stack will create a new Spring container object s2,
When s2 is created, the Spring configuration file is loaded and parsed, and the bean objects of datasource, factory, US and mapper are created
⑧ Obtain the mapper object in the s2 container object in the business login method, complete the database operation, execute the business processing, log in the business method, complete the processing, return the result to the service method of the controller, and then the business method is out of the stack
⑨ After the service method of the servlet obtains the return value of the business layer, it continues to process, and then responds to the processing result to the browser. The service method ends, the service method comes out of the stack, the request is processed, and the thread is destroyed
Through the above process, it is found that in the current code structure, there will be 10 objects other than Servlet objects in a thread. Once highly concurrent access, it will cause a great waste of memory resources and cause the project to crash
665 SM optimization 1
The userMapper dependency of the mapper layer is injected into the UserServiceImpl class!
C in B - Dynamic factory mode
A - > b!!!
solve:
realization:
① Imported jar package:
② Create and configure ApplicationContext under src XML file
<!--Configure business layer bean--> <bean id="us" class="com.bjsxt.service.impl.UserServiceImpl" > <property name="userMapper" ref="userMapper"></property> </bean>
③ On the web The configuration file path to configure the Spring container object in the XML file
④ Load the initialization resources in the init method of the Servlet (get the business layer object from the Spring container object)
⑤ Declare the attributes of the mapper layer in the business layer and the corresponding get/set methods
⑥ Function development can be completed normally
UserServiceImpl
package com.bjsxt.service.impl; import com.bjsxt.mapper.UserMapper; import com.bjsxt.pojo.User; import com.bjsxt.service.UserService; 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 org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.io.IOException; import java.io.InputStream; public class UserServiceImpl implements UserService { //Declare mapper layer properties private UserMapper userMapper; public UserMapper getUserMapper() { return userMapper; } public void setUserMapper(UserMapper userMapper) { this.userMapper = userMapper; } //User login @Override public User userLoginService(String uname, String pwd) throws IOException { //Complete database query User user = userMapper.userLoginMapper(uname, pwd); //return return user; } }
666 SM optimization 2
④ Load the initialization resources in the init method of the Servlet (get the business layer object from the Spring container object)
Just get the required UserServiceImpl class object!
@WebServlet(value = "/userLogin",loadOnStartup = 1) public class UserServlet extends HttpServlet { //Declare variables to record business layer objects private UserService userService; //Initialization method @Override public void init() throws ServletException { ApplicationContext ac = new ClassPathXmlApplicationContext( "applicationcontext.xml"); userService = (UserService) ac.getBean("us"); } ... }
667 SM optimization 3
applicationcontext.xml is dead!!
Optimize the following code:
ApplicationContext ac = new ClassPathXmlApplicationContext( "applicationcontext.xml");
web.xml
<!--Configuring global parameters: logging spring Profile name--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationcontext.xml</param-value> </context-param> <!-- Configure listener--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
public class UserServlet extends HttpServlet { //Declare variables to record business layer objects private UserService userService; //Initialization method @Override public void init() throws ServletException { ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext()); userService = (UserService) ac.getBean("us"); }
Process summary 668
All jar packages
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.xsd"> <!--To create a data source bean--> <!-- spring Rewritten dataSource because dataSource It's an interface--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/502?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true"></property> <property name="username" value="root"></property> <property name="password" value="123456"></property> </bean> <!--establish SqlSessionFactory of bean--> <bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- to configure mapper scanning bean--> <bean id="mapper" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.bjsxt.mapper"></property> <property name="sqlSessionFactory" ref="factory"></property> </bean> <!--Configure business layer bean--> <bean id="us" class="com.bjsxt.service.impl.UserServiceImpl" > <property name="userMapper" ref="userMapper"></property> </bean> </beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <!--Configuring global parameters: logging spring Profile name--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationcontext.xml</param-value> </context-param> <!-- Configure listener--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
UserServlet
@Override public void init() throws ServletException { ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext()); userService = (UserService) ac.getBean("us"); }
669 process code implementation
1. Lead the package to build the package structure of src
2 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.xsd"> <!--Configure data sources bean--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/502?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true"></property> <property name="username" value="root"></property> <property name="password" value="123456"></property> </bean> <!-- Configuration factory bean--> <bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> </bean> <!-- to configure mapper scanning bean--> <bean id="mapper" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.bjsxt.mapper"></property> <property name="sqlSessionFactory" ref="factory"></property> </bean> <!-- Configure business layer bean--> </beans>
3 web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <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> </web-app>