MyBatis教程3【映射文件和动态sql】

1.logj

在程序的运行的过程中为了便于查询sql的输出,需要引入logj添加依赖

<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文件

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中,引入参数有两种方式,一种是使用#,还有一种是使用KaTeX parse error: Expected 'EOF', got '#' at position 7: ,其中,使用#̲对应了Jdbc种的Prepar…则对应了Jdbc种的Statement,因此在MyBatis种,推荐使用#。

#的使用

在这里插入图片描述
在这里插入图片描述

$的使用

加入可以使用KaTeX parse error: Expected 'EOF', got '#' at position 3: 替换#̲,注意,如果使用,需要在Mapper种指定参数名字
在这里插入图片描述
在这里插入图片描述

包装对象

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>

测试

在这里插入图片描述
在这里插入图片描述

3.返回数据

ResultType

对于简单数据类型,例如查询总记录数、查询某一个用户名这一类返回值是一个基本数据类型的,直接写Java中的基本数据类型即可。
  如果返回的是一个对象或者集合,并且对象中的属性和查询的字段名是一一对应的,那么resultType也可以直接写一个对象。

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> 

在这里插入图片描述

主键回写

一般情况下,主键有两种生成方式:

主键自增长
自定义主键(一般可以使用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对多既是多对多关系

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值