1 Mybatis快速入门
Mybatis开发步骤:
1. 创建表,添加数据
2.创建模块,导入maven坐标
3.编写Mybatis核心配置文件--->替换连接信息,解决硬编码问题
4.编写SQL映射文件--->统一管理sql语句,解决硬编码问题
5. 编码
1)定义POJO类
2)加载核心配置文件,获取SqlSessionFactory对象
3)获取SqlSession对象,执行SQL语句
4)释放资源
2 Mapper代理开发
使用Mapper代理方式开发步骤:
1. 定义与SQL映射文件同名的Mapper接口,并将Mapper接口和SQL映射文件放在同一目录下
2.设置SQL映射文件的namespace属性为Mapper接口的全限定名
3.在Mapper接口中定义方法,方法名就是SQL映射文件中的sql语句的id,并保持参数类型和返回值类型一致
4.编码
1)通过SqlSession的getMapper方法获取Mapper接口的代理对象
2)调用对应方法即可完成sql的执行,相当于将方法与与sql做了绑定
细节:若Mapper接口名称与SQL映射文件名称相同,且在同一目录下,则可以使用包扫描方式简化SQL映射文件加载(扫描Mapper接口所在包即可)。
<!--加载sql映射文件-->
<mapper resource="com/shan/mapper/UserMapper.xml"/>
......
<!--使用Mapper代理方式时,可以使用包扫描的方式,即包下所有Mapper接口对应的sql映射文件都被加载-->
<package name="com.shan.mapper"/>
3 Mybatis核心配置文件(mybatis-config.xml)
注意注释中的要点
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--配置文件的标签顺序有严格要求,不然会报错,一般按如下顺序即可-->
<configuration>
<typeAliases>
<!--此处配置别名进行包扫描,在xxxMapper.xml文件中的返回值类型resultType,可以直接写类名,而不用写全限定类名-->
<package name="com.shan.pojo"/>
</typeAliases>
<!--配置数据库连接环境,可以配置多个environment,通过default属性切换不同的environment-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/test" />
<property name="username" value="root" />
<property name="password" value="admin" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/mybatis3/mappers/StudentMapper.xml" />
</mappers>
</configuration>
4 配置文件完成增删改查
4.1 查询
4.1.1.在数据库字段名与定义实体类的属性名不一致时,导致查询出来的数据不能正确的封装到实体类对象中。
可以在xxxMapper.xml文件中定义resultMap标签,将查询的字段名取别名,从而与实体类的属性名一致。同时要将statement(即定义的sql语句)中的resultType改为resultMap。
<select id="selectAll" resultType="brand">
select * from tb_brand;
</select>
<!--修改后-->
<resultMap id="brandResultMap" type="brand">
<!--result标签完成一般字段的映射,id标签可以完成主键字段的映射-->
<result column="brand_name" property="brandName"/>
<result column="company_name" property="companyName"/>
</resultMap>
<select id="selectAll" resultMap="brandResultMap">
select * from tb_brand;
</select>
4.1.2.查询时需要传递参数,使用参数占位符及特殊字符处理
参数占位符:
1. #{ }:会将其替换为?(类似于preparedStatment),为了防止SQL注入
2. ${ }:拼sql,会存在SQL注入问题
3. 使用时机:
参数传递时使用 #{ }
表名或列名不固定的情况下,可能会使用${ },但可能出现sql注入问题
特殊字符处理:
1. 转义字符:如 < (小于号)在XML文件中会报错,用 < 代替
2. CDATA区:<![CDATA[内容]]> 适合大篇幅使用转移字符
<select id="selectById" resultMap="brandResultMap">
select * from tb_brand where id = #{id};
</select>
<select id="selectById" resultMap="brandResultMap">
select * from tb_brand where id < #{id};
</select>
4.1.3.条件查询
多条件查询
需要多参数传递,常用的有以下三种方式(mybatis参数传递有机会可再深入了解)
<!--@Param("SQL中的参数占位符名称")-->
List<Brand> selectByCondition(@Param("status")int status,@Param("companyName") String companyName,@Param("brandName") String brandName);
<!--保证SQL中的参数名和实体类属性名对应-->
List<Brand> selectByCondition(Brand brand);
<!--保证SQL中的参数名和map集合的健的名称对应-->
List<Brand> selectByCondition(Map map);
<select id="selectByCondition" resultMap="brandResultMap">
select *
from tb_brand
where status = #{status}
and company_name like #{companyName}
and brand_name like #{brandName}
</select>
多条件-动态条件查询
但上述sql语句在未传递所有参数进行查询时(即只想根据少量条件进行查询)会导致查询错误
这一类sql我们称之为动态sql,mybatis对动态sql有很好的支持,并提供了以下标签
-- if
-- choose(when,otherwise)
-- trim(where,set)
-- foreach
该问题可以使用<if>和<where>标签解决
<select id="selectByCondition" resultMap="brandResultMap">
select *
from tb_brand
<where>
<if test="status != null">
and status = #{status}
</if>
<if test="companyName != null and companyName != '' ">
and company_name like #{companyName}
</if>
<if test="brandName != null and brandName != '' ">
and brand_name like #{brandName}
</if>
</where>
</select>
单条件-动态条件查询(下面两种方式均可)
<select id="selectByCondition" resultMap="brandResultMap">
select *
from tb_brand
where
<choose> <!--类似于switch-->
<when test="status != null">
and status = #{status}
</when>
<when test="companyName != null and companyName != '' "> <!--类似于case-->
and company_name like #{companyName}
</when>
<when test="brandName != null and brandName != '' ">
and brand_name like #{brandName}
</when>
<otherwise> <!--类似于default-->
1 = 1
</otherwise>
</choose>
</select>
<select id="selectByCondition" resultMap="brandResultMap">
select *
from tb_brand
<where>
<choose>
<when test="status != null">
and status = #{status}
</when>
<when test="companyName != null and companyName != '' ">
and company_name like #{companyName}
</when>
<when test="brandName != null and brandName != '' ">
and brand_name like #{brandName}
</when>
</choose>
</where>
</select>
4.2 添加
Mybatis事务:
openSession():默认开启事务,进行增删改后需要使用sqlSession.commit();手动提交事务
openSession(true):可以设置为自动提交事务(关闭事务)
添加后返回主键值
void add(Brand brand);
默认添加数据时不会返回主键值,若想添加后返回主键值需要在insert标签中设置如下两个属性
<insert useGeneratedKeys="true" keyProperty="id">
<insert id="add" useGeneratedKeys="true" keyProperty="id">
insert into tb_brand (brand_name,company_name,ordered)
values (#{brandName},#{companyName},#{ordered});
</insert>
4.3 修改
修改全部字段
int update(Brand brand);
<update id="update">
update tb_brand
set
brand_name = #{brandName},
company_name = #{companyName},
ordered = #{ordered}
where id = #{id};
</update>
修改动态字段
若只想修改部分字段的值,使用上述sql则会导致其他值被设置为null。应使用下面方式
<update id="update">
update tb_brand
<set>
<if test="brandName != null and brandName != ''">
brand_name = #{brandName},
</if>
<if test="companyName != null and companyName != ''">
company_name = #{companyName},
</if>
<if test="ordered != null">
ordered = #{ordered}
</if>
</set>
where id = #{id};
</update>
4.4 删除
删除一个
void deleteById(int id);
<delete id="deleteById">
delete from tb_brand where id = #{id}
</delete>
批量删除
void deleteByIds(@Param("ids") int[] ids);
<delete id="deleteByIds">
delete from tb_brand
where id in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>
5 注解完成增删改查
注解完成简单功能、配置文件完成复杂功能。注解不用写xml文件。
以查询为例
@Select("select * from tb_user where id = #{id}")
public User selectById(int id);