MyBatis的xml配置(核心配置)
configuration(配置)
properties(屬性)
settings(設定)
typeAliases(型別別名)
typeHandlers(型別處理器)
objectFactory(物件工廠)
plugins(外掛)
environments(環境配置)
environment(環境變數)
transactionManager(事務管理器)
dataSource(資料來源)
databaseIdProvider(資料庫廠商標識)
mappers(對映器)
MyBatis的Mapper對映
Mapper對映檔案只有幾個頂級元素(按照應被定義的順序如下): cache – 對給定名稱空間的快取配置。 cache-ref – 對其他名稱空間快取配置的引用。 resultMap – 是最複雜也是最強大的元素,用來描述如何從資料庫結果集中來載入物件。 sql – 可被其他語句引用的可重用語句塊。 insert – 對映插入語句 update – 對映更新語句 delete – 對映刪除語句 select – 對映查詢語句
MyBatis也可以使用註解開發
生成程式碼時候,配置: <javaClientGenerator type="ANNOTATEDMAPPER"... 生成註解程式碼,不生成xml程式碼了
MyBatis開發使用註解還是xml?
方式 | 優點 | 缺點 |
Xml | Xml與介面分離,方便管理,複雜的SQL不影響程式碼的可讀性 | 過多的Xml配置檔案 |
Annotation | 介面就能看到SQL語句,可讀性強,不需要去找xml檔案,方便 | 程式碼和SQL混雜,複雜一點過於混亂 |
MyBatis批量插入
1 普通for迴圈(此種方式對於資料庫的I/O過於頻繁,不適合大資料量的操作)
for (int i = 0; i < 500; i++) { user = new User(); user.setId("id" + i); user.setName("name" + i); userMapper.insert(user); }
2 ExeutorType.BATCH(設定批量模式),把SQL語句發個資料庫,資料庫預編譯好,然後資料庫等待需要執行的引數,接收到引數一次性執行
session = sqlSessionFactory.openSession(ExecutorType.BATCH, true); for (int i=0; i<500; i++) { UUserInfo userInfo = new UUserInfo(); userInfo.setPhone("1346262122" + i); userInfo.setUserName("張" + i); uUserInfoMapper.insert(userInfo); }
3 傳入一個陣列或集合,標籤<foreach>插入
<foreach item="item" collection="strs.split(',')" separator="," open="(" close=")"> #{item} </foreach>
方式 | 效能 | 說明 |
For迴圈 | 效能低,IO高 | |
ExeutorType.BATCH | 效能居中 | |
<foreach>標籤拼SQL | 效能最高 |
有SQL長度限制,mysql預設接收SQl的長度為10486576(1M),該方式若超過1M 會丟擲異常 |
MyBatis聯合查詢
一對一關係
在一對一關係中,A表中的一行最多隻能匹配B表的一行,反之亦然.這種關係並不常見,因為一般來說,這種關係的資訊會儲存在一張表中,當然也可以利用一對一關係來儲存,比如分割具有多列的表.(如:一個人只有一個身份證)
<association>標籤
<resultMap id="OneToOneBaseResultMap" type="com.test.mybatis.model.Person"> <id column="id" jdbcType="INTEGER" property="id" /> <result column="nick" jdbcType="VARCHAR" property="nick" /> <result column="phone" jdbcType="VARCHAR" property="phone" /> <result column="sex" jdbcType="INTEGER" property="sex" /> <association property="idCard" javaType="com.test.mybatis.model.IdCard"> <id column="id" jdbcType="INTEGER" property="id" /> <result column="personId" jdbcType="INTEGER" property="personid" /> <result column="realName" jdbcType="VARCHAR" property="realname" /> <result column="idCard" jdbcType="VARCHAR" property="idcard" /> </association> </resultMap>
一對多關係
一對多是最普通的一種關係,在這種關係中,A表的一行可以匹配B表中的多行,但是B表中的一行只能匹配A表中的一行.舉例:(一個部門可以有多個員工)
<collection>標籤
<resultMap type="com.mybatis.bean.Department" id="MyDept"> <id column="did" property="id"/> <result column="dept_name" property="departmentName"/> <!-- collection定義關聯集合型別的屬性的封裝規則 ofType:指定集合裡面元素的型別 --> <collection property="emps" ofType="com.mybatis.bean.Employee"> <!-- 定義這個集合中元素的封裝規則 --> <id column="eid" property="id"/> <result column="last_name" property="lastName"/> <result column="email" property="email"/> <result column="gender" property="gender"/> </collection> </resultMap>
多對多關係
在多對多的關係中,A表的一行可以匹配B表的多行.反之亦然.要建立這種關係,需要定義第三張表,也可以稱之為結合表或者關係表.它的主鍵是由A表和B表的外部鍵組成. 舉例(一個使用者有多個角色,一個角色可以對應多個使用者)
<collection>標籤
MyBatis插入並返回主鍵
方式一:(資料庫要設定主鍵自增長)
<insert id="insertSelective" useGeneratedKeys="true" keyProperty="id" keyColumn="id" parameterType="com.test.mybatis.model.UUserInfo">
useGeneratedKeys="true"表示使用主鍵自增 keyProperty="id"表示將主鍵自增後的主鍵值賦值給實體類中的id屬性
parameterType="com.test.mybatis.model.UUserInfo" 實體類,自增後的主鍵值將會賦值給該實體類的id屬性
方式二:(一般用在<insert>標籤裡面)
<selectKey keyProperty="id" resultType="integer" order="AFTER"> SELECT LAST_INSERT_ID() </selectKey>
SELECT LAST_INSERT_ID()表示查詢出剛剛插入的的記錄自增長id order='AFTER' 表示先執行插入語句,之後再執行查詢語句
MyBatis的SQL隱碼攻擊
注入攻擊的危害
1:資料庫被拖庫(把資料從資料庫拉取出來,造成資料洩露)
2.重要資訊被洩露
注入的本質是把使用者輸入的資料當做有效程式碼執行. Mybatis的預編譯機制可以有效防止SQL隱碼攻擊. '#{}' 和 '${}'的區別: '#{}':MyBaits會首先對其進行預編譯,將#{user_ids}替換成?佔位符,然後在執行時替換成實際傳入的user_id值,**並在兩邊加上單引號,以字串方式處理。 '${}':簡單的字串拼接
栗子:
uUserInfoMapper.selectByIn("select user_name from u_user_info"); where user_name in (${userName}) 可使用MyBatis自帶迴圈標籤解決SQL語句動態拼接的問題: select * from news where id in <foreach collection="ids" item="item" open="("separator="," close=")"> #{item} </foreach>
MyBatis的自定義型別轉換器(實現資料型別和資料庫資料型別的對映關係 如:String和VARCHAR的對應關係) 需求:實現對資料庫身份證儲存的加密
1、定義自己的HandlerType實現TypeHandler介面或者繼承BaseTypeHandler類 2、覆蓋其四個方法; 3、在核心配置檔案mybatis-config.xml中配置<typeHandlers>標籤或者在對映檔案的增、改、查位置單獨配置; <typeHandlers> <typeHandler javaType="com.test.mybatis.typehandler.UserIdCard" handler="com.bjpowernode.mybatis.typehandler.CryptTypeHandler"/> </typeHandlers> <result column="idCard" jdbcType="VARCHAR" property="userIdCard" javaType="com.bjpowernode.mybatis.typehandler.UserIdCard"
typeHandler="com.test.mybatis.typehandler.CryptTypeHandler"/> <if test="userIdCard != null"> #{userIdCard, jdbcType=VARCHAR, typeHandler=com.test.mybatis.typehandler.CryptTypeHandler}, </if>
系統自帶的型別轉換器StringTypeHandler
public class StringTypeHandler extends BaseTypeHandler<String> { @Override public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException { ps.setString(i, parameter); } @Override public String getNullableResult(ResultSet rs, String columnName) throws SQLException { return rs.getString(columnName); } @Override public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException { return rs.getString(columnIndex); } @Override public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { return cs.getString(columnIndex); } }
MyBatis的動態SQL
if --判斷標籤
choose (when, otherwise) --多項選擇 ,與頁面的 jstl 標籤非常類似
trim (where, set) --修剪、格式化,新增前字尾的一個標籤
foreach --迴圈
<select id="dynamicChoose" parameterType="News" resultType="News"> select * from news where 1 = 1 <choose> <when test="title != null"> and title = #{title} </when> <when test="content != null"> and content = #{content} </when> <otherwise> and owner = "zhangsan" </otherwise> </choose> </select>
MyBatis的SQL片段使用
<sql id="Base_Column_List"> id, name </sql>
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap"> select <include refid="Base_Column_List"/> from user where id = #{id,jdbcType=INTEGER} </select>
MyBatis的一級.二級快取
一級快取是sqlSession級別,預設開啟
二級快取是mapper級別,預設關閉,快取命中率低
MyBatis的事務管理:
<transactionManager type="JDBC"> <property name="..." value="..."/> </transactionManager>
如果你正在使用 Spring + MyBatis,則沒有必要配置事務管理器, 因為 Spring 模組會使用自帶的管理器來覆蓋前面的配置.