在程序的運行的過程當中爲了便於查詢sql的輸出,須要引入logj添加依賴java
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.25</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
添加log4j.properties文件sql
log4j.rootCategory=DEBUG, stdout , R log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=[QC] %p [%t] %C.%M(%L) | %m%n log4j.appender.R=org.apache.log4j.DailyRollingFileAppender log4j.appender.R.File=C:\\tools\\logs\\dpb.log log4j.appender.R.layout=org.apache.log4j.PatternLayout log4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c - %m%n
效果 數據庫
因爲MyBatis底層仍是Jdbc,而Jdbc在操做數據庫傳遞參數時,有兩種方式,一種是使用Statement,還有一種是使用PreparedStatement: 使用statement時,存在SQL注入問題,PreparedStatement則經過預編譯解決了SQL注入問題。 在MyBatis中,引入參數有兩種方式,一種是使用#,還有一種是使用$,其中,使用#對應了Jdbc種的PreparedStatement,而使用$則對應了Jdbc種的Statement,所以在MyBatis種,推薦使用#。apache
加入可使用$替換#,注意,若是使用$,須要在Mapper種指定參數名字 api
javabean數組
public class UserWrapper { private User user; public User getUser() { return user; } public void setUser(User user) { this.user = user; } }
<!-- 從包裝對象中獲取信息 包裝對象的別名. 取信息 --> <insert id="addUser4" parameterType="UserWrapper"> insert into t_user(name,age,favorites)values(#{user.name},#{user.age} ,#{user.favorites}) </insert>
測試mybatis
對於簡單數據類型,例如查詢總記錄數、查詢某一個用戶名這一類返回值是一個基本數據類型的,直接寫Java中的基本數據類型便可。 若是返回的是一個對象或者集合,而且對象中的屬性和查詢的字段名是一一對應的,那麼resultType也能夠直接寫一個對象。app
resultMap主要用來解決屬性名和字段名不一致以及一對多、一對一查詢等問題 字段名不一致時,首先能夠經過取別名解決,例如Bean的定義以下:框架
private int id; // 該類型和字段不一致 private String username; private int age;
<resultMap type="com.sxt.bean.User" id="baseMap"> <id column="id" property="id"/> <result property="username" column="name"/> <result property="age" column="age"/> </resultMap> <select id="getUserById" resultMap="baseMap" resultType="com.sxt.bean.User"> select id ,name ,age from t_user where id=${id} </select>
通常狀況下,主鍵有兩種生成方式:ide
主鍵自增加 自定義主鍵(通常可使用UUID)
若是是第二種,主鍵通常是在Java代碼中生成,而後傳入數據庫執行,若是是第一個主鍵自增加,此時,Java可能須要知道數據添加成功後的主鍵。 在MyBatis中,能夠經過主鍵回填來解決這個問題(推薦)。
<insert id="add" parameterType="user" useGeneratedKeys="true" keyProperty="id"> insert into t_user(username,password) values (#{name},#{password}) </insert>
另外,能夠利用MySQL自帶的==last_insert_id()==函數查詢剛剛插入的id
<insert id="add1" parameterType="user"> <selectKey keyProperty="id" resultType="int" > select LAST_INSERT_ID() </selectKey> insert into t_user(username,password) values (#{name},#{password}) </insert>
MyBatis 的強大特性之一即是它的動態 SQL。若是你有使用 JDBC 或其它相似框架的經驗,你就能體會到根據不一樣條件拼接 SQL 語句的痛苦。例如拼接時要確保不能忘記添加必要的空格,還要注意去掉列表最後一個列名的逗號。利用動態 SQL 這一特性能夠完全擺脫這種痛苦。 雖然在之前使用動態 SQL 並不是一件易事,但正是 MyBatis 提供了能夠被用在任意 SQL 映射語句中的強大的動態 SQL 語言得以改進這種情形。 動態 SQL 元素和 JSTL 或基於相似 XML 的文本處理器類似。在 MyBatis 以前的版本中,有不少元素須要花時間瞭解。MyBatis 3 大大精簡了元素種類,如今只需學習原來一半的元素即可。MyBatis 採用功能強大的基於 OGNL 的表達式來淘汰其它大部分元素。
動態 SQL 一般要作的事情是根據條件包含 where 子句的一部分。好比
<select id="queryUser" resultMap="baseMap" resultType="com.sxt.bean.User" parameterType="user"> select id ,name ,age from t_user where 1 =1 <if test="username!=null"> and name = #{username} </if> </select>
// 接口 public List<User> queryUser(User user);
測試
在使用if語句作動態條件處理的時候若是全部條件都不知足,那麼獲得的SQL語句以下:
select * from t_user where
在這種狀況下,咱們通常會加一個1=1來匹配語法規則
<select id="queryUser" resultMap="baseMap" resultType="com.sxt.bean.User" parameterType="user"> select id ,name ,age from t_user where 1 =1 <if test="username!=null"> and name = #{username} </if> </select>
此時可使用標籤來處理這種狀況
<select id="queryUser" resultMap="baseMap" resultType="com.sxt.bean.User" parameterType="user"> select id ,name ,age from t_user <where> <if test="username!=null"> and name = #{username} </if> </where> </select>
set主要也是用來解決更新問題的。
<update id="updateBookById"> update t_book <set> <if test="author!=null"> author=#{author},</if> <if test="name!=null"> b_name=#{name},</if> <if test="price!=null"> price=#{price},</if> </set> where id=#{id}; </update>
foreach用來遍歷,遍歷的對象能夠是數組,也能夠是集合
<select id="query1" resultType="User" resultMap="basemap"> select * from t_user where id in <foreach collection="ids" open="(" close=")" separator="," item="id"> #{id} </foreach> </select> <insert id="add2" parameterType="user" useGeneratedKeys="true" keyProperty="id"> insert into t_user(username,password) values <foreach collection="users" separator="," item="user"> (#{user.name},#{user.password}) </foreach> </insert>
bind 元素能夠從 OGNL 表達式中建立一個變量並將其綁定到上下文。
<select id="getUserById" resultMap="baseMap" resultType="com.sxt.bean.User"> <!-- 聲明瞭一個參數aaa 在後面就可使用了 --> <bind name="aaa" value="12"/> select id ,name ,age from t_user where id=${aaa} </select>
sql片斷通常用來定義sql中的列
在關係型數據庫中,表與表之間不多是獨立與其餘表不要緊的。因此在實際開發過程當中咱們會碰到不少複雜的關聯關係。在此咱們來分析下載mybatis中怎麼處理這些關係
咱們有一張員工表(T_EMP),一張部門表(T_DEPT)。員工表中的一條記錄對應於部門表中有且僅有一條記錄。這就是一對一的關聯關係。
查詢每一個員工的信息及對應的部門信息
package com.sxt.bean; public class Dept { private Integer deptid; private String deptname; private String deptdesc; public Integer getDeptid() { return deptid; } public void setDeptid(Integer deptid) { this.deptid = deptid; } public String getDeptname() { return deptname; } public void setDeptname(String deptname) { this.deptname = deptname; } public String getDeptdesc() { return deptdesc; } public void setDeptdesc(String deptdesc) { this.deptdesc = deptdesc; } @Override public String toString() { return "Dept [deptid=" + deptid + ", deptname=" + deptname + ", deptdesc=" + deptdesc + "]"; } }
package com.sxt.bean; public class Emp { private Integer id; private String name; private Dept dept; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Dept getDept() { return dept; } public void setDept(Dept dept) { this.dept = dept; } @Override public String toString() { return "Emp [id=" + id + ", name=" + name + ", dept=" + dept + "]"; } }
<?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.sxt.dao.EmpDao"> <resultMap type="Emp" id="basemap"> <id property="id" column="id"/> <result property="name" column="name"/> <association property="dept" javaType="Dept"> <id property="deptid" column="deptid"/> <result property="deptname" column="deptname"/> <result property="deptdesc" column="deptdesc"/> </association> </resultMap> <select id="query" resultMap="basemap"> SELECT t.*,t1.* FROM t_emp t LEFT JOIN t_dept t1 on t.deptid=t1.deptid </select> </mapper>
查詢出全部的部門信息及該部門下全部員工的信息
<?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.sxt.dao.DeptDao"> <resultMap type="Dept" id="basemap"> <id property="deptid" column="deptid"/> <result property="deptname" column="deptname"/> <result property="deptdesc" column="deptdesc"/> <collection property="emps" ofType="Emp"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="deptid" column="deptid"/> </collection> </resultMap> <select id="query" resultMap="basemap"> SELECT t.*,t1.* FROM t_dept t LEFT JOIN t_emp t1 on t.deptid=t1.deptid </select> </mapper>