【Mybatis 之应用篇】2_配置解析、属性名问题、日志、分页和注解开发
文章目錄
- Mabatis
- 四、配置解析
- 1.核心配置文件
- 2.environments(環(huán)境配置)☆
- 3.properties(屬性)☆
- 4.typeAliases(類型別名)☆
- 5.settings(設(shè)置)
- 6.其他配置
- 7.mappers(映射器)
- 8.生命周期和作用域
- 五、解決屬性名和字段名不一致的問題
- 1.問題
- 2.resultMap☆
- 六、日志
- 1.日志工廠
- 2.Log4j
- 七、分頁(yè)
- 1.為什么要分頁(yè)?
- 2.使用Limit分頁(yè)
- 3.練習(xí)
- 八、使用注解開發(fā)
- 1.面向接口編程
- 2.使用注解開發(fā)
Mabatis
四、配置解析
1.核心配置文件
mybatis-config.xml
MyBatis 的配置文件包含了會(huì)深深影響 MyBatis 行為的設(shè)置和屬性信息。 配置文檔的頂層結(jié)構(gòu)如下:
configuration(配置) properties(屬性) settings(設(shè)置) typeAliases(類型別名) typeHandlers(類型處理器) objectFactory(對(duì)象工廠) plugins(插件) environments(環(huán)境配置) environment(環(huán)境變量) transactionManager(事務(wù)管理器) dataSource(數(shù)據(jù)源) databaseIdProvider(數(shù)據(jù)庫(kù)廠商標(biāo)識(shí)) mappers(映射器)2.environments(環(huán)境配置)☆
切換默認(rèn)環(huán)境:只需要修改default中的字段即可
<!--這是數(shù)據(jù)庫(kù)驅(qū)動(dòng)配置--><environments default="development"> <!--只需要修改default中的字段即可--><environment id="development"><transactionManager type="JDBC"/> <!--事務(wù)管理器:JDBC(默認(rèn)),MANAGED--><dataSource type="POOLED"> <!--數(shù)據(jù)源:POOLED(默認(rèn)),UNPOOLED連接數(shù)據(jù)庫(kù)--><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/><property name="username" value="root"/><property name="password" value="root"/></dataSource></environment><environment id="test"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/><property name="username" value="root"/><property name="password" value="root"/></dataSource></environment></environments>3.properties(屬性)☆
resources路徑下不用寫路徑
我們可以通過properties屬性來實(shí)現(xiàn)引用配置文件
這些屬性都是可外部配置且可動(dòng)態(tài)替換的,既可以在典型的 Java 屬性文件中配置,亦可通過 properties 元素的子元素來傳遞。【db.properties】
在mybatis-config.xml配置文件中,標(biāo)簽順序是非常嚴(yán)格的
編寫一個(gè)配置文件
db.properties
driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8 username=root password=root在核心配置文件中映入
<!--引入外部配置文件--><properties resource="db.properties"><property name="username" value="root"/><property name="pwd" value="11111"/></properties>- 可以直接引入外部文件
- 可以在其中增加一些屬性配置
- 如果兩個(gè)文件有同一個(gè)字段,優(yōu)先使用外部配置文件的!
4.typeAliases(類型別名)☆
- 類型別名是為 Java 類型設(shè)置一個(gè)短的名字。
- 存在的意義僅在于用來減少類完全限定名的冗余。
也可以指定一個(gè)包名,MyBatis 會(huì)在包名下面搜索需要的 Java Bean,比如:
掃描實(shí)體類的包,它的默認(rèn)別名就為這個(gè)類的 類名,首字母小寫!
<typeAliases><!--2.可以設(shè)置包名,此時(shí)引用的類名是類的小寫--><package name="entity"></package> </typeAliases>在實(shí)體類比較少的時(shí)候,使用第一種方式。
如果實(shí)體類十分多,建議使用第二種。
第一種可以DIY別名,第二種則不行,如果非要改,需要在實(shí)體上增加注解
@Alias("user")//@Alias("admin") public class User {}5.settings(設(shè)置)
6.其他配置
- typeHandlers(類型處理器)
- objectFactory(對(duì)象工廠)
- plugins插件
- mybatis-generator-core
- mybatis-plus
- 通用mapper
7.mappers(映射器)
MapperRegistry:注冊(cè)綁定我們的Mapper文件;
方式一: 【推薦使用】
<!--每一個(gè)Mapper.XML都需要在Mybatis核心配置文件中注冊(cè)!--> <mappers><mapper resource="com/kuang/dao/UserMapper.xml"/> </mappers>方式二:使用class文件綁定注冊(cè)
<!--每一個(gè)Mapper.XML都需要在Mybatis核心配置文件中注冊(cè)!--> <mappers><mapper class="com.kuang.dao.UserMapper"/> </mappers>使用class文件綁定注冊(cè)的注意點(diǎn):
- 接口和他的Mapper配置文件必須同名!
- 接口和他的Mapper配置文件必須在同一個(gè)包下!
方式三:使用掃描包進(jìn)行注入綁定
<!--每一個(gè)Mapper.XML都需要在Mybatis核心配置文件中注冊(cè)!--> <mappers><package name="com.kuang.dao"/> </mappers>注意點(diǎn):
- 接口和他的Mapper配置文件必須同名!
- 接口和他的Mapper配置文件必須在同一個(gè)包下!
8.生命周期和作用域
生命周期,和作用域,是至關(guān)重要的,因?yàn)殄e(cuò)誤的使用會(huì)導(dǎo)致非常嚴(yán)重的并發(fā)問題。
SqlSessionFactoryBuilder:
- 一旦創(chuàng)建了 SqlSessionFactory,就不再需要它了
- 局部變量
SqlSessionFactory:
- 說白了就是可以想象為 :數(shù)據(jù)庫(kù)連接池
- SqlSessionFactory 一旦被創(chuàng)建就應(yīng)該在應(yīng)用的運(yùn)行期間一直存在,沒有任何理由丟棄它或重新創(chuàng)建另一個(gè)實(shí)例。
- 因此 SqlSessionFactory 的最佳作用域是應(yīng)用作用域——即全局變量
- 最簡(jiǎn)單的就是使用單例模式或者靜態(tài)單例模式。
SqlSession
- 連接到連接池的一個(gè)請(qǐng)求!
- SqlSession 的實(shí)例不是線程安全的,因此是不能被共享的,所以它的最佳的作用域是請(qǐng)求或方法作用域。
- 用完之后需要趕緊關(guān)閉,否則資源被占用!
這里面的每一個(gè)Mapper,就代表一個(gè)具體的業(yè)務(wù)!
五、解決屬性名和字段名不一致的問題
1.問題
數(shù)據(jù)庫(kù)中的字段
新建一個(gè)項(xiàng)目,拷貝之前的,測(cè)試實(shí)體類字段不一致的情況
測(cè)試出現(xiàn)問題
出現(xiàn)null值
解決方法:
-
起別名
<select id="getUserById" resultType="com.kuang.pojo.User">select id,name,pwd as password from mybatis.user where id = #{id} </select>
2.resultMap☆
結(jié)果集映射
id name pwd id name password <!--要將map(注意:這里的id要與select中的resultType相同)映射為User類型--><resultMap id="map" type="user"><!--column數(shù)據(jù)庫(kù)中的字段,property實(shí)體類中的屬性,將一個(gè)字段映射成屬性--><result column="id" property="id"/><result column="name" property="name"/><result column="pwd" property="password"/></resultMap><!--根據(jù)id查詢用戶--><select id="getById" resultMap="map">select * from mybatis.user where id = #{id}</select>- resultMap 元素是 MyBatis 中最重要最強(qiáng)大的元素
- ResultMap 的設(shè)計(jì)思想是,對(duì)于簡(jiǎn)單的語句根本不需要配置顯式的結(jié)果映射,而對(duì)于復(fù)雜一點(diǎn)的語句只需要描述它們的關(guān)系就行了。
- ResultMap 最優(yōu)秀的地方在于,雖然你已經(jīng)對(duì)它相當(dāng)了解了,但是根本就不需要顯式地用到他們。只要映射不一樣的字段即可。
- 如果世界總是這么簡(jiǎn)單就好了。
六、日志
1.日志工廠
如果一個(gè)數(shù)據(jù)庫(kù)操作出現(xiàn)了異常,我們需要拍錯(cuò),那么日志將會(huì)很好的的助手
-
SLF4J
-
LOG4J 【掌握】
-
LOG4J2
-
JDK_LOGGING
-
COMMONS_LOGGING
-
STDOUT_LOGGING 【掌握】
-
NO_LOGGING
在Mybatis中具體使用那個(gè)一日志實(shí)現(xiàn),在設(shè)置中設(shè)定!
STDOUT_LOGGING標(biāo)準(zhǔn)日志輸出
在mybatis核心配置文件中,配置我們的日志!這里的字段要求十分嚴(yán)格
<!--不能出錯(cuò),寫死--> <settings><setting name="logImpl" value="STDOUT_LOGGING"/> </settings>在mybatis和新配置文件中(mybatis-config.xml)設(shè)置。
2.Log4j
什么是Log4j?
- Log4j是Apache的一個(gè)開源項(xiàng)目,通過使用Log4j,我們可以控制日志信息輸送的目的地是控制臺(tái)、文件、GUI組件
- 我們也可以控制每一條日志的輸出格式;
- 通過定義每一條日志信息的級(jí)別,我們能夠更加細(xì)致地控制日志的生成過程。
- 通過一個(gè)配置文件來靈活地進(jìn)行配置,而不需要修改應(yīng)用的代碼。
如何使用log4j
先導(dǎo)入log4j的包
<!-- https://mvnrepository.com/artifact/log4j/log4j --> <dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version> </dependency>log4j.properties
#將等級(jí)為DEBUG的日志信息輸出到console和file這兩個(gè)目的地,console和file的定義在下面的代碼 log4j.rootLogger=DEBUG,console,file#控制臺(tái)輸出的相關(guān)設(shè)置 log4j.appender.console = org.apache.log4j.ConsoleAppender log4j.appender.console.Target = System.out log4j.appender.console.Threshold=DEBUG log4j.appender.console.layout = org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern=[%c]-%m%n#文件輸出的相關(guān)設(shè)置 log4j.appender.file = org.apache.log4j.RollingFileAppender log4j.appender.file.File=./log/kuang.log log4j.appender.file.MaxFileSize=10mb log4j.appender.file.Threshold=DEBUG log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n#日志輸出級(jí)別 log4j.logger.org.mybatis=DEBUG log4j.logger.java.sql=DEBUG log4j.logger.java.sql.Statement=DEBUG log4j.logger.java.sql.ResultSet=DEBUG log4j.logger.java.sql.PreparedStatement=DEBUG配置log4j為日志的實(shí)現(xiàn)
<settings><setting name="logImpl" value=""/> </settings>Log4j的使用!,直接測(cè)試運(yùn)行剛才的查詢
簡(jiǎn)單使用
在要使用Log4j 的類中,導(dǎo)入包 import org.apache.log4j.Logger;
日志對(duì)象,參數(shù)為當(dāng)前類的class
static Logger logger = Logger.getLogger(UserDaoTest.class);日志級(jí)別
logger.info("info:進(jìn)入了testLog4j"); logger.debug("debug:進(jìn)入了testLog4j"); logger.error("error:進(jìn)入了testLog4j");七、分頁(yè)
1.為什么要分頁(yè)?
減少數(shù)據(jù)的處理量
2.使用Limit分頁(yè)
SELECT * from user limit startIndex,pageSize;SELECT * from user limit 3; #[0,n)3.練習(xí)
在接口UserMapper.java中寫出抽象方法
<!--使用map有很多好處--> List<User> getUserByLimit(Map<String,Integer> map);在綁定的UserMapper.xml配置文件中,寫出sql語句
<!--這里的user之所以是小寫因?yàn)橐呀?jīng)在別名中配置過了,在package下的類都小寫--> <select id="getUserByLimit" parameterType="map" resultType="user"> select * from mybatis.user limit #{startIndex},#{PageSize};</select>在測(cè)試類中寫出
@Testpublic void testGetUserByLimit(){SqlSession sqlSession = MybatisUtil.getSqlSession();UserMapper mapper = sqlSession.getMapper(UserMapper.class);Map<String,Integer> map = new HashMap<String,Integer>();map.put("startIndex",1);map.put("PageSize",2);List<User> list = mapper.getUserByLimit(map);for(User user:list){System.out.println(user);}sqlSession.close();}八、使用注解開發(fā)
只能使用簡(jiǎn)單的開發(fā),否則會(huì)出現(xiàn)力有不逮的問題
1.面向接口編程
- 大家之前都學(xué)過面向?qū)ο缶幊?#xff0c;也學(xué)習(xí)過接口,但在真正的開發(fā)中,很多時(shí)候我們會(huì)選擇面向接口編程
- 根本原因 : 解耦 , 可拓展 , 提高復(fù)用 , 分層開發(fā)中 , 上層不用管具體的實(shí)現(xiàn) , 大家都遵守共同的標(biāo)準(zhǔn) , 使得開發(fā)變得容易 , 規(guī)范性更好
- 在一個(gè)面向?qū)ο蟮南到y(tǒng)中,系統(tǒng)的各種功能是由許許多多的不同對(duì)象協(xié)作完成的。在這種情況下,各個(gè)對(duì)象內(nèi)部是如何實(shí)現(xiàn)自己的,對(duì)系統(tǒng)設(shè)計(jì)人員來講就不那么重要了;
- 而各個(gè)對(duì)象之間的協(xié)作關(guān)系則成為系統(tǒng)設(shè)計(jì)的關(guān)鍵。小到不同類之間的通信,大到各模塊之間的交互,在系統(tǒng)設(shè)計(jì)之初都是要著重考慮的,這也是系統(tǒng)設(shè)計(jì)的主要工作內(nèi)容。面向接口編程就是指按照這種思想來編程。
關(guān)于接口的理解
- 接口從更深層次的理解,應(yīng)是定義(規(guī)范,約束)與實(shí)現(xiàn)(名實(shí)分離的原則)的分離。
- 接口的本身反映了系統(tǒng)設(shè)計(jì)人員對(duì)系統(tǒng)的抽象理解。
- 接口應(yīng)有兩類:
- 第一類是對(duì)一個(gè)個(gè)體的抽象,它可對(duì)應(yīng)為一個(gè)抽象體(abstract class);
- 第二類是對(duì)一個(gè)個(gè)體某一方面的抽象,即形成一個(gè)抽象面(interface);
- 一個(gè)體有可能有多個(gè)抽象面。抽象體與抽象面是有區(qū)別的。
三個(gè)面向區(qū)別
- 面向?qū)ο笫侵?#xff0c;我們考慮問題時(shí),以對(duì)象為單位,考慮它的屬性及方法 .
- 面向過程是指,我們考慮問題時(shí),以一個(gè)具體的流程(事務(wù)過程)為單位,考慮它的實(shí)現(xiàn) .
- 接口設(shè)計(jì)與非接口設(shè)計(jì)是針對(duì)復(fù)用技術(shù)而言的,與面向?qū)ο?#xff08;過程)不是一個(gè)問題.更多的體現(xiàn)就是對(duì)系統(tǒng)整體的架構(gòu)
2.使用注解開發(fā)
注解在接口上實(shí)現(xiàn)
@Select("select * from user") List<User> getUsers();需要再核心配置文件中綁定接口!
<!--綁定接口--><mappers><mapper class="dao.UserMapper"/></mappers>測(cè)試
本質(zhì):反射機(jī)制實(shí)現(xiàn)
底層:動(dòng)態(tài)代理!
Mybatis詳細(xì)的執(zhí)行流程!
我們可以在工具類創(chuàng)建的時(shí)候?qū)崿F(xiàn)自動(dòng)提交事務(wù)!
public static SqlSession getSqlSession(){return sqlSessionFactory.openSession(true); }編寫接口,增加注解
public interface UserMapper {@Select("select * from user")List<User> getUsers();// 方法存在多個(gè)參數(shù),所有的參數(shù)前面必須加上 @Param("id")注解,獲取是必須用注解指定的那個(gè)字段去獲取參數(shù)@Select("select * from user where id = #{id}")User getUserByID(@Param("id") int id);@Insert("insert into user(id,name,pwd) values (#{id},#{name},#{password})")int addUser(User user);@Update("update user set name=#{name},pwd=#{password} where id = #{id}")int updateUser(User user);@Delete("delete from user where id = #{uid}")int deleteUser(@Param("uid") int id); }測(cè)試類
【注意:我們必須要講接口注冊(cè)綁定到我們的核心配置文件中!】
關(guān)于@Param() 注解
- 基本類型的參數(shù)或者String類型,需要加上
- 引用類型不需要加
- 如果只有一個(gè)基本類型的話,可以忽略,但是建議大家都加上!
- 我們?cè)赟QL中引用的就是我們這里的 @Param() 中設(shè)定的屬性名!
#{} ${} 區(qū)別
") int id);
@Insert("insert into user(id,name,pwd) values (#{id},#{name},#{password})") int addUser(User user);@Update("update user set name=#{name},pwd=#{password} where id = #{id}") int updateUser(User user);@Delete("delete from user where id = #{uid}") int deleteUser(@Param("uid") int id);}
測(cè)試類【注意:我們必須要講接口注冊(cè)綁定到我們的核心配置文件中!】**關(guān)于@Param() 注解**- 基本類型的參數(shù)或者String類型,需要加上 - 引用類型不需要加 - 如果只有一個(gè)基本類型的話,可以忽略,但是建議大家都加上! - 我們?cè)赟QL中引用的就是我們這里的 @Param() 中設(shè)定的屬性名!**#{} ${} 區(qū)別**#{}可以防止sql注入總結(jié)
以上是生活随笔為你收集整理的【Mybatis 之应用篇】2_配置解析、属性名问题、日志、分页和注解开发的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Mybatis 之应用篇】1_Myba
- 下一篇: 【Mybatis 之应用篇】 3_Lom