MyBatis教程3【映射文件和動態sql】

1.logj

在程序的運行的過程當中爲了便於查詢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

效果 在這裏插入圖片描述數據庫

2.傳入參數【$和#】

因爲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

在這裏插入圖片描述 在這裏插入圖片描述

3.返回數據

ResultType

對於簡單數據類型,例如查詢總記錄數、查詢某一個用戶名這一類返回值是一個基本數據類型的,直接寫Java中的基本數據類型便可。   若是返回的是一個對象或者集合,而且對象中的屬性和查詢的字段名是一一對應的,那麼resultType也能夠直接寫一個對象。app

ResultMap

resultMap主要用來解決屬性名和字段名不一致以及一對多、一對一查詢等問題 字段名不一致時,首先能夠經過取別名解決,例如Bean的定義以下:框架

User對象

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>

在這裏插入圖片描述 在這裏插入圖片描述

selectKey

另外,能夠利用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>

在這裏插入圖片描述

動態sql語句

MyBatis 的強大特性之一即是它的動態 SQL。若是你有使用 JDBC 或其它相似框架的經驗,你就能體會到根據不一樣條件拼接 SQL 語句的痛苦。例如拼接時要確保不能忘記添加必要的空格,還要注意去掉列表最後一個列名的逗號。利用動態 SQL 這一特性能夠完全擺脫這種痛苦。   雖然在之前使用動態 SQL 並不是一件易事,但正是 MyBatis 提供了能夠被用在任意 SQL 映射語句中的強大的動態 SQL 語言得以改進這種情形。   動態 SQL 元素和 JSTL 或基於相似 XML 的文本處理器類似。在 MyBatis 以前的版本中,有不少元素須要花時間瞭解。MyBatis 3 大大精簡了元素種類,如今只需學習原來一半的元素即可。MyBatis 採用功能強大的基於 OGNL 的表達式來淘汰其它大部分元素。

if語句

動態 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);

測試 在這裏插入圖片描述

where語句

在使用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語句

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語句

foreach用來遍歷,遍歷的對象能夠是數組,也能夠是集合

dao層接口

在這裏插入圖片描述

mapper映射文件

<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元素

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片斷通常用來定義sql中的列 在這裏插入圖片描述

關聯關係

在關係型數據庫中,表與表之間不多是獨立與其餘表不要緊的。因此在實際開發過程當中咱們會碰到不少複雜的關聯關係。在此咱們來分析下載mybatis中怎麼處理這些關係

1對1

咱們有一張員工表(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>

在這裏插入圖片描述

1對多關係

查詢出全部的部門信息及該部門下全部員工的信息 在這裏插入圖片描述

映射文件

<?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>

在這裏插入圖片描述

多對多,即便雙向的1對多既是多對多關係

相關文章
相關標籤/搜索