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