日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

MyBatis(3)

發布時間:2023/12/8 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MyBatis(3) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?我們在進行指定ID進行刪除的時候還可以加上一個屬性:表示要傳遞的參數的類型是啥

<delete id="Delete" parameterType="java.lang.Integer">delete from user where userID=#{userID}</delete>

我們現在先實現一個場景----我們來進行查詢一下UserID是7的學生信息(回顧)

注意:我們再進行查詢數據庫的操作的時候,進行寫方法的時候,不可以將返回值類型寫成int,既然是查詢,那么返回的一定是一條一條的紀錄

一:UserController里面的代碼:

package com.example.demo.Controller; import com.example.demo.Service.UserService; import com.example.demo.User; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import java.util.List; @Controller public class UserController {@AutowiredUserService userService;@RequestMapping("/SelectByID")@ResponseBodypublic User SelectByID(Integer userID){if(userID==null||userID.equals("")||userID<0){return null;}return userService.SelectByID(userID);} }

二:UserService里面的代碼:

package com.example.demo.Service; import com.example.demo.User; import com.example.demo.UserMapper.SpringBootMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class UserService {@Autowiredprivate SpringBootMapper mapper;public User SelectByID(Integer userID) {return mapper.SelectByID(userID);} }

XML文件里面的代碼:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD com.example.demo.Mapper1 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.demo.UserMapper.SpringBootMapper"><select id="SelectByID" resultType="com.example.demo.User">select * from user where userID="${userID}"</select> </mapper>

MyBatisMapper里面的代碼:

User SelectByID(Integer userID); 我們最終查詢的url是:http://127.0.0.1:8080/SelectByID?userID=11 #數據庫連接配置: spring.datasource.url=jdbc:mysql://127.0.0.1:3306/springboot?characterEncoding=utf-8&useSSL=false spring.datasource.username=root spring.datasource.password=12503487 spring.datasource.driver-class-name=com.mysql.jdbc.Driver mybatis.mapper-locations=classpath:mapper/**Mapper.xml #classpath表示項目的根路徑,這里面的mapper和resources下的mapper是對應的,況且這里面的mapper的名稱可以是任意的,我們想要在mapper目錄里面創建 #xml文件,后綴名就必須是Mapper.xml #開啟MyBatisSQL語句打印 mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

上面進行的查詢語句還可以寫成這種,那么使用#{}和使用${}他們之間有什么區別那?

? select * from user where userID=#{userID}

1)#是不會發生SQL注入的問題的,是當我們使用$時會發生SQL注入的問題,但是當我們使用order by進行查詢的時候,我們所傳遞的參數一定要是程序員自己進行傳入的,或者說當用戶進行傳入的時候我們直接調用replace方法直接把我們的單引號去掉,這樣就可以減少SQL注入的發生

2)下面是我們自己寫的一個登錄功能:

1)UserController里面的代碼:

package com.example.demo.Controller;import com.example.demo.Service.UserService; import com.example.demo.User; import netscape.security.UserTarget; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.util.HashMap; import java.util.List;@Controller public class UserController {@AutowiredUserService userService;@RequestMapping("/Login")@ResponseBodypublic HashMap<String, Object> login(String username, String password,HttpServletRequest req){HashMap<String,Object> map=new HashMap<>();String message="登陸成功";int state=1;if(username==null||password==null||username.equals("")||password.equals("")){String str="當前您傳遞的用戶名或者密碼不存在,說明您傳遞參數丟失";state=-1;}else {User user = userService.login(username,password);if (user == null || user.equals("") || user.getUserID() < 0) {message = "您當前登錄失敗,用戶名錯誤,在數據庫中無法查詢";state = -1;} else {message = "您當前登錄成功";HttpSession httpSession=req.getSession(true);httpSession.setAttribute("user",user);}}map.put("message",message);map.put("state",state);return map;} }

2)UserService里面的代碼:

package com.example.demo.Service; import com.example.demo.User; import com.example.demo.UserMapper.SpringBootMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class UserService {@Autowiredprivate SpringBootMapper mapper;public User login(String username,String password) {return mapper.login(username,password);} }

3)我們寫一下Mapper里面的代碼:

User login(String username,String password); xml文件里面的代碼: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD com.example.demo.Mapper1 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.demo.UserMapper.SpringBootMapper"><select id="login" resultType="com.example.demo.User">select * from user where username=#{username} and password=#{password}</select> </mapper>

但是當我們使用#的時候,查看程序是不會發生SQL注入的問題的:

?但是此時我們如果是把#改成$符,那么此時如果我們想輸入密碼還是' 1 or 1='1的時候,雖然不會登錄成功,但是會成功的查詢出所有的SQL語句:

http://127.0.0.1:8080/Login?username=李佳偉&passwor=’ or 1='1

select * from user where username="${username}" and password='${password}'

所以我們一定要對前端用戶輸入的值進行過濾

User user = userService.login(username,password.replace("'",""));

1)#{}是預編譯處理,是占位符,${}是字符串替換,是拼接符

2)Mybatis在處理#{}的時候會將sql中的#{}替換成?號,調用PreparedStatement來賦值

3)使用#{}是可以進行有效防止SQL注入的問題的

4)我們來假設一個場景:他可以適用于SQL關鍵字的替換,我們需要在瀏覽器上面輸入一個指令,來返回MYSQL進行查詢的結果,根據querystring中的字段order返回結果,它只能有兩個值,一個是asc一個是desc,我們可以根據userID來進行升序查詢也可以進行降序查詢-----下面我們來進行寫一段代碼進行演示:

輸入:127.0.0.1:8080/Java100?order=desc

一:我們在UserController里面的代碼:

package com.example.demo.Controller; import com.example.demo.Service.UserService; import com.example.demo.User; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import java.util.List; @Controller public class UserController {@AutowiredUserService userService;@RequestMapping("/GetAll")@ResponseBodypublic List<User> GetAll(String order){//我們首先要在Controller層進行參數校驗if(order==null||order.equals("")){return null;}return userService.GetAll(order);} }

二:我們在UserService里面的代碼:

package com.example.demo.Service; import com.example.demo.User; import com.example.demo.UserMapper.SpringBootMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class UserService {@Autowiredprivate SpringBootMapper mapper;public List<User> GetAll(String order) {return mapper.GetAll(order);} }

三:我們在接口里面和XML文件里面的代碼:

List<User> GetAll(String order); <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD com.example.demo.Mapper1 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.demo.UserMapper.SpringBootMapper"><select id="GetAll" resultType="com.example.demo.User">select * from user order by userID ${order}</select> </mapper>

我們如果在這里面直接使用的是#{變量名}的方式,程序就會發生報錯,這個時候的查詢語句就變成:

select * from user order by userID?' 'desc' '

?但是這種情況是不會發生SQL注入的,是由程序員是進行這個操作的(不是由用戶操作的),直接把單引號過濾掉,運用replace方法,里面加入要替換的字符串,過濾用戶前臺的輸入詞

小技巧:我們在application.properties里面寫上一句:就可以看到執行的SQL

mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

SQL注入:'+空格+or+空格+or+1=’1;(and優先級最高)+后面還可以加上delete語句,把數據庫搞沒了

總結:

1)#是進行預處理,而$是直接進行替換

2)#適用于所有的參數類型匹配,但是$只能適用于數值類型匹配

2.1)也就是說#和$再進行數值替換的時候沒有任何區別,得到的SQL語句都是相同的,對應的查詢SQL語句都是正確的,現在從瀏覽器上面輸入:127.0.0.1:8080/Java100?userID=1;

#:select * from user where userID=1,同時$也是一樣的(當我們進行數值匹配的時候,用#和$的效果是一樣的,但是當我們進行傳遞的參數都是字符串類型的時候,就會出現問題了

2.2)127.0.0.1:8080/Java100?username=A&password=123456

但是針對于前端輸入的字符串,#會自動將字符串加上雙引號,但是$不會自動加上雙引號

#:select * from user where username="A"&password="123456"

$:select * from user where username=A&password=123456,除非你給$加上

select * from user where username="${username}" and password="${password}"

因為如果說傳遞的參數是字符類型的,在SQL語法當中,如果是是字符類型,那么需要給值添加雙引號,而$是自動進行替換,不會添加單雙引號,所以程序就會直接報錯了,但是#是使用占位符的方式直接進行使用的,所以不會存在任何問題

3)使用#不會發生SQL注入,使用$是會發生SQL注入問題的:

3.1)User user= userMapper.SelectUser("A","' or 1='1");或者在瀏覽器上面輸入

127.0.0.1:8080/Java100?username=A&password=' or 1=1'

使用$select * from user where username='${username}' and password='${password}'

會發生SQL注入:?select * from user where username='A' and password='' or 1='1',但是此時使用#不會發生SQL注入問題

4)但是當我們進行傳遞的參數是一個查詢關鍵字的時候,我們就要使用$的方式,例如進行SQL排序:127.0.0.1:8080/Java100?order=desc(使用SQL命令或者是SQL關鍵字)

4.1)使用#:select * from user order by time #{order}

會被自動替換成:select * from user order by time "desc"

4.2)但是現在使用$符的方式:select * from user order by time ${order}

會被自動替換成:select * from user order by time desc;

5)當我們進行like模糊匹配的時候,我們優先使用$,但會發生SQL注入的問題,所以我們需要使用#的形式,還需要進行搭配MYSQL提供的內置函數

select * from user where username like "%#{username}"使用這種格式是錯誤的,當我們輸入:127.0.0.1:8080/Java100?username=a,最終就會變成"%"a"%"

下面我們來演示一下like查詢----根據用戶在瀏覽器上面的輸入不同的like的值來進行模糊匹配

我們可以寫一段代碼:

這是UserController里面的代碼:

package com.example.demo.Controller; import com.example.demo.Service.UserService; import com.example.demo.User; import netscape.security.UserTarget; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.util.HashMap; import java.util.List; @Controller public class UserController {@AutowiredUserService userService;@RequestMapping("/SelectAll")@ResponseBodypublic List<User> start(String name){//我們還是需要在Controller層進行參數校驗if(name==null||name.equals("")){return null;}return userService.start(name);} }

二:我們使用的UserService層的代碼和接口層的代碼:

package com.example.demo.Service; import com.example.demo.User; import com.example.demo.UserMapper.SpringBootMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class UserService {@Autowiredprivate SpringBootMapper mapper;public List<User> start(String name) {return mapper.start(name);} } 接口層的代碼:List<User> start(String name);

三:我們寫的XML文件里面的代碼:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD com.example.demo.Mapper1 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.demo.UserMapper.SpringBootMapper"><select id="start" resultType="com.example.demo.User">select * from user where username like '%${name}%'</select> </mapper>

1)我們如果使用$是可以的,但是很有可能會出現安全問題,可以直接過濾,但是如果name有可能是中文名,也有可能是英文名時可能會出現’字符的,所以我們不建議使用這種方法

2)但是我們不可以直接使用#的方式來進行模糊匹配,但是可以使用所以我們可以進行使用MYSQL提供的內置函數,這樣做既可以保證了安全,還可以使用#的方式

select * from user where username like concat('%',#{name},'%')

總結

以上是生活随笔為你收集整理的MyBatis(3)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。