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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

SSM框架整合(参考尚硅谷视频和文档

發布時間:2023/12/31 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SSM框架整合(参考尚硅谷视频和文档 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、MyBatis


1MyBatis簡介


1.1MyBatis歷史?

MyBatis最初是Apache的一個開源項目iBatis, iBatis3.x正式更名為MyBatis。代碼于 2013年11月遷移到Github iBatis一詞來源于“internet”“abatis”的組合,是一個基于Java的持久層框架。 iBatis提供的持久層框架包括SQL MapsData Access ObjectsDAO)。

1.2MyBatis特性

1 MyBatis 是支持定制化 SQL、存儲過程以及高級映射的優秀的持久層框架 2 MyBatis 避免了幾乎所有的 JDBC 代碼和手動設置參數以及獲取結果集 3 MyBatis可以使用簡單的XML或注解用于配置和原始映射,將接口和JavaPOJOPlain Old Java Objects,普通的Java對象)映射成數據庫中的記錄 4 MyBatis 是一個 半自動的ORMObject Relation Mapping)框架 Object Relation Mapping 對象 關系數據庫 映射

1.3MyBatis下載

MyBatis下載地址:https://github.com/mybatis/mybatis-3

?

1.4、和其它持久化層技術對比

  • JDBC? ? ? ?
  • SQL 夾雜在Java代碼中耦合度高,導致硬編碼內傷
  • 維護不易且實際開發需求中 SQL 有變化,頻繁修改的情況多見
  • 代碼冗長,開發效率低
    • Hibernate JPA
  • 操作簡便,開發效率高
  • 程序中的長難復雜 SQL 需要繞過框架
  • 內部自動生產的 SQL,不容易做特殊優化
  • 基于全映射的全自動框架,大量字段的 POJO 進行部分映射時比較困難。
  • 反射操作太多,導致數據庫性能下降
    • MyBatis
  • 輕量級,性能出色
  • SQL Java 編碼分開,功能邊界清晰。Java代碼專注業務、SQL語句專注數據
  • 開發效率稍遜于HIbernate,但是完全能夠接受
  • 2、搭建MyBatis


    2.1、開發環境

    IDEidea 2021.1.3 構建工具:maven 3.5.4 MySQL版本:MySQL 8 MyBatis版本:MyBatis 3.5.7 MySQL不同版本的注意事項 1、驅動類driver-class-name MySQL 5版本使用jdbc5驅動,驅動類使用:com.mysql.jdbc.Driver MySQL 8版本使用jdbc8驅動,驅動類使用:com.mysql.cj.jdbc.Driver 2、連接地址url MySQL 5版本的url jdbc:mysql://localhost:3306/ssm MySQL 8版本的url jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC 否則運行測試用例報告如下錯誤: java.sql.SQLException: The server time zone value '?D1ú±ê×?ê±??' is unrecognized or represents more

    2.2、創建maven工程

    ①打包方式:jar ②引入依賴 <dependencies><!-- Mybatis核心 --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.7</version></dependency><!-- junit測試 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><!-- MySQL驅動 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.16</version></dependency> </dependencies>

    2.3、創建MyBatis的核心配置文件

    習慣上命名為mybatis-config.xml,這個文件名僅僅只是建議,并非強制要求。將來整合Spring 之后,這個配置文件可以省略,所以大家操作時可以直接復制、粘貼。 核心配置文件主要用于配置連接數據庫的環境以及MyBatis的全局配置信息 核心配置文件存放的位置是src/main/resources目錄下 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration><!--配置連接數據庫的環境--><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC"/><property name="username" value="root"/><property name="password" value="XXXX"/></dataSource></environment></environments><!--引入mybatis的映射文件--><mappers><package name=""/></mappers> </configuration>

    2.4、創建mapper接口 ?

    MyBatis中的mapper接口相當于以前的dao。但是區別在于,mapper僅僅是接口,我們不需要提供實現類。 public interface UserMapper {int insertUser();}

    2.5、創建MyBatis的映射文件

    相關概念:ORMObject Relationship Mapping)對象關系映射。
    • 對象:Java的實體類對象
    • 關系:關系型數據庫
    • 映射:二者之間的對應關系

    ?

    ?1、映射文件的命名規則:

    表所對應的實體類的類名+Mapper.xml 例如:表t_user,映射的實體類為User,所對應的映射文件為UserMapper.xml 因此一個映射文件對應一個實體類,對應一張表的操作 MyBatis映射文件用于編寫SQL,訪問以及操作表中的數據 MyBatis映射文件存放的位置是src/main/resources/mappers目錄下 2 MyBatis中可以面向接口操作數據,要保證兩個一致: a>mapper接口的全類名和映射文件的命名空間(namespace)保持一致 b>mapper接口中方法的方法名和映射文件中編寫SQL的標簽的id屬性保持一致 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.atguigu.mybatis.mapper.UserMapper"><!--mapper接口和映射文件要保證兩個一致:1、mapper接口的全類名和映射文件的namespace一致2、mapper接口中的方法的方法名要和映射文件中的sql的id保持一致--><!-- int insertUser();--><insert id="insertUser">insert into t_user values (null,'admin','123456',23,'男','12345@qq.com');</insert></mapper>

    ?2.6、通過junit測試功能

    @Testpublic void testInsert() throws IOException {//獲取核心配置文件的輸入流(讀的功能/輸出流(寫的功能))InputStream is = Resources.getResourceAsStream("mybatis-config.xml");//獲取SqlSessionFactoryBuilder對象SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();//獲取SqlSessionFactory對象SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);//獲取sql的會話對象Sqlsession(不會自動提交事務),是Mybatis提供的操作數據庫的對象 // SqlSession sqlSession = sqlSessionFactory.openSession();//獲取sql的會話對象Sqlsession(會自動提交事務),是Mybatis提供的操作數據庫的對象SqlSession sqlSession = sqlSessionFactory.openSession(true);//獲取UserMapper的代理實現對象UserMapper mapper = sqlSession.getMapper(UserMapper.class);//調用mapper接口中的方法,實現添加用戶信息的功能int result = mapper.insertUser();System.out.println("結果:" + result);//提交事務 // sqlSession.commit();//關閉sqlsessionsqlSession.close();}

    測試遇到的報錯:

    org.apache.ibatis.binding.BindingException: Type interface com.atguigu.mybatis.mapper.UserMapper is not known to the MapperRegistry.

    錯誤原因:核心配置文件中沒有注冊mappers

    解決方法1:在核心配置文件中注冊每個mapper

    <!--引入mybatis的映射文件--><mappers><mapper resource="mappers/UserMapper.xml"/></mappers>

    解決方法2:以包的方式批量注冊mapper

    <mappers><!--以包的方式引入映射文件,但是必須滿足兩個條件:1、mapper接口和映射文件所在的包必須一致2、mapper接口的名字和映射文件的名字必須一致--><package name="com.atguigu.mybatis.mapper"/></mappers>

    SqlSession:代表Java程序和數據庫之間的會話。(HttpSessionJava程序和瀏覽器之間的會話) SqlSessionFactory:是生產”SqlSession工廠 工廠模式:如果創建某一個對象,使用的過程基本固定,那么我們就可以把創建這個對象的相關代碼封裝到一個“工廠類中,以后都使用這個工廠類來生產我們需要的對象。

    ?2.7、加入log4j日志功能

    ①加入依賴 <!-- log4j日志 --><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency>

    ?②加入log4j的配置文件

    log4j的配置文件名為log4j.xml,存放的位置是src/main/resources目錄下

    <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"><appender name="STDOUT" class="org.apache.log4j.ConsoleAppender"><param name="Encoding" value="UTF-8" /><layout class="org.apache.log4j.PatternLayout"><param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n" /></layout></appender><logger name="java.sql"><level value="debug" /></logger><logger name="org.apache.ibatis"><level value="info" /></logger><root><level value="debug" /><appender-ref ref="STDOUT" /></root> </log4j:configuration> 日志的級別 FATAL(致命)>ERROR(錯誤)>WARN(警告)>INFO(信息)>DEBUG(調試) 從左到右打印的內容越來越詳細

    3、核心配置文件詳解?


    ?核心配置文件中的標簽必須按照固定的順序:

    properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,refl ectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?

    <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration><!--MyBatis核心配置文件中的標簽必須要按照指定的順序配置:The content of element type "configuration" must match"(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?)".--><!--引入properties文件,此后就可以在當前文件中使用${key}的方式訪問value--><properties resource="jdbc.properties"/><!--typeAliases:設置類型別名,即為某個具體的類型設置一個別名在MyBatis的范圍中,就可以使用別名表示一個具體的類型--><typeAliases><!--type:設置需要起別名的類型alias:設置某個類型的別名--> <!-- <typeAlias type="com.atguigu.mybatis.pojo.User" alias="abc"></typeAlias>--><!--若不設置alias,當前的類型擁有默認的別名,即類名且不區分大小寫--> <!-- <typeAlias type="com.atguigu.mybatis.pojo.User"></typeAlias>--><!--通過包設置類型別名,指定包下所有的類型將全部擁有默認的別名,即類名且不區分大小寫--><package name="com.atguigu.mybatis.pojo"/></typeAliases><!--environments:配置連接數據庫的環境屬性:default:設置默認使用的環境的id--><environments default="development"><!--environment:設置一個具體的連接數據庫的環境屬性:id:設置環境的唯一標識,不能重復--><environment id="development"><!--transactionManager:設置事務管理器屬性:type:設置事務管理的方式type:"JDBC|MANAGED"JDBC:表示使用JDBC中原生的事務管理方式MANAGED:被管理,例如Spring--><transactionManager type="JDBC"/><!--dataSource:設置數據源屬性:type:設置數據源的類型type="POOLED|UNPOOLED|JNDI"POOLED:表示使用數據庫連接池UNPOOLED:表示不使用數據庫連接池JNDI:表示使用上下文中的數據源--><dataSource type="POOLED"><property name="driver" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></dataSource></environment><environment id="test"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC"/><property name="username" value="root"/><property name="password" value="XXXX"/></dataSource></environment></environments><!--引入mybatis的映射文件--><mappers> <!-- <mapper resource="mappers/UserMapper.xml"/>--><!--以包的方式引入映射文件,但是必須滿足兩個條件:1、mapper接口和映射文件所在的包必須一致2、mapper接口的名字和映射文件的名字必須一致--><package name="com.atguigu.mybatis.mapper"/></mappers> </configuration>

    4MyBatis的增刪改查


    4.1、新增

    <!-- int insertUser();--><insert id="insertUser">insert into t_user values (null,'admin','123456',23,'男','12345@qq.com')</insert>

    4.2、刪除

    <!--void deleteUser();--><delete id="deleteUser">delete from t_user where id = 3</delete>

    4.3、修改

    <!--void updateUser();--><update id="updateUser">update t_user set username='root',password='123' where id = 3</update>

    ?4.4、查詢一個實體類對象

    <!--User getUserById();--><!--resultType:設置結果類型,即查詢的數據要轉換為的java類型resultMap:自定義映射,處理多對一或一對多的映射關系--><select id="getUserById" resultType="com.atguigu.mybatis.pojo.User">select * from t_user where id = 1</select>

    4.5、查詢list集合

    <!--List<User> getAllUser();--><select id="getAllUser" resultType="User">select * from t_user</select> 注意: 查詢的標簽select必須設置屬性resultTyperesultMap,用于設置實體類和數據庫表的映射關系 resultType:自動映射,用于屬性名和表中字段名一致的情況 resultMap:自定義映射,用于一對多或多對一或字段名和屬性名不一致的情況

    5MyBatis獲取參數值的兩種方式 ?


    MyBatis獲取參數值的兩種方式:${}#{}

    ${}的本質就是字符串拼接,#{}的本質就是占位符賦值

    ${}使用字符串拼接的方式拼接sql,若為字符串類型或日期類型的字段進行賦值時,需要手動加單引號; #{}使用占位符賦值的方式拼接sql,此時為字符串類型或日期類型的字段進行賦值時,可以自動添加單引號

    5.1、單個字面量類型的參數 ?

    若mapper接口方法的參數為單個的字面量類型

    此時可以通過#{}和${}以任意的內容獲取參數值,一定要注意${}的單引號問題

    5.2、多個字面量類型的參數

    若mapper接口方法的參數為多個的字面量類型 此時MyBatis會將參數放在map集合中,以兩種方式存儲數據 a>以arg0,arg1...為鍵,以參數為值 b>以param1,param2...為鍵,以參數為值 因此,只需要通過#{}和${}訪問map集合的鍵,就可以獲取相對應的值,一定要注意${}的單引號問題

    5.3map集合類型的參數

    若mapper接口方法的參數為map集合類型的參數 只需要通過#{}和${}訪問map集合的鍵,就可以獲取相對應的值,一定要注意${}的單引號問題

    5.4、實體類類型的參數

    若mapper接口方法的參數為實體類類型的參數 只需要通過#{}和${}訪問實體類中的屬性名(把方法里的get\set去掉剩余部分的首字母變為小寫的結果就是屬性名),就可以獲取相對應的屬性值,一定要注意${}的單引號問題 可以在mapper接口方法的參數上設置@Param注解
    此時MyBatis會將這些參數放在map中,以兩種方式進行存儲
    a>以@Param注解的value屬性為鍵,以參數為值
    b>以param1,param2...為鍵,以參數為值
    只需要通過#{}和${}訪問map集合的鍵,就可以獲取相對應的值,一定要注意${}的單引號問題

    5.5、使用@Param標識參數

    可以在mapper接口方法的參數上設置@Param注解
    此時MyBatis會將這些參數放在map中,以兩種方式進行存儲
    a>以@Param注解的value屬性為鍵,以參數為值
    b>以param1,param2...為鍵,以參數為值
    只需要通過#{}和${}訪問map集合的鍵,就可以獲取相對應的值,一定要注意${}的單引號問題

    ?6MyBatis的各種查詢功能


    6.1、查詢一個實體類對象

    /*** 根據id查詢用戶信息* @param id* @return*/User getUserById(@Param("id") Integer id); <!--User getUserById(@Param("id") Integer id);--><select id="getUserById" resultType="com.atguigu.mybatis.pojo.User">select * from t_user where id = #{id}</select>

    6.2、查詢一個list集合

    /*** 查詢所有的用戶信息* @return*/List<User> getAllUser(); <!--User getUserById(@Param("id") Integer id);--><select id="getAllUser" resultType="com.atguigu.mybatis.pojo.User">select * from t_user</select> 若sql語句查詢的結果為多條時,一定不能以實體類類型作為方法的返回值,否則會拋出異常TooManyResultsException 若sql語句查詢的結果為1條時,此時可以使用實體類類型或list集合類型作為方法的返回值

    6.3、查詢單個數據

    /*** 查詢用戶的總數量* @return*/Integer getCount(); <!--Integer getCount();--><!--MyBatis中為Java中常用的類型設置了類型別名Integer:Integer,intint:_int,_integerMap:mapString:string--><select id="getCount" resultType="java.lang.Integer">select count(*) from t_user</select>

    ?MyBatis中為Java中常用的類型設置了類型別名

    ?6.4、查詢一條數據為map集合

    /*** 根據id查詢用戶信息為map集合* @param id* @return*/Map<String,Object> getUserByIdToMap(@Param("id") Integer id); <!--Map<String,Object> getUserByIdToMap(@Param("id") Integer id);--> <!--結果:{password=123456, gender=男, enail=12345@qq.com, id=1, age=23, username=admin}--><select id="getUserByIdToMap" resultType="java.util.Map">select * from t_user where id = #{id}</select>

    6.5、查詢多條數據為map集合

    ①方式一 /*** 查詢所有的用戶信息為map集合* 若查詢的數據有多條時,并且要將每條數據轉換為map集合* 此時有兩種解決方案:* 1、將mapper接口方法的返回值設置為泛型時map的list集合* List<Map<String,Object>> getAllUserToMap();* 結果: [* {password=123456, gender=男, enail=12345@qq.com, id=1, age=23, username=admin},* {password=123456, gender=女, enail=123@qq.com, id=2, age=33, username=root}* ]** @return*/List<Map<String,Object>> getAllUserToMap(); <!--List<Map<String,Object>> getAllUserToMap();--><select id="getAllUserToMap" resultType="java.util.Map">select * From t_user</select> ②方式二 /*** 查詢所有的用戶信息為map集合* 若查詢的數據有多條時,并且要將每條數據轉換為map集合* 此時有兩種解決方案:* 2、可以將每條數據轉的map集合放在一個大的map中,但是必須要通過@MapKey注解* 將查詢的某個字段的值作為大的map的鍵* @MapKey("id")* Map<String, Object> getAllUserToMap();* 結果: {* 1={password=123456, gender=男, enail=12345@qq.com, id=1, age=23, username=admin},* 2={password=123456, gender=女, enail=123@qq.com, id=2, age=33, username=root}* }** @return*/@MapKey("id")Map<String,Object> getAllUserToMap(); <!--Map<String,Object> getAllUserToMap();--><select id="getAllUserToMap" resultType="java.util.Map">select * From t_user</select>

    7、特殊SQL的執行


    7.1、模糊查詢

    /*** 通過用戶名模糊查詢用戶信息* @param mohu* @return*/List<User> getUserByLike(@Param("mohu") String mohu); <!--List<User> getUserByLike(@Param("mohu") String mohu);--><select id="getUserByLike" resultType="com.atguigu.mybatis.pojo.User"><!--第一種方式:select * from t_user where username like '%${mohu}%'--><!--第二種方式:select * from t_user where username like concat('%',#{mohu},'%')--><!--最常用第三種方式:select * from t_user where username like "%"#{mohu}"%"-->select * from t_user where username like "%"#{mohu}"%"</select>

    mysql中模糊查詢語句:

    select * from t_user where username like '%a%';

    ?7.2、批量刪除

    /*** 批量刪除* @param ids*/void deleteMoreUser(@Param("ids") String ids); <!--void deleteMoreUser(@Param("ids") String ids);//ids:9,10--><delete id="deleteMoreUser">delete from t_user where id in(${ids})</delete>

    7.3、動態設置表名

    /*** 動態設置表名,查詢用戶信息* @param tableName* @return*/List<User> getUserList(@Param("tableName") String tableName); <!--List<User> getUserList(@Param("tableName") String tableName);--><select id="getUserList" resultType="com.atguigu.mybatis.pojo.User">select * from ${tableName}</select>

    7.4、添加功能獲取自增的主鍵

    /*** 添加用戶信息并獲取自增的主鍵* @param user*/void insertUser(User user); <!--void insertUser(User user);--><!--重要:useGeneratedKeys:表示當前添加功能使用自增的主鍵keyProperty:因為增刪改有統一的返回值是受影響的行數,因此只能將添加的自增主鍵為實體類類型的參數的屬性賦值--><insert id="insertUser" useGeneratedKeys="true" keyProperty="id">insert into t_user values(null,#{username},#{password},#{age},#{gender},#{email})</insert>

    8、自定義映射resultMap


    8.1resultMap處理字段和屬性的映射關系

    若字段名和實體類中的屬性名不一致,則可以通過resultMap設置自定義映射 /*** 根據id查詢員工信息* @param empId* @return*/Emp getEmpByEmpId(@Param("empId") Integer empId); <!--resultMap:設置自定義的映射關系id:唯一標識type:處理映射關系的實體類類型常用的標簽:id:處理主鍵和實體類中屬性的映射關系result:處理普通字段和實體類中屬性的映射關系column:設置映射關系中的字段名,必須時sql查詢出的某個字段property:設置映射關系中的屬性的屬性名,必須時處理的實體類類型中的屬性名--><resultMap id="empResultMap" type="emp"><id column="emp_id" property="empId"></id><result column="emp_name" property="empName"></result><result column="age" property="age"></result><result column="gender" property="gender"></result></resultMap><!--Emp getEmpByEmpId(@Param("empId") Integer empId);--><select id="getEmpByEmpId" resultMap="empResultMap">select * from t_emp where emp_id = #{empId}</select>

    字段名和屬性名不一致的情況,如何處理映射關系
    1、為查詢的字段設置別名,和屬性名保持一致
    2、當字段符合MySQL的要求使用_,而屬性符合java的要求使用駝峰
    此時可以在MyBatis的核心配置文件中設置一個全局配置,可以自動將下劃線映射為駝峰

    例如:字段名user_name,設置了mapUnderscoreToCamelCase,此時字段名就會轉換為userName
    3、使用resultMap自定義映射處理

    處理多對一的映射關系:
    1、級聯方式處理
    2、association
    3、分步查詢

    處理一對多的映射關系:
    1、collection
    2、分步查詢

    ?8.2、多對一映射處理

    對一對應對象,對多對應集合 場景模擬: 查詢員工信息以及員工所對應的部門信息 MySQL中多表查詢: SELECT t_emp.*,t_dept.* FROM t_emp LEFT JOIN t_dept ON t_emp.dept_id = t_dept.dept_id WHERE t_emp.emp_id = 1

    ?8.2.1、級聯方式處理映射關系

    <resultMap id="empAndDeptResultMap" type="emp"><id column="emp_id" property="empId"></id><result column="emp_name" property="empName"></result><result column="age" property="age"></result><result column="gender" property="gender"></result><result column="dept_id" property="dept.deptId"></result><result column="dept_name" property="dept.deptName"></result></resultMap><!--Emp getEmpAndDeptByEmpId(@Param("empId") Integer empId);--><select id="getEmpAndDeptByEmpId" resultMap="empAndDeptResultMap">selectt_emp.*,t_dept.*from t_empleft join t_depton t_emp.dept_id = t_dept.dept_idwhere t_emp.emp_id = #{empId}</select> 8.2.2、使用association處理映射關系 <resultMap id="empAndDeptResultMap" type="emp"><id column="emp_id" property="empId"></id><result column="emp_name" property="empName"></result><result column="age" property="age"></result><result column="gender" property="gender"></result><!--association:處理多對一的映射關系(處理實體類類型的屬性)property:設置需要處理映射關系的屬性的屬性名javaType:設置要處理的屬性的類型--><association property="dept" javaType="Dept"><id column="dept_id" property="deptId"></id><result column="dept_name" property="deptName"></result></association></resultMap><!--Emp getEmpAndDeptByEmpId(@Param("empId") Integer empId);--><select id="getEmpAndDeptByEmpId" resultMap="empAndDeptResultMap">selectt_emp.*,t_dept.*from t_empleft join t_depton t_emp.dept_id = t_dept.dept_idwhere t_emp.emp_id = #{empId}</select> 8.2.3、分步查詢 ①查詢員工信息 /*** 通過分步查詢員工以及所對應的部門信息的第一步* @param empId* @return*/Emp getEmpAndDeptByStepOne(@Param("empId") Integer empId); <resultMap id="empAndDeptByStepResultMap" type="emp"><id column="emp_id" property="empId"></id><result column="emp_name" property="empName"></result><result column="age" property="age"></result><result column="gender" property="gender"></result><!--property:設置需要處理映射關系的屬性的屬性名select:設置分布查詢的sql的唯一標識column:將查詢出的某個字段作為分布查詢的sql的條件fetchType:在開啟了延遲加載的環境中,通過該屬性設置當前的分步查詢是否使用延遲加載fetchType="eager(立即加載)|lazy(延遲加載)"--><association property="dept" fetchType="eager"select="com.atguigu.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo"column="dept_id"></association></resultMap><!--Emp getEmpAndDeptByStepOne(@Param("empId") Integer empId);--><select id="getEmpAndDeptByStepOne" resultMap="empAndDeptByStepResultMap">select * from t_emp where emp_id =#{empId}</select> ②根據員工所對應的部門id查詢部門信息 /*** 通過分步查詢員工以及所對應的部門信息的第二步* @return*/Dept getEmpAndDeptByStepTwo(@Param("deptId") Integer deptId); <!--Dept getEmpAndDeptByStepTwo(@Param("deptId") Integer deptId);--><select id="getEmpAndDeptByStepTwo" resultType="com.atguigu.mybatis.pojo.Dept">select * from t_dept where dept_id = #{deptId}</select>

    8.3、一對多映射處理

    8.3.1collection /*** 查詢部門以及部門中的員工信息* @param deptId* @return*/Dept getDeptAndEmpByDeptId(@Param("deptId") Integer deptId); <resultMap id="deptAndEmpResultMap" type="dept"><id column="dept_id" property="deptId"></id><result column="dept_name" property="deptName"></result><!--ofType:設置集合類型的屬性中存儲的數據的類型--><collection property="emps" ofType="emp"><id column="emp_id" property="empId"></id><result column="emp_name" property="empName"></result><result column="age" property="age"></result><result column="gender" property="gender"></result></collection></resultMap><!--Dept getDeptAndEmpByDeptId(@Param("deptId") Integer deptId);--><select id="getDeptAndEmpByDeptId" resultMap="deptAndEmpResultMap">select *from t_deptleft join t_empon t_dept.dept_id= t_emp.dept_idwhere t_dept.dept_id = #{deptId}</select> 8.3.2、分步查詢 ①查詢部門信息 /*** 通過分步查詢查詢部門以及部門中的員工信息的第一步* @param deptId* @return*/Dept getDeptAndEmpByStepOne(@Param("deptId") Integer deptId); <resultMap id="deptAndEmpResultMapByStep" type="Dept"><id column="dept_id" property="deptId"></id><result column="dept_name" property="deptName"></result><collection property="emps"select="com.atguigu.mybatis.mapper.EmpMapper.getDeptAndEmpByStepTwo"column="dept_id"></collection></resultMap><!--Dept getDeptAndEmpByStepOne(@Param("deptId") Integer deptId);--><select id="getDeptAndEmpByStepOne" resultMap="deptAndEmpResultMapByStep">select * from t_dept where dept_id = #{deptId}</select> ②根據部門id查詢部門中的所有員工 /*** 通過分步查詢查詢部門以及部門中的員工信息的第二步* @param deptId* @return*/List<Emp> getDeptAndEmpByStepTwo(@Param("deptId") Integer deptId); <!--List<Emp> getDeptAndEmpByStepTwo(@Param("deptId") Integer deptId);--><select id="getDeptAndEmpByStepTwo" resultType="com.atguigu.mybatis.pojo.Emp">select * from t_emp where dept_id = #{deptId}</select> 分步查詢的優點:可以實現延遲加載 但是必須在核心配置文件中設置全局配置信息: lazyLoadingEnabled:延遲加載的全局開關。當開啟時,所有關聯對象都會延遲加載 aggressiveLazyLoading:當開啟時,任何方法的調用都會加載該對象的所有屬性。否則,每個屬性會按需加載 此時就可以實現按需加載,獲取的數據是什么,就只會執行相應的sql。此時可通過association和collection中的fetchType屬性設置當前的分步查詢是否使用延遲加載, fetchType="lazy(延遲加載)|eager(立即加載)"

    9、動態SQL?


    Mybatis框架的動態SQL技術是一種根據特定條件動態拼裝SQL語句的功能,它存在的意義是為了解決拼接SQL語句字符串時的痛點問題。

    ?9.1if

    if:通過test屬性中的表達式判斷標簽中的內容是否有效(是否會拼到sql中)

    <!--List<Emp> getEmpByCondition(Emp emp);--><select id="getEmpByCondition" resultType="com.atguigu.mybatis.pojo.Emp">select * from t_emp where 1=1<if test="empName != null and empName != ''">and emp_name = #{empName}</if><if test="age != null and age != ''">and age = #{age}</if><if test="gender != null and gender != ''">and gender = #{gender}</if></select>

    ?9.2where

    where和if結合使用:
    ????a.若where標簽中有條件成立,會自動生成where關鍵字
    ????b.會自動將where標簽中內容前多余的and去掉,但是其中內容后多余的and無法去掉
    ????c.若where中沒有任何一個條件成立,則where沒有任何功能

    <!--List<Emp> getEmpByCondition(Emp emp);--> <select id="getEmpByCondition" resultType="com.atguigu.mybatis.pojo.Emp">select * from t_emp<where><if test="empName != null and empName != ''">emp_name = #{empName}</if><if test="age != null and age != ''">and age = #{age}</if><if test="gender != null and gender != ''">and gender = #{gender}</if></where></select>

    ?9.3trim

    trim:
    prefix、suffix:在標簽中內容前面或后面添加指定內容
    prefixOverrides、suffixOverrides:在標簽中內容前面或后面去掉指定內容

    <!--List<Emp> getEmpByCondition(Emp emp);--><select id="getEmpByCondition" resultType="com.atguigu.mybatis.pojo.Emp">select * from t_emp<trim prefix="where" suffixOverrides="and"><if test="empName != null and empName != ''">emp_name = #{empName} and</if><if test="age != null and age != ''">age = #{age} and</if><if test="gender != null and gender != ''">gender = #{gender}</if></trim></select>

    ?9.4choosewhenotherwise

    相當于java中的if...else if...else
    when至少設置一個,otherwise最多設置一個

    <!--List<Emp> getEmpByChoose(Emp emp);--><select id="getEmpByChoose" resultType="com.atguigu.mybatis.pojo.Emp">select * from t_emp<where><choose><when test="empName != null and empName != ''">emp_name = #{empName}</when><when test="age != null and age != ''">age = #{age}</when><when test="gender != null and gender != ''">gender = #{gender}</when></choose></where></select>

    ?9.5、foreach

    foreach:

    collection:設置要循環的數組或集合
    item:用員工字符串標識數組或集合中的每一個數據
    separator:設置每次循環的數據之間的分隔符
    open:循環的所有內容以什么開始
    close:循環的所有內容以什么結束

    <!--void insertMoreEmp(@Param("emps") List<Emp> emps);--><insert id="insertMoreEmp">insert into t_emp values<foreach collection="emps" item="emp" separator=",">(null,#{emp.empName},#{emp.age},#{emp.gender},null)</foreach></insert> <!--void deleteMoreEmp(@Param("empIds") Integer[] empIds);--><delete id="deleteMoreEmp">delete from t_emp where emp_id in<foreach collection="empIds" item="empId" separator="," open="(" close=")">#{empId}</foreach></delete><!--void deleteMoreEmp(@Param("empIds") Integer[] empIds);--><delete id="deleteMoreEmp"> <!-- delete from t_emp where emp_id in<foreach collection="empIds" item="empId" separator="," open="(" close=")">#{empId}</foreach>-->delete from t_emp where<foreach collection="empIds" item="empId" separator="or">emp_id = #{empId}</foreach></delete>

    9.6SQL片段

    SQL片段:可以記錄一段sql,在需要用的地方使用include標簽進行引用 <sql id="empColumns">emp_id,emp_name,age,gender,dept_id</sql><!-- select * from t_emp-->select <include refid="empColumns"></include> from t_emp

    ?10、MyBatis的緩存


    10.1MyBatis的一級緩存

    ?MyBatis的一級緩存是SqlSession級別,即通過同一個SqlSession查詢的數據會被緩存
    ?再次使用同一個SqlSession查詢同一條數據,會從緩存中獲取
    ?使一級緩存失效的四種情況:
    ?1) 不同的SqlSession對應不同的一級緩存
    ?2) 同一個SqlSession但是查詢條件不同
    ?3) 同一個SqlSession兩次查詢期間執行了任何一次增刪改操作
    ?4) 同一個SqlSession兩次查詢期間手動清空了緩存?

    @Testpublic void testGetEmpById(){SqlSession sqlSession1 = SqlSessionUtil.getSqlSession();CacheMapper mapper1 = sqlSession1.getMapper(CacheMapper.class);Emp emp1 = mapper1.getEmpById(1);System.out.println(emp1);//4) 同一個SqlSession兩次查詢期間手動清空了緩存sqlSession1.clearCache();//3) 同一個SqlSession兩次查詢期間執行了任何一次增刪改操作 // mapper1.insertEmp(new Emp(null,"小紅",25,"男"));Emp emp2 = mapper1.getEmpById(1);System.out.println(emp2);//1) 不同的SqlSession對應不同的一級緩存/* SqlSession sqlSession2 = SqlSessionUtil.getSqlSession();CacheMapper mapper2 = sqlSession2.getMapper(CacheMapper.class);Emp emp3 = mapper2.getEmpById(1);System.out.println(emp3);*/}

    10.2、MyBatis的二級緩存

    MyBatis的二級緩存是SqlSessionFactory級別的,即通過同一個SqlSessionFactory所獲取的SqlSession對象

    查詢的數據會被緩存,在通過同一個SqlSessionFactory所獲取的SqlSession查詢相同的數據會從緩存中獲取

    MyBatis二級緩存開啟的條件
    a>在核心配置文件中,設置全局配置屬性cacheEnabled="true",默認為true,不需要設置
    b>在映射文件中設置標簽<cache/>
    c>二級緩存必須在SqlSession關閉或提交之后有效
    d>查詢的數據所轉換的實體類類型必須實現序列化的接口

    使二級緩存失效的情況:
    兩次查詢之間執行了任意的增刪改,會使一級和二級緩存同時失效

    ?10.3、二級緩存的相關配置(了解)

    在mapper配置文件中添加的cache標簽可以設置一些屬性:

    ①eviction屬性:緩存回收策略,默認的是?LRU。

    LRU(Least Recently Used)?– 最近最少使用的:移除最長時間不被使用的對象。

    FIFO(First in First out)?– 先進先出:按對象進入緩存的順序來移除它們。

    SOFT – 軟引用:移除基于垃圾回收器狀態和軟引用規則的對象。

    WEAK – 弱引用:更積極地移除基于垃圾收集器狀態和弱引用規則的對象。

    ②flushInterval屬性:刷新間隔,單位毫秒

    默認情況是不設置,也就是沒有刷新間隔,緩存僅僅調用語句時刷新

    ③size屬性:引用數目,正整數

    代表緩存最多可以存儲多少個對象,太大容易導致內存溢出

    ④readOnly屬性:只讀,?true/false

    true:只讀緩存;會給所有調用者返回緩存對象的相同實例。因此這些對象不能被修改。這提供了很重 要的性能優勢。

    false:讀寫緩存;會返回緩存對象的拷貝(通過序列化)。這會慢一些,但是安全,因此默認是false。

    10.4MyBatis緩存查詢的順序

    ?先查詢二級緩存,因為二級緩存中可能會有其他程序已經查出來的數據,可以拿來直接使用。

    如果二級緩存沒有命中,再查詢一級緩存

    如果一級緩存也沒有命中,則查詢數據庫

    SqlSession關閉之后,一級緩存中的數據會寫入二級緩存

    ?10.5、整合第三方緩存EHCache

    10.5.1、添加依賴 <!-- Mybatis EHCache整合包 --> <dependency> <groupId>org.mybatis.caches</groupId> <artifactId>mybatis-ehcache</artifactId> <version>1.2.1</version> </dependency> <!-- slf4j日志門面的一個具體實現 --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency> 10.5.2、各jar包功能

    10.5.3、創建EHCache的配置文件ehcache.xml

    <?xml version="1.0" encoding="utf-8" ?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="../config/ehcache.xsd"><!-- 磁盤保存路徑 --><diskStore path="D:\atguigu\ehcache"/><defaultCachemaxElementsInMemory="1000"maxElementsOnDisk="10000000"eternal="false"overflowToDisk="true"timeToIdleSeconds="120"timeToLiveSeconds="120"diskExpiryThreadIntervalSeconds="120"memoryStoreEvictionPolicy="LRU"></defaultCache> </ehcache> 10.5.4、設置二級緩存的類型 <cache type="org.mybatis.caches.ehcache.EhcacheCache"/> 10.5.5、加入logback日志 存在SLF4J時,作為簡易日志的log4j將失效,此時我們需要借助SLF4J的具體實現logback來打印日志。 創建logback的配置文件logback.xml <?xml version="1.0" encoding="UTF-8"?> <configuration debug="true"><!-- 指定日志輸出的位置 --><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><!-- 日志輸出的格式 --><!-- 按照順序分別是: 時間、日志級別、線程名稱、打印日志的類、日志主體內容、換行--><pattern>[%d{HH:mm:ss.SSS}] [%-5level] [%thread] [%logger][%msg]%n</pattern></encoder></appender><!-- 設置全局日志級別。日志級別按順序分別是: DEBUG、INFO、WARN、ERROR --><!-- 指定任何一個日志級別都只打印當前級別和后面級別的日志。 --><root level="DEBUG"><!-- 指定打印日志的appender,這里通過“STDOUT”引用了前面配置的appender --><appender-ref ref="STDOUT" /></root><!-- 根據特殊需求指定局部日志級別 --><logger name="com.atguigu.mybatis.mapper" level="DEBUG"/> </configuration>

    ?10.5.6EHCache配置文件說明

    ?11MyBatis的逆向工程


    正向工程:先創建Java實體類,由框架負責根據實體類生成數據庫表。 Hibernate是支持正向工程的。 逆向工程:先創建數據庫表,由框架負責根據數據庫表,反向生成如下資源:
    • Java實體類
    • Mapper接口
    • Mapper映射文件

    ?11.1、創建逆向工程的步驟

    ①添加依賴和插件 <!-- 依賴MyBatis核心包 --><dependencies><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.7</version></dependency><!-- junit測試 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><!-- log4j日志 --><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.16</version></dependency></dependencies><!-- 控制Maven在構建過程中相關配置 --><build><!-- 構建過程中用到的插件 --><plugins><!-- 具體插件,逆向工程的操作是以構建過程中插件形式出現的 --><plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.3.0</version><!-- 插件的依賴 --><dependencies><!-- 逆向工程的核心依賴 --><dependency><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-core</artifactId><version>1.3.2</version></dependency><!-- MySQL驅動 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.16</version></dependency></dependencies></plugin></plugins></build> ②創建MyBatis的核心配置文件 ③創建逆向工程的配置文件 文件名必須是:generatorConfig.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration><!--targetRuntime: 執行生成的逆向工程的版本MyBatis3Simple: 生成基本的CRUD(清新簡潔版)MyBatis3: 生成帶條件的CRUD(奢華尊享版)--><context id="DB2Tables" targetRuntime="MyBatis3"><!-- 數據庫的連接信息 --><jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"connectionURL="jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC"userId="root"password="XXXX"><property name="nullCatalogMeansCurrent" value="true"/></jdbcConnection><!-- javaBean的生成策略--><javaModelGenerator targetPackage="com.atguigu.mybatis.pojo"targetProject=".\src\main\java"><property name="enableSubPackages" value="true" /><property name="trimStrings" value="true" /></javaModelGenerator><!-- SQL映射文件的生成策略 --><sqlMapGenerator targetPackage="com.atguigu.mybatis.mapper"targetProject=".\src\main\resources"><property name="enableSubPackages" value="true" /></sqlMapGenerator><!-- Mapper接口的生成策略 --><javaClientGenerator type="XMLMAPPER"targetPackage="com.atguigu.mybatis.mapper" targetProject=".\src\main\java"><property name="enableSubPackages" value="true" /></javaClientGenerator><!-- 逆向分析的表 --><!-- tableName設置為*號,可以對應所有表,此時不寫domainObjectName --><!-- domainObjectName屬性指定生成出來的實體類的類名 --><table tableName="t_emp" domainObjectName="Emp"/><table tableName="t_dept" domainObjectName="Dept"/></context> </generatorConfiguration> ④執行MBG插件的generate目標 ⑤效果

    ?11.2QBC查詢

    @Testpublic void testMBG(){SqlSession sqlSession = SqlSessionUtil.getSqlSession();EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);//根據id查詢數據 // Emp emp = mapper.selectByPrimaryKey(1); // System.out.println(emp);//查詢所有數據 // List<Emp> list = mapper.selectByExample(null); // list.forEach(System.out::println);//根據條件查詢數據 // EmpExample example = new EmpExample(); // example.createCriteria().andEmpNameEqualTo("張三").andAgeGreaterThanOrEqualTo(20); // example.or().andGenderEqualTo("男"); // List<Emp> list = mapper.selectByExample(example); // list.forEach(System.out::println);Emp emp = new Emp(1,"小黑",null,"女");//測試普通修改功能 // mapper.updateByPrimaryKey(emp);//測試選擇性修改mapper.updateByPrimaryKeySelective(emp);}

    使用逆行工程產生的問題

    ①idea中逆向工程生成文件,出現很多重復文件

    ②解決重復文件

    在逆向工程文件里的數據庫連接的信息jdbcConnection標簽中加入:

    <property name="nullCatalogMeansCurrent" value="true"/>

    ?12、分頁插件


    ?limit index,pageSize

    pageSize:每頁顯示的條數

    pageNum:當前頁的頁碼

    index:當前頁的起始索引,index=(pageNum-1)*pageSize

    count:總記錄數

    totalPage:總頁數

    totalPage = count / pageSize;

    if(count % pageSize != 0){

    totalPage += 1;

    }

    pageSize=4,pageNum=1,index=0 limit 0,4

    pageSize=4,pageNum=3,index=8 limit 8,4

    pageSize=4,pageNum=6,index=20 limit 8,4

    首頁 上一頁 2 3 4 5 6 下一頁 末頁

    12.1、分頁插件的使用步驟

    ①添加依賴

    <dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.2.0</version></dependency> ②配置分頁插件 MyBatis的核心配置文件中配置插件 <plugins><!--設置分頁插件--><plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin></plugins>

    12.2、分頁插件的使用

    @Testpublic void testPage(){SqlSession sqlSession = SqlSessionUtil.getSqlSession();EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);//查詢功能之前開啟分頁功能Page<Object> page = PageHelper.startPage(5, 4);List<Emp> list = mapper.selectByExample(null);//查詢功能之后可以獲取分頁相關的所有數據PageInfo<Emp> pageInfo = new PageInfo<>(list,5);list.forEach(System.out::println);System.out.println(pageInfo);} a>在查詢功能之前使用PageHelper.startPage(int pageNum, int pageSize)開啟分頁功能 pageNum:當前頁的頁碼 pageSize:每頁顯示的條數

    ?b>在查詢獲取list集合之后,使用PageInfo<T> pageInfo = new PageInfo<>(List<T> list, int navigatePages)獲取分頁相關數據

    list:分頁之后的數據 navigatePages:導航分頁的頁碼數

    ?c>分頁相關數據

    PageInfo{ pageNum=8, pageSize=4, size=2, startRow=29, endRow=30, total=30, pages=8, list=Page{count=true, pageNum=8, pageSize=4, startRow=28, endRow=32, total=30, pages=8, reasonable=false, pageSizeZero=false}, prePage=7, nextPage=0, isFirstPage=false, isLastPage=true, hasPreviousPage=true, hasNextPage=false, navigatePages=5, navigateFirstPage4, navigateLastPage8, navigatepageNums=[4, 5, 6, 7, 8] } pageNum:當前頁的頁碼 pageSize:每頁顯示的條數 size:當前頁顯示的真實條數 total:總記錄數 pages:總頁數 prePage:上一頁的頁碼 nextPage:下一頁的頁碼 isFirstPage/isLastPage:是否為第一頁/最后一頁 hasPreviousPage/hasNextPage:是否存在上一頁/下一頁 navigatePages:導航分頁的頁碼數 navigatepageNums:導航分頁的頁碼,[1,2,3,4,5]

    ?二、Spring


    1Spring簡介


    1.1Spring概述

    總結

    以上是生活随笔為你收集整理的SSM框架整合(参考尚硅谷视频和文档的全部內容,希望文章能夠幫你解決所遇到的問題。

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