mybatis 文檔:https://mybatis.org/mybatis-3/zh/
##maven:pom.xml
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.3</version>
</dependency>
#mybatis-config.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>
<!-- 可以配置兩個環境development test default=xxx-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/iqiyi?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="howhy@123"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- <mapper class="com.howhy.study.mapper.UserMapper"/>-->
<package name="com.howhy.study.mapper"/>
</mappers>
</configuration>
##UserMapper.java接口 UserMapper.xml 檔案名稱路徑必須一緻
##UserMapper.java
public interface UserMapper {
public User findUserById(Integer id);
}
##UserMapper.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">
<mapper namespace="com.howhy.study.mapper.UserMapper">
<select id="findUserById" resultType="com.howhy.study.domain.User">
select * from account where id = #{id}
</select>
</mapper>
##mybatis日志
##pom.xml
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.20</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
##logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- 配置檔案修改時重新加載,預設true -->
<configuration scan="true">
<!--定義日志檔案的存儲位址 勿在 LogBack 的配置中使用相對路徑-->
<property name="CATALINA_BASE" value="**/logs"></property>
<!-- 控制台輸出 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder charset="UTF-8">
<!-- 輸出日志記錄格式 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- 第一個檔案輸出,每天産生一個檔案 -->
<appender name="FILE1" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 輸出檔案路徑+檔案名 -->
<fileNamePattern>${CATALINA_BASE}/aa.%d{yyyyMMdd}.log</fileNamePattern>
<!-- 儲存30天的日志 -->
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder charset="UTF-8">
<!-- 輸出日志記錄格式 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- 第二個檔案輸出,每天産生一個檔案 -->
<appender name="FILE2" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${CATALINA_BASE}/bb.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${CATALINA_BASE}/bb.%d{yyyyMMdd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder charset="UTF-8">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="CUSTOM" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${CATALINA_BASE}/custom.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>${CATALINA_BASE}/custom.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- keep 30 days' worth of history -->
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder charset="UTF-8">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- 設定日志輸出級别 -->
<root level="ERROR">
<appender-ref ref="CONSOLE" />
</root>
<logger name="file1" level="DEBUG">
<appender-ref ref="FILE1" />
</logger>
<logger name="file1" level="INFO">
<appender-ref ref="FILE2" />
</logger>
<!-- 自定義logger -->
<logger name="custom" level="INFO">
<appender-ref ref="CUSTOM" />
</logger>
</configuration>
首先,如果你的資料庫支援自動生成主鍵的字段(比如 MySQL 和 SQL Server),那麼你可以設定 useGeneratedKeys=”true”,然後再把 keyProperty 設定為目标屬性就 OK 了。例如,如果上面的 Author 表已經在 id 列上使用了自動生成,那麼語句可以修改為:
<insert id="insertAuthor" useGeneratedKeys="true"
keyProperty="id">
insert into Author (username,password,email,bio)
values (#{username},#{password},#{email},#{bio})
</insert>
如果你的資料庫還支援多行插入, 你也可以傳入一個
Author
數組或集合,并傳回自動生成的主鍵。
<insert id="insertAuthor" useGeneratedKeys="true"
keyProperty="id">
insert into Author (username, password, email, bio) values
<foreach item="item" collection="list" separator=",">
(#{item.username}, #{item.password}, #{item.email}, #{item.bio})
</foreach>
</insert>
對于不支援自動生成主鍵列的資料庫和可能不支援自動生成主鍵的 JDBC 驅動,MyBatis 有另外一種方法來生成主鍵。
這裡有一個簡單(也很傻)的示例,它可以生成一個随機 ID(不建議實際使用,這裡隻是為了展示 MyBatis 處理問題的靈活性和寬容度):
<insert id="insertAuthor">
<selectKey keyProperty="id" resultType="int" order="BEFORE">
select CAST(RANDOM()*1000000 as INTEGER) a from SYSIBM.SYSDUMMY1
</selectKey>
insert into Author
(id, username, password, email,bio, favourite_section)
values
(#{id}, #{username}, #{password}, #{email}, #{bio}, #{favouriteSection,jdbcType=VARCHAR})
</insert>
在上面的示例中,首先會運作 selectKey 元素中的語句,并設定 Author 的 id,然後才會調用插入語句。這樣就實作了資料庫自動生成主鍵類似的行為,同時保持了 Java 代碼的簡潔。
selectKey 元素描述如下:
<selectKey
keyProperty="id"
resultType="int"
order="BEFORE"
statementType="PREPARED">
##mybatis 參數傳遞
1、#{} jdbc預編譯的方式?傳參 可以防止sql注入 ${} sql語句拼接的方式 有sql注入問題 一個參數 #{這裡可以随便寫} ${這裡可以随便寫}
2、多個參數:#{arg0} #{arg1} 或 #{param1} #{param2} 若dao層 參數沒有注解@Param() 這兩個方式都可以 若有注解@Param()隻能使用#{param1} #{param2}
3、參數是javaBean或map 單個參數可以直接使用#{屬性名} 或#{param1} 多個參數可以使用:#{param1} #{bean.屬性} #{param1.屬性}
4、參數是集合或數組 mybatis list會封閉成map {key:"list",value:"[1,2]"} 數組會封裝成map {key:"array",value:"[1,2]"}如下
<select id="findUserByIds" resultType="com.howhy.study.domain.User">
select * from account where id = #{list[0]} or id = #{list[1]}
</select>
<select id="findUserByIds" resultType="com.howhy.study.domain.User">
select * from account where id = #{array[0]} or id = #{array[1]}
</select>
##ResultMap
<resultMap id="userResultMap" type="User">
<id property="id" column="user_id" />
<result property="username" column="user_name"/>
<result property="password" column="hashed_password"/>
</resultMap>
然後在引用它的語句中設定 resultMap 屬性就行了(注意我們去掉了 resultType 屬性)。比如:
<select id="selectUsers" resultMap="userResultMap">
select user_id, user_name, hashed_password
from some_table
where id = #{id}
</select>
Mybatis緩存
一級緩存:預設開啟了
1、若關閉:localCacheScope=STATEMENT
2、緩存預設作用域是基于sqlSession的,一次資料庫操作會話
3、緩存預設實作類PerpetualCache,使用map進行存儲的key的值是hashcode+sqlid+sql語句+hashcode+開發環境
4、查詢時就會緩存
緩存失效的情況:
1、不同的sqlSession會使一級緩存失效
2、同一個sqlSession不同的sql查詢語句
3、同一個sqlSession和同樣的sql查詢語句但執行了其它的增删改的情況
4、手動清空緩存
二級緩存:預設也是開啟的,但沒有實作
1、作用域是全局的,應用級的
2、開啟二級緩存 :<setting name="cacheEnabled" value="true"></setting>
3、在需要用到二級緩存的映射檔案mapper.xml中加入<cache></cache>,基于mapper映射檔案來實作緩存的,基于mapper映射檔案命名空間來存儲的
4、事務送出時才會緩存
緩存失效:
1、同一個命名空間進行增删改就會失效
先從二級緩存中取 若二級緩存沒有再從一級緩存中取