亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術(shù)文章
文章詳情頁

MyBatis中#{}占位符與${}拼接符的用法說明

瀏覽:3日期:2023-10-19 17:58:00
1、關(guān)于#{}占位符

先來看以下的示例,該示例是MyBatis中的SQL映射配置文件(Mapper配置文件),在該配置中使用了#{}占位符。

<?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='test'> <!-- 根據(jù)用戶編號,查詢單個(gè)用戶實(shí)體 --> <select parameterType='int' resultType='com.pjb.mybatis.po.User'> SELECT * FROM tb_user WHERE id = #{id} </select> <!-- 新增用戶 --> <insert parameterType='com.pjb.mybatis.po.User'> INSERT INTO tb_user(user_name,blog_url,remark) VALUES(#{userName},#{blogUrl},#{remark}); </insert></mapper>

在SQL映射配置文章中,輸入?yún)?shù)需要用占位符來標(biāo)識對應(yīng)的位置。

在傳統(tǒng)的JDBC編程中,占位符用“?”來標(biāo)識,然后在加載SQL之前按照“?”的位置設(shè)置參數(shù)。

而“#{}”在MyBatis中也代表一種占位符,該符號接受輸入?yún)?shù),在大括號中編寫參數(shù)名稱來接受對應(yīng)參數(shù)。

“#{}”接受的輸入?yún)?shù)的類型可以是簡單類型、普通JavaBean或者HashMap。

當(dāng)接受簡單類型時(shí),“#{}”中可以寫“value”或者其他任意名稱。

如果接受的是JavaBean,它會(huì)通過OGNL讀取對象中的屬性值。

2、關(guān)于${}拼接符

再來看以下的示例,該示例是MyBatis中的SQL映射配置文件(Mapper配置文件),在該配置中使用了${}拼接符。

<?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='test'> <!-- 根據(jù)用戶名稱,模糊查詢用戶列表 --> <select parameterType='java.lang.String' resultType='com.pjb.mybatis.po.User'> SELECT * FROM tb_user WHERE user_name LIKE ’%${value}%’ </select></mapper>

在SQL映射配置文件中,有時(shí)候需要拼接SQL語句。例如在模糊查詢的時(shí)候,就需要在查詢條件的兩側(cè)拼接兩個(gè)“%”字符串,這個(gè)時(shí)候如果使用“#{}”占位符是不行的。在MyBatis中,“${}”在SQL配置文件中代表一個(gè)“拼接符號”,可以在原有SQL語句上拼接新的符合SQL語法的語句。

但是要注意的是,使用“${}”拼接的SQL語句,會(huì)引起SQL注入,所以一般不建議使用“${}”。

“${}”接受輸入?yún)?shù)的類型可以是簡單類型、普通JavaBean或者HashMap。

當(dāng)接受簡單類型時(shí),“${}”中只能寫“value”,而不能寫其他任意名稱。

如果接受的是JavaBean,它會(huì)通過OGNL讀取對象中的屬性值。

另外,在MyBatis 3.4.2之后,還可以在“${}”拼接符中設(shè)置一個(gè)默認(rèn)值,格式如下:

${屬性:默認(rèn)值}

即在所需引入的屬性名的后面添加“:”引號,然后緊跟著填寫屬性不存在或?yàn)榭諘r(shí)的默認(rèn)值。

【示例】設(shè)置“${}”拼接符的默認(rèn)值。

(1)創(chuàng)建數(shù)據(jù)庫連接的屬性文件(db.properties)

在src目錄下創(chuàng)建db.propertie屬性文件,并使用“#”符號將屬性項(xiàng)jdbc.username和jdbc.password注釋掉,表示這兩個(gè)屬性項(xiàng)未進(jìn)行配置。

jdbc.driver=com.mysql.cj.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/db_admin?useSSL=false&amp#jdbc.username=root#jdbc.password=123456(2)啟用拼接符默認(rèn)值的配置

要使用“${}”拼接符中設(shè)置一個(gè)默認(rèn)值,需要在properties標(biāo)簽中設(shè)置啟用拼接符默認(rèn)值的配置項(xiàng)。

在MyBatis配置文件(mybatis-config.xml)中,使用<properties>標(biāo)簽加載數(shù)據(jù)庫連接屬性文件(db.properties),并在該標(biāo)簽中設(shè)置啟用拼接符默認(rèn)值的配置項(xiàng),該配置如下:

<!-- 加載用于數(shù)據(jù)庫配置的屬性文件 --><properties resource='db.properties'> <!-- 啟用默認(rèn)值特性,這樣${}拼接符才可以設(shè)置默認(rèn)值 --> <property name='org.apache.ibatis.parsing.PropertyParser.enable-default-value' value='true'/></properties>

注意:在MyBatis配置文件(mybatis-config.xml)中,<properties>標(biāo)簽的配置必須寫在<settings>標(biāo)簽的上面,因?yàn)镸yBatis中的配置,不但有類型限制,還有順序限制。

必須按照:<properties>、<settings>、<typeAliases>、<typeHandlers>、…順序排放。

(3)編寫數(shù)據(jù)庫配置信息,并使用“${}”拼接符的默認(rèn)值。

MyBatis中#{}占位符與${}拼接符的用法說明

說明:

由于在db.propertie屬性文件中,已經(jīng)將jdbc.username和jdbc.password屬性項(xiàng)注釋掉了,然后在上面的配置信息中,給username和password配置項(xiàng)中的“${}”拼接符中設(shè)置默認(rèn)值,這樣程序在啟動(dòng)時(shí),就會(huì)讀取默認(rèn)值。

補(bǔ)充:MyBatis映射——SQL占位符及傳參

簡介

本篇主要講述Mybatis映射SQL通過#{}獲取引入類型參數(shù)的屬性值及通過@Param注解指定名稱傳參。

關(guān)于占位符與字符拼接:

占位符:占位符就是在某個(gè)地方占領(lǐng)一個(gè)位置,把它單獨(dú)作為某個(gè)東西,比如這里就是把它作為 值。

#{}表示一個(gè)占位符號,通過#{}可以實(shí)現(xiàn) preparedStatement 向占 位符中設(shè)置值, 自動(dòng)進(jìn)行 java

類型和 jdbc 類型轉(zhuǎn)換。#{}可以有效防止 sql 注入。 #{}可以接 收簡單類型值或 pojo 屬性值。 如果 parameterType 傳輸單個(gè)簡單類型值,#{} 括號中可以是 value 或其它名稱。

字符拼接:字符拼接就是簡單的對字符串拼接。沒有特殊的其它含義。

表 示 拼 接 s q l 串 , 通 過 可 以 將 p a r a m e t e r T y p e 傳 入 的 內(nèi) 容 拼 接 在 s q l 中 且 不 進(jìn) 行 j d b c 類 型 轉(zhuǎn) 換 , 可 以 將 p a r a m e t e r T y p e 傳 入 的 內(nèi) 容 拼 接 在 s q l 中 且 不 進(jìn) 行 j d b c 類 型 轉(zhuǎn) 換 , 可 以 接 收 簡 單 類 型 值 或 p o j o 屬 性 值 , 如 果 p a r a m e t e r T y p e 傳 輸 單 個(gè) 簡 單 類 型 值 , {}表示拼接 sql 串,通過可以將parameterType傳入的內(nèi)容拼接在sql中且不進(jìn)行jdbc類型轉(zhuǎn)換,可以將parameterType傳入的內(nèi)容拼接在sql中且不進(jìn)行jdbc類型轉(zhuǎn)換,{}可以接收簡單類型值或 pojo 屬性值,如果 parameterType 傳輸單個(gè)簡單類型值,表示拼接sql串,通過可以將parameterType傳入的內(nèi)容拼接在sql中且不進(jìn)行jdbc類型轉(zhuǎn)換,可以將parameterType傳入的內(nèi)容拼接在sql中且不進(jìn)行jdbc類型轉(zhuǎn)換,可以接收簡單類型值或pojo屬性值,如果parameterType傳輸單個(gè)簡單類型值,{}括號中只能是 value。

關(guān)于@Param:

在用注解來簡化xml配置的時(shí)候(比如Mybatis的Mapper.xml映射文件中的sql參數(shù)引入);

@Param注解的作用是給參數(shù)命名,參數(shù)命名后就能根據(jù)名字得到參數(shù)值,正確的將參數(shù)傳入sql語句中(一般通過#{}的方式,${}會(huì)有sql注入的問題)。

#{}: 解析為一個(gè) JDBC 預(yù)編譯語句(prepared statement)的參數(shù)標(biāo)記符,一個(gè) #{ } 被解析為一個(gè)參數(shù)占位符 。 ${}: 僅僅為一個(gè)純碎的 string 替換,在動(dòng)態(tài) SQL 解析階段將會(huì)進(jìn)行變量替換。

MyBatis 的真正強(qiáng)大在于它的映射語句

Mapper.xml映射文件中定義了操作數(shù)據(jù)庫的sql,每個(gè)sql是一個(gè)statement,映射文件是mybatis的核心。

映射文件中有很多屬性,常用的就是parameterType(輸入類型)、resultType(輸出類型)、resultMap()、rparameterMap()。

實(shí)例步驟

先建好實(shí)體類Teacher和接口類

Teacher類

package com.lanou3g.mybaties.bean;import lombok.Getter;import lombok.Setter;@Getter@Setterpublic class Teacher { private Integer id; private String tname; private Integer age; private Integer salary;public Teacher(){} @Override public String toString() { return 'Teacher{' +'id=' + id +', tname=’' + tname + ’’’ +', salary=' + salary +', remark=’' + remark + ’’’ +', age=' + age +’}’; } private String remark; public Teacher(Integer id, String tname, Integer age, Integer salary, String remark) { this.id = id; this.tname = tname; this.age = age; this.salary = salary; this.remark = remark; } public Teacher(Integer id) { this.id = id; } }

接口類

package com.lanou3g.mybaties.dao;import com.lanou3g.mybaties.bean.Teacher;import org.apache.ibatis.annotations.Param;import java.util.List;public interface TeacherDao { List<Teacher> queryAll(); Teacher queryById(int id); Teacher queryByIdAndAge(@Param('id') int id, @Param('age') int age); int insertTeacher(Teacher teacher); int insertTeacherByParam(@Param('tname') String tname, @Param('age') int age); int updateTeacherById(Teacher teacher); int deleteTeacherById(int id);}

主要還是xml配置文件的配置,下面是 mybatis_conf.xml文件,它主要引入外部的properties文件(用于配置數(shù)據(jù)源)、定義類型別名(全局)、配置多套環(huán)境的數(shù)據(jù)庫連接參數(shù)及引入哪些Mapper映射文件等

mybatis_conf.xml配置文件

<?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'><configuration> <properties resource='jdbc.properties' /> <settings> <setting name='mapUnderscoreToCamelCase' value='false'/> </settings> <typeAliases> <!--這樣我們就可以在mybatis的的上下文中使用Teacher來代替全路徑名了,減少配置的復(fù)雜度。 --> <typeAlias type='com.lanou3g.mybaties.bean.Teacher' alias='Teacher' /> <!--default屬性,這個(gè)屬性作用就是指定當(dāng)前情況下使用哪個(gè)數(shù)據(jù)庫配置, 也就是使用哪個(gè)<environment>節(jié)點(diǎn)的配置, default的值就是配置的<environment>標(biāo)簽元素的id值。--> <environments default='test'> <environment id='test'> <!-- 事務(wù)管理器: MANAGED: 這個(gè)配置就是告訴mybatis不要干預(yù)事務(wù),具體行為依賴于容器本身的事務(wù)處理邏輯。 JDBC: 這個(gè)配置就是直接使用了 JDBC 的提交和回滾設(shè)置,它依賴于從數(shù)據(jù)源得到的連接來管理事務(wù)作用域。 --> <!-- 使用jdbc事務(wù)管理 --> <transactionManager type='JDBC'/> <!-- 數(shù)據(jù)庫連接池 --> <dataSource type='POOLED'><property name='driver' value='${jdbc.driver}'/><property name='url' value='${jdbc.url}'/><property name='username' value='${jdbc.user}'/><property name='password' value='${jdbc.password}'/> </dataSource> </environment> </environments> <!--<mappers>用來在mybatis初始化的時(shí)候,告訴mybatis需要引入哪些Mapper映射文件。--> <mappers> <!--通過class屬性指定mapper接口名稱,此時(shí)對應(yīng)的映射文件必須與接口位于同一路徑下, 并且名稱相同--><!--通過resource屬性引入classpath路徑的相對資源--> <mapper resource='mapper/TeacherMapper.xml' /> </mappers></configuration>

TeacherMapper.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'><!-- namespace對應(yīng)空Dao接口的全名 --><!--namespace屬性在MyBatis中,Mapper中的namespace用于綁定Dao接口的,即面向接口編程。它的好處在于當(dāng)使用了namespace之后就可以不用寫接口實(shí)現(xiàn)類,業(yè)務(wù)邏輯會(huì)直接通過這個(gè)綁定尋找到相對應(yīng)的SQL語句進(jìn)行對應(yīng)的數(shù)據(jù)處理--><mapper namespace='com.lanou3g.mybaties.dao.TeacherDao'> <!-- 此處的id是查詢語句的名稱,對應(yīng)接口中的方法名 --> <!--指定 resultType 返回值類型時(shí) Teacher 類型的, Teacher 在這里是一個(gè)別名,代表的是 com.lanou3g.mybaties.bean.Teacher 對于引用數(shù)據(jù)類型,都是將大寫字母轉(zhuǎn)小寫,比如 HashMap 對應(yīng)的別名是 ’hashmap’ 基本數(shù)據(jù)類型考慮到重復(fù)的問題,會(huì)在其前面加上 ’_’,比如 byte 對應(yīng)的別名是 ’_byte’--> <select resultType='Teacher'> <!-- 通過 resultType 指定查詢的結(jié)果是 Teacher 類型的數(shù)據(jù) 只需要指定 resultType 的類型,MyBatis 會(huì)自動(dòng)將查詢的結(jié)果映射成 JavaBean 中的屬性 --> select * from teacher; </select> <!-- 帶一個(gè)簡單類型的參數(shù), 這種情況下parameterType屬性可以省略, mybatis可以自動(dòng)推斷出類型 --> <select resultType='Teacher'>select * from teacher where id = #{id}; </select> <!-- 帶兩個(gè)參數(shù),需要在接口中通過@Param注解指定名稱(因?yàn)榫幾g時(shí)參數(shù)名不會(huì)保留) --> <select resultType='Teacher'> select * from teacher where id = #{id} and age &lt;= #{age}; </select> <!-- insert、update、delete的返回值都是int(影響行數(shù)) --> <!-- 自定義類型參數(shù),通過#{屬性名}可以直接獲取引入類型參數(shù)的屬性值 --> <insert parameterType='Teacher'> insert into teacher(tname) values (#{tname}); </insert> <insert id='insertTeacherByParam'> insert into teacher(tname, age) values (#{tname}, #{age}); </insert> <update parameterType='Teacher'> update teacher set tname = #{tname}, age = #{age} where id = #{id} </update> <delete id='deleteTeacherById'> delete from teacher where id = #{id}; </delete></mapper>

前面完成后,就要測試了。不過在測試時(shí)需要實(shí)例化創(chuàng)建對象,因要實(shí)現(xiàn)多個(gè)方法,在這先建MyBatisTools.java工具類,其主要進(jìn)行封裝Mybatis初始化操作,要求支持創(chuàng)建多env sqlSessionFactory,整個(gè)應(yīng)用生命周期內(nèi)相同env的sqlSessionFactory對象只有一個(gè)(這個(gè)類不要過于探究,會(huì)用即可)。

MyBatisTools.java

package com.lanou3g.mybaties;import lombok.extern.slf4j.Slf4j;import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.ExecutorType;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import org.apache.ibatis.session.SqlSessionFactoryBuilder;import java.io.InputStream;import java.util.concurrent.ConcurrentHashMap;/** * 封裝Mybatis初始化操作 * 支持創(chuàng)建多env sqlSessionFactory * 整個(gè)應(yīng)用生命周期內(nèi)相同env的sqlSessionFactory對象只有一個(gè) */@Slf4jpublic class MyBatisTools { private static ConcurrentHashMap<String, SqlSessionFactory> factoryMap = new MyConcurrentHashMap(); private static MyBatisTools myBatisTools; private MyBatisTools() {} public static MyBatisTools getInstance() { if(myBatisTools == null) { synchronized (MyBatisTools.class) {if(myBatisTools == null) { myBatisTools = new MyBatisTools();} } } log.debug('當(dāng)前一共有: ' + factoryMap.size() +'個(gè)SqlSessionFactory實(shí)例'); log.debug('他們分別是: ' + factoryMap); return myBatisTools; } public SqlSessionFactory getSessionFactory(String env) { try { // 1. 讀入配置文件 InputStream in = Resources.getResourceAsStream('mybatis_conf.xml'); // 2. 構(gòu)建SqlSessionFactory(用于獲取sqlSession) SqlSessionFactory sessionFactory = null; synchronized (factoryMap) {if(factoryMap.containsKey(env)) { return factoryMap.get(env);} else { sessionFactory = new SqlSessionFactoryBuilder().build(in, env); factoryMap.put(env, sessionFactory);} } return sessionFactory; } catch (Exception e) { log.error('初始化SqlSessionFactory失敗', e); return null; } } public SqlSession openSession() { return getSessionFactory(null).openSession(); } public SqlSession openSession(boolean autoCommit) { return getSessionFactory(null).openSession(autoCommit); } public SqlSession openSession(ExecutorType executorType, boolean autoCommit) { return getSessionFactory(null).openSession(executorType, autoCommit); }}/** * 繼承原生ConcurrentHashMap,處理null key問題 */class MyConcurrentHashMap extends ConcurrentHashMap { @Override public Object put(Object key, Object value) { if(key == null) { key = 'null'; } return super.put(key, value); } @Override public boolean containsKey(Object key) { if(key == null) { key = 'null'; } return super.containsKey(key); } @Override public Object get(Object key) { if(key == null) { key = 'null'; } return super.get(key); }}

最后就是測試,在AppTest類測試

AppTest

@Slf4jpublic class AppTest { /** * Rigorous Test :-) */ TeacherDao teacherDao = null; @Before public void setUp() { teacherDao = MyBatisTools.getInstance().openSession(true).getMapper(TeacherDao.class); } /** * 練習(xí)查詢多個(gè)庫(用到了多環(huán)境配置) */ @Test public void textqueryById(){ Teacher teacher=teacherDao.queryById(1); System.out.println(teacher); } @Test public void text(){ List<Teacher> teachers=teacherDao.queryAll(); System.out.println(teachers); } /** * 多個(gè)參數(shù)查詢語句 */ @Test public void testQueryByIdAndAge() { Teacher teacherList = teacherDao.queryByIdAndAge(1, 65); log.info('查詢結(jié)果:' + teacherList); } @Test public void testInsert() { // 新增Teacher表 System.out.println('--------------插入前:'); List<Teacher> teacherList = teacherDao.queryAll(); System.out.println(teacherList); int ret = teacherDao.insertTeacher(new Teacher('好人')); log.info('影響的行數(shù): ' + ret); // 比較low的寫法(不推薦) //int ret = teacherDao.insertTeacherByParam('哈哈哥', 99); //log.info('影響的行數(shù): ' + ret); System.out.println('--------------插入后:'); teacherList = teacherDao.queryAll(); System.out.println(teacherList); } @Test public void testUpdate() { Teacher teacher = new Teacher(); teacher.setId(6); teacher.setAge(99); teacher.setTname('喬巴老師'); int rows = teacherDao.updateTeacherById(teacher); log.info('更新行數(shù):' + rows); } @Test public void testDelete() { int rows = teacherDao.deleteTeacherById(13); log.info('刪除行數(shù):' + rows); } @Test public void testinsertTeacherByParam(){int row=teacherDao.insertTeacherByParam('hh',22); System.out.println(row); }}

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持好吧啦網(wǎng)。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。

標(biāo)簽: Mybatis 數(shù)據(jù)庫
相關(guān)文章:
主站蜘蛛池模板: www一级毛片 | 亚洲无圣光一区二区 | 青青热久免费精品视频在线观看 | 日本一级特黄特色大片免费视频 | 日韩欧美一区二区三区中文精品 | 成人在线观看国产 | 国产香港特级一级毛片 | 青草香蕉精品视频在线观看 | 免费看国产做爰大片 | 一级全黄男女免费大片 | 在线免费观看视频黄 | 成人一a毛片免费视频 | 成人国产午夜在线视频 | 国产人成午夜免费噼啪视频 | 国产精品亚洲精品日韩己满十八小 | 九九亚洲精品 | 亚洲欧美日本国产 | 全免费午夜真人毛片视频 | 日本高清天码一区在线播放 | 国产成人久久精品 | 国产酒店视频 | 在线观看国产免费高清不卡 | 色综合图片 | 国产 日韩 欧美视频二区 | 国产精品不卡无毒在线观看 | 日本精品中文字幕有码 | 观看麻豆影视文化有限公司 | 亚洲欧美日韩不卡一区二区三区 | 亚洲精品国产精品乱码视色 | 一级国产视频 | 欧美性三三影院 | 欧美二级在线观看免费 | 香蕉视频在线观看国产 | 日本黄色片在线 | 亚洲综合亚洲综合网成人 | 国产一级视频久久 | 黄视频免费观看 | 亚洲综合欧美在线 | 日韩激情淫片免费看 | 亚洲精品tv久久久久久久久 | pans国产大尺度私密拍摄视频 |