6。4 案例
6。4。1 使用者登入
1。 需求
使用者在登入頁面輸入使用者名稱和密碼,提交請求給LoginServlet
在LoginServlet中接收請求和資料[使用者名稱和密碼]
在LoginServlt中透過Mybatis實現呼叫UserMapper來根據使用者名稱和密碼查詢資料庫表
將查詢的結果封裝到User物件中進行返回
在LoginServlet中判斷返回的User物件是否為null
如果為nul,說明根據使用者名稱和密碼沒有查詢到使用者,則登入失敗,返回“登入失敗”資料給前端
如果不為null,則說明使用者存在並且密碼正確,則登入成功,返回“登入成功”資料給前端
2。 環境準備
複製資料中的靜態頁面到專案的webapp目錄下
參考
資料\1。 登陸註冊案例\1。 靜態頁面
,複製完效果如下:
建立db1資料庫,建立tb_user表,建立User實體類
2。1 將
資料\1。 登陸註冊案例\2。 MyBatis環境\tb_user。sql
中的sql語句執行下:
2。2 將
資料\1。 登陸註冊案例\2。 MyBatis環境\User。java
複製到com。itheima。pojo
在專案的pom。xml匯入Mybatis和Mysql驅動座標
建立mybatis-config。xml核心配置檔案,UserMapper。xml對映檔案,UserMapper介面
4。1 將
資料\1。 登陸註冊案例\2。 MyBatis環境\mybatis-config。xml
複製到resources目錄下
<?xml version=“1。0” encoding=“UTF-8” ?> <!DOCTYPE configuration PUBLIC “-//mybatis。org//DTD Config 3。0//EN” “http://mybatis。org/dtd/mybatis-3-config。dtd”>
4。2 在com。itheima。mapper包下建立UserMapper介面
public interface UserMapper { }
4。3 將
資料\1。 登陸註冊案例\2。 MyBatis環境\UserMapper。xml
複製到resources目錄下
注意:在resources下建立UserMapper。xml的目錄時,要使用/分割
至此我們所需要的環境就都已經準備好了,具體該如何實現?
3。 程式碼實現
在UserMapper介面中提供一個根據使用者名稱和密碼查詢使用者物件的方法
/** * 根據使用者名稱和密碼查詢使用者物件 * @param username * @param password * @return */ @Select(“select * from tb_user where username = #{username} and password = #{password}”) User select(@Param(“username”) String username,@Param(“password”) String password);
說明
@Param註解的作用:用於傳遞引數,是方法的引數可以與SQL中的欄位名相對應。
修改loign。html
<!DOCTYPE html>
編寫LoginServlet
@WebServlet(“/loginServlet”) public class LoginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1。 接收使用者名稱和密碼 String username = request。getParameter(“username”); String password = request。getParameter(“password”); //2。 呼叫MyBatis完成查詢 //2。1 獲取SqlSessionFactory物件 String resource = “mybatis-config。xml”; InputStream inputStream = Resources。getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()。build(inputStream); //2。2 獲取SqlSession物件 SqlSession sqlSession = sqlSessionFactory。openSession(); //2。3 獲取Mapper UserMapper userMapper = sqlSession。getMapper(UserMapper。class); //2。4 呼叫方法 User user = userMapper。select(username, password); //2。5 釋放資源 sqlSession。close(); //獲取字元輸出流,並設定content type response。setContentType(“text/html;charset=utf-8”); PrintWriter writer = response。getWriter(); //3。 判斷user釋放為null if(user != null){ // 登陸成功 writer。write(“登陸成功”); }else { // 登陸失敗 writer。write(“登陸失敗”); } } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this。doGet(request, response); } }
啟動伺服器測試
4。1 如果使用者名稱和密碼輸入錯誤,則
4。2 如果使用者名稱和密碼輸入正確,則
至此使用者的登入功能就已經完成了~
6。4。2 使用者註冊
1。 需求分析
使用者在註冊頁面輸入使用者名稱和密碼,提交請求給RegisterServlet
在RegisterServlet中接收請求和資料[使用者名稱和密碼]
在RegisterServlet中透過Mybatis實現呼叫UserMapper來根據使用者名稱查詢資料庫表
將查詢的結果封裝到User物件中進行返回
在RegisterServlet中判斷返回的User物件是否為null
如果為nul,說明根據使用者名稱可用,則呼叫UserMapper來實現新增使用者
如果不為null,則說明使用者不可以,返回“使用者名稱已存在”資料給前端
2。 程式碼編寫
編寫UserMapper提供根據使用者名稱查詢使用者資料方法和新增使用者方法
/** * 根據使用者名稱查詢使用者物件 * @param username * @return */ @Select(“select * from tb_user where username = #{username}”) User selectByUsername(String username); /** * 新增使用者 * @param user */ @Insert(“insert into tb_user values(null,#{username},#{password})”) void add(User user);
修改register。html
<!DOCTYPE html>
建立RegisterServlet類
@WebServlet(“/registerServlet”) public class RegisterServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1。 接收使用者資料 String username = request。getParameter(“username”); String password = request。getParameter(“password”); //封裝使用者物件 User user = new User(); user。setUsername(username); user。setPassword(password); //2。 呼叫mapper 根據使用者名稱查詢使用者物件 //2。1 獲取SqlSessionFactory物件 String resource = “mybatis-config。xml”; InputStream inputStream = Resources。getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()。build(inputStream); //2。2 獲取SqlSession物件 SqlSession sqlSession = sqlSessionFactory。openSession(); //2。3 獲取Mapper UserMapper userMapper = sqlSession。getMapper(UserMapper。class); //2。4 呼叫方法 User u = userMapper。selectByUsername(username); //3。 判斷使用者物件釋放為null if( u == null){ // 使用者名稱不存在,新增使用者 userMapper。add(user); // 提交事務 sqlSession。commit(); // 釋放資源 sqlSession。close(); }else { // 使用者名稱存在,給出提示資訊 response。setContentType(“text/html;charset=utf-8”); response。getWriter()。write(“使用者名稱已存在”); } } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this。doGet(request, response); } }
啟動伺服器進行測試
4。1 如果測試成功,則在資料庫中就能檢視到新註冊的資料
4。2 如果使用者已經存在,則在頁面上展示
使用者名稱已存在
的提示資訊
6。4。3 SqlSessionFactory工具類抽取
上面兩個功能已經實現,但是在寫Servlet的時候,因為需要使用Mybatis來完成資料庫的操作,所以對於Mybatis的基礎操作就出現了些重複程式碼,如下
String resource = “mybatis-config。xml”; InputStream inputStream = Resources。getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()。build(inputStream);
有了這些重複程式碼就會造成一些問題:
重複程式碼不利於後期的維護
SqlSessionFactory工廠類進行重複建立
就相當於每次買手機都需要重新建立一個手機生產工廠來給你製造一個手機一樣,資源消耗非常大但效能卻非常低。所以這麼做是不允許的。
那如何來最佳化呢?
程式碼重複可以抽取工具類
對指定程式碼只需要執行一次可以使用靜態程式碼塊
有了這兩個方向後,程式碼具體該如何編寫?
public class SqlSessionFactoryUtils { private static SqlSessionFactory sqlSessionFactory; static { //靜態程式碼塊會隨著類的載入而自動執行,且只執行一次 try { String resource = “mybatis-config。xml”; InputStream inputStream = Resources。getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder()。build(inputStream); } catch (IOException e) { e。printStackTrace(); } } public static SqlSessionFactory getSqlSessionFactory(){ return sqlSessionFactory; } }
工具類抽取以後,以後在對Mybatis的SqlSession進行操作的時候,就可以直接使用
SqlSessionFactory sqlSessionFactory =SqlSessionFactoryUtils。getSqlSessionFactory();
這樣就可以很好的解決上面所說的程式碼重複和重複建立工廠導致效能低的問題了。