Mybatis的基本用法笔记

1.mybatis核心文件和概念说明

1.配置文件
a)整合spring之后,配置了mybatis的运行环境等信息,此文件作为mybatis的全局配置文件。
b) Mapper.xml,此文件作为mybatis的sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。
2.SqlSessionFactory
通过mybatis环境等配置信息构造SqlSessionFactory,即会话工厂,生命周期:sqlsessionFactory:全局范围(应用级别)。
3.sqlSession
通过会话工厂创建sqlSession即会话,通过sqlsession会话接口对数据库进行增删改查操作,生命周期:sqlsession:方法级别。
4.Executor执行器
mybatis底层自定义了Executor执行器接口来具体操作数据库,Executor接口有两个实现,一个是基本执行器(默认)、一个是缓存执行器,sqlsession底层是通过executor接口操作数据库的。
5.Mapped Statement
mybatis的底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个select\insert\update\delete标签对应一个Mapped Statement对象,select\insert\update\delete标签的id即是Mapped statement的id。
a)Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。
b)Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。

2. XML开发方式

使用mybatis开发DAO层代码,只需要开发Mapper接口(dao接口)和Mapper约束文件,不需要编写实现类。
Mapper接口开发需要遵循以下规范:
1、 Mapper接口的类路径与Mapper.xml文件中的namespace相同。
2、 Mapper接口方法名称和Mapper.xml中定义的每个statement的id相同。
3、 Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同。
4、 Mapper接口方法的返回值类型和mapper.xml中定义的每个sql的resultType的类型相同。
代码如下:

mapper映射文件
<mapper namespace="mybatis.mapper.UserMapper">
<!-- 根据id获取用户信息 -->
	<select id="findUserById" parameterType="int" resultType="mybatis.po.User">
		select * from user where id = #{id}
	</select>
</mapper>
mapper接口
public interface UserMapper {
	//根据用户id查询用户信息
	public User findUserById(int id) ;
}
<!-- 加载映射文件 -->
  <mappers>
    <mapper resource="mapper/UserMapper.xml"/>
  </mappers>
注意:在项目集成spring时,直接在spring的配置中配置即可

3.查询简单用法

a)parameterType:定义输入到sql中的映射类型,可以映射的输入参数类型有:
简单类型、POJO类型、Map类型、List类型(数组)。
b)resultType:属性可以映射的java类型有:简单类型、POJO类型、Map类型。使用resultType进行输出映射时,要求sql语句中查询的列名和要映射的pojo的属性名一致。
代码示例:

接口:
public interface UserMapper {
    public User findUserById(int id);
    public List<User> findUserList(Object object);
}
mapper.xml
<!-- 简单查询 -->
<select id="findUserById" parameterType="int" resultType="User">
		select * from user where id = #{id} 
</select>
<!-- 使用包装类型查询用户,使用ognl从对象中取属性值,如果是包装对象可以使用 . 操作符来取内容部的属性,
user.username为ognl表达式用法-->
	<select id="findUserList" parameterType="Object" resultType="user">
		SELECT * FROM user where username like '%${user.username}%'
	</select>

c)resultMap:若sql查询列名和pojo的属性名不一致,可以通过resultMap将列名和属性名作一个对应关系,最终将查询结果映射到指定的pojo对象中。实际上:resultType底层也是通过resultMap完成映射的。属性标签说明:
id标签:此属性表示查询结果集的唯一标识。如果是多个字段为复合唯一约束则定义多个。
Property:表示User类的属性。
Column:表示sql查询出来的字段名。
Column和property放在一块儿表示将sql查询出来的字段映射到指定的pojo类属性上。
result:普通结果,即pojo的属性。
代码示例:

接口:
public List<User> findUserListResultMap() 
Mapper映射文件
<!-- 定义resultMap:将查询的列名和映射的pojo的属性名做一个对应关系 -->
<!-- type:指定查询结果要映射的pojo的类型,id:指定resultMap的唯一标示 -->
<resultMap type="user" id="userListResultMap">
		<!-- 
		id标签:映射查询结果的唯一列(主键列)
			column:查询sql的列名
			property:映射结果的属性名
		-->
		<id column="id_" property="c_id"/>
		<!-- result标签:映射查询结果的普通列 -->
		<result column="username" property="c_username"/>
	</resultMap>
	<!-- resultMap入门 -->
	<select id="findUserListResultMap" resultMap="userListResultMap">
		SELECT c_id id,c_username username FROM user
	</select>

d)一对一查询
1、使用resultType进行结果映射,查询的列名和映射pojo的属性名称要一致。
创建包含两个表属性的pojo,做为查询结果的返回集resultType

<!-- 查询用户订单信息,需要用户和定订单两张表 -->
	<select id="findOrdersList" resultType="mybatis.po.OrdersExt">
	SELECT
	orders.*,
	user.username,
	user.address
	FROM
	orders,	user
	WHERE orders.user_id = user.id 
	</select>

e)一对多查询
在一对多关联查询时,只能使用resultMap进行结果映射。
1、一对多关联查询时,sql查询结果有多条,而映射对象是一个。
2、resultType完成结果映射的方式的一条记录映射一个对象。
3、resultMap完成结果映射的方式是以[主信息]为主对象,[从信息]映射为集合或者对象,然后封装到主对象中。
标签说明:
Collection标签:定义了一对多关联的结果映射。
property=“orders”:关联查询的结果集存储在User对象的上哪个属性。
ofType=“orders”:指定关联查询的结果集中的对象类型即List中的对象类型。此处可以使用别名,也可以使用全限定名。
代码示例:

一个人的多个订单信息,封装查询返回的对象:
public class User{
	private String id;
	private String username;
	private  List<Order> orders;
}
在UserMapper.xml文件中,添加以下代码:
<resultMap type="user" id="userAndOrderRstMap">
		<!-- 用户信息映射 -->
		<id property="id" column="id"/>
		<result property="username" column="username"/>
		<!-- 一对多关联映射 -->
		<collection property="orders" ofType="orders">
			<id property="id" column="oid"/>	
			<result property="userId" column="id"/>
			<result property="number" column="number"/>
			<result property="createtime" column="createtime"/>
			<result property="note" column="note"/>
		</collection>
	</resultMap>
	<select id="findUserAndOrderRstMap" resultMap="userAndOrderRstMap">
		SELECT
		u.*,
        o.id oid,
		o.number,
		o.createtime,
		o.note
		FROM
		`user` u
		LEFT JOIN orders o ON u.id = o.user_id
	</select>

f)#{}和${}区别

区别1
#{} :相当于JDBC SQL语句中的占位符? (PreparedStatement),如:#{id}表示使用preparedstatement设置占位符号,并将输入变量id传到sql
${}  : 相当于JDBC SQL语句中的连接符合 + (Statement),相当于JDBC中的 ?占位符
区别2
#{} : 进行输入映射的时候,会对参数进行类型解析(如果是String类型,那么SQL语句会自动加上’’)
${}  :进行输入映射的时候,将参数原样输出到SQL语句中
区别3
#{} : 如果进行简单类型(String、Date、8种基本类型的包装类)的输入映射时,#{}中参数名称可以任意
${}  : 如果进行简单类型(String、Date、8种基本类型的包装类)的输入映射时,${}中参数名称必须是value
区别4
底层解析方法不一样
#{}:是通过反射获取数据的---StaticSqlSource 
${}:是通过OGNL表达式会随着对象的嵌套而相应的发生层级变化 --DynamicSqlSource

注意:${} :存在SQL注入问题 ,使用OR 1=1 关键字将查询条件忽略

4.插入的简单用法

插入数据之后,返回主键,添加selectKey标签实现主键返回。

  • keyProperty:指定返回的主键,存储在pojo中的哪个属性
  • order:selectKey标签中的sql的执行顺序,是相对与insert语句来说。由于mysql的自增原理,执行完insert语句之后才将主键生成,所以这里selectKey的执行顺序为after。
  • resultType:返回的主键对应的JAVA类型
  • LAST_INSERT_ID():是mysql的函数,返回auto_increment自增列新记录id值。
    代码示例:
<insert id="insertUser" parameterType="mybatis.po.User">
		<!-- selectKey将主键返回,需要再返回 -->
		<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
			select LAST_INSERT_ID()
		</selectKey>
	   insert into user(username,birthday,sex,address)
	    values(#{username},#{birthday},#{sex},#{address});
	</insert>

5.删除用法

<!-- 删除用户 -->
	<delete id="deleteUserById" parameterType="int">
		delete from user where id=#{id}
	</delete>

6.修改用法

<!-- 更新用户 -->
	<update id="updateUser" parameterType="mybatis.po.User">
		update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}
		where id=#{id}
    </update>

7.动态SQL

  • if标签使用方法
    代码示例:
<select id="findUserList" parameterType="queryVo" resultType="user">
	SELECT * FROM user where 1=1
	<if test="user != null">
		<if test="user.username != null and user.username != ''">
			AND username like '%${user.username}%'
		</if>
	</if>
</select>
  • where标签使用方法
    在where语句后的sql中使用1=1,虽然可以保证sql语句的完整性:但是存在性能问题。
    使用where标签可以解决此问题
    代码示例:
<select id="findUserList" parameterType="queryVo" resultType="user">
		SELECT * FROM user
		<!-- where标签会处理它后面的第一个and -->
		<where>
			<if test="user != null">
				<if test="user.username != null and user.username != ''">
					AND username like '%${user.username}%'
				</if>
			</if>
		</where>
	</select>
  • sql片段
    将常用的不变的sql提取成公共的sql片段,在其他的sql需要使用时,直接引用即可。
    代码示例:
<sql id="query_user_where">
		<if test="user != null">
			<if test="user.username != null and user.username != ''">
				AND username like '%${user.username}%'
			</if>
		</if>
</sql>
<!-- 使用包装类型查询用户 使用ognl从对象中取属性值,如果是包装对象可以使用.操作符来取内容部的属性 -->
	<select id="findUserList" parameterType="queryVo" resultType="user">
		SELECT * FROM user
		<!-- where标签会处理它后面的第一个and -->
		<where>
			<include refid="query_user_where"></include>
		</where>
	</select>

注意:
1、如果引用其它mapper.xml的sql片段,则在引用时需要加上namespace,如下:<include refid="namespace.sql片段”/>

  • foreach标签的使用
    代码示例:
<sql id="query_user_where">
		<if test="user != null">
			<if test="user.username != null and user.username != ''">
				AND username like '%${user.username}%'
			</if>
		</if>
		<if test="ids != null and ids.size() > 0">
			<!-- collection:指定输入的集合参数的参数名称 -->
			<!-- item:声明集合参数中的元素变量名 -->
			<!-- open:集合遍历时,需要拼接到遍历sql语句的前面 -->
			<!-- close:集合遍历时,需要拼接到遍历sql语句的后面 -->
			<!-- separator:集合遍历时,需要拼接到遍历sql语句之间的分隔符号 -->
			<foreach collection="ids" item="id" open=" AND id IN ( "
				close=" ) " separator=",">
				#{id}
			</foreach>
		</if>
	</sql>

注意:如果parameterType不是POJO类型,而是List或者Array的话,那么foreach语句中,collection属性值需要固定写死为list或者array。

以上只是对Mybatis使用的简单总结
如有错误,敬请指正。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值