上次写到数据库操作使用了
MyBatis Plus, 但是考虑到之后的源码学习, 因此决定改用MyBatis
首先确定在依赖中引入mybatis
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
进行mybatis的配置
mybatis:
configuration:
map-underscore-to-camel-case: true # 打开驼峰命名法
mapper-locations: classpath:mapper/*.xml # 设置mapper文件位置
创建Dao接口类
@Mapper
public interface UserDao {
Integer saveUser(@Param("user") User user);
Integer deleteUserById(@Param("id") Long id);
User getUserById(@Param("id") Long id);
User login(@Param("account") String account, @Param("password") String password);
Integer updateUserById(@Param("user") User user);
}
与Mybatis Plus不同的就是Mybatis自身并不具备基本的SQL
需要我们自己进行添加.
<?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="cn.bngel.bngelbookuserprovider8001.dao.UserDao">
<insert id="saveUser">
insert into bngel_user(username, password, phone, email, gender, birthday, register_date, profile)
values (#{user.username}, #{user.password}, #{user.phone}, #{user.email}, #{user.gender},
#{user.birthday}, now(), #{user.profile});
</insert>
<delete id="deleteUserById">
delete from bngel_user where id = #{id};
</delete>
<select id="getUserById" resultType="cn.bngel.bngelbookuserprovider8001.bean.User">
select * from bngel_user where id = #{id};
</select>
<select id="login" resultType="cn.bngel.bngelbookuserprovider8001.bean.User">
select * from bngel_user where (phone = #{account} or email = #{account}) and password = #{password};
</select>
<update id="updateUserById">
update bngel_user
<set>
<if test="user.username != null">username=#{user.username},</if>
<if test="user.password != null">password=#{user.password},</if>
<if test="user.phone != null">phone=#{user.phone},</if>
<if test="user.email != null">email=#{user.email},</if>
<if test="user.gender != null">gender=#{user.gender},</if>
<if test="user.email != null">birthday=#{user.birthday},</if>
<if test="user.profile != null">profile=#{user.profile}</if>
</set>
where id = #{user.id};
</update>
</mapper>
sql 映射文件: 写 sql 语句的, MyBatis 会执行这些 sql
1. <!DOCTYPE xxx> 指定约束文件
mybatis-3-mapper.dtd 约束文件的名称, 扩展名为 dtd
2. 约束文件作用:限制, 检查当前文件中出现的标签, 属性必须满足MyBatis的要求
3. mapper 是当前文件的根标签, 是必需的
namespace: 命名空间, 是唯一值, 可以是自定义的字符串
要求使用 dao 接口的全限定名称
4. 在当前文件中, 可以使用特定的标签, 表示数据库的特定操作
<select>: 表示执行查询
<update>: 表示更新数据库的操作, 也就是在<update>标签中写的是 update 的 sql 语句
<insert>: 表示插入, 放的是 insert 的 sql 语句
<delete>: 表示删除
5. id 表示要执行的 sql 语句的唯一标识, MyBatis 会使用这个 id 的值来找到要执行的 sql 语句
可以自定义, 但是一般使用接口中的方法名
resultType 表示结果类型, 是遍历 sql 语句执行后得到的 ResultSet 的 java 对象的类型
值为类型的全限定名称
其中比较特殊的就是update方法.
因为我们在更新用户信息的时候不一定需要将所有的信息, 或者说基本上都是不需要的.
只需要将其中的个别属性进行修改
因此就需要使用动态SQL语句
mybatis官方文档 | 动态 SQL
动态SQL语句
sql的内容是变化的, 可以根据条件获取到不同的sql语句, 主要是where部分发生变化
动态sql的实现, 使用的是MyBatis提供的标签: <if> 、 <where> 、 <foreach>
-
<if> 判断条件标签
-
动态sql使用时, 方法要使用java对象作为参数
-
在mapper中使用<if>标签
<select id="selectStudentIf" resultType="student"> select `id`,`name`,`email`,`age` from student where <if test="name != null and name != '' "> name = #{name} </if> <if test="age > 0"> and age > #{age} </if> </select>在不同的情况下所得到的sql语句为:
# 当两个if同时成立时 select `id`,`name`,`email`,`age` from student where name = ? and age > ? # 当姓名为空时 报错 select `id`,`name`,`email`,`age` from student where and age > ? # 当年龄为负数时 select `id`,`name`,`email`,`age` from student where name = ? # 当两个条件同时不满足时 报错 select `id`,`name`,`email`,`age` from student where因此需要进行修改
<select id="selectStudentIf" resultType="student"> select `id`,`name`,`email`,`age` from student <if test="name != null and name != '' "> where name = #{name} <if test="age > 0"> and age > #{age} </if> </if> </select>也就是<if>标签之间可以互相嵌套.
或者在主sql语句中, 增加
1=1<select id="selectStudentIf" resultType="student"> select `id`,`name`,`email`,`age` from student where 1 = 1 <if test="name != null and name != '' "> and name = #{name} </if> <if test="age > 0"> and age > #{age} </if> </select>
-
-
<where> 标签用来包含多个 <if>
当多个<if>标签有一个成立时, <where>会自动添加一个where关键字, 并去掉<if>中多余的 and, or 等.
避免了sql语法错误导致的报错
<select id="selectStudentWhere" resultType="student"> select `id`,`name`,`email`,`age` from student <where> <if test=""> <if test="name != null and name != '' "> and name = #{name} </if> <if test="age > 0"> and age > #{age} </if> </if> </where> </select>此时在组装sql语句时, 就会自动添加where关键字, 并且去除多余的 and, or 等关键字.
-
<foreach>标签做循环处理
循环java中的数组, list集合, 主要用在sql的in语句中, 例如:
select * from student where id in (1001,1002,1003)因此需要从java代码中传入List数组. 作为sql语句的in的参数.
-
需要循环整数(基本类型)集合时
<select id="selectStudentForEach" resultType="student"> select * from student where id in <!-- collection: 表示接口中的方法参数的类型, 数组为array, list集合使用list item: 自定义的, 表示数组和集合成员的变量 open: 循环开始时的字符 close: 循环结束时的字符 separator: 集合成员之间的分隔符 --> <foreach collection="list" item="myId" open="(" close=")" separator=","> #{myId} </foreach> </select> -
需要循环对象集合时
<select id="selectStudentForEach2" resultType="student"> select * from student where id in <foreach collection="list" item="student" open="(" close=")" separator=","> #{student.id} </foreach> </select>直接在对应的对象后使用点运算符访问属性即可.
student.id访问当前student对象的id属性.
-
-
代码片段
格式:
<sql id="用来调用的唯一标识"> sql代码片段 </sql>调用时使用:
格式:
<include refid="需要调用的代码片段"/>
通过用户传入的`User`, 不为`null`的则表示需要修改
之后直接通过注入进行使用即可.
@Autowired
private UserDao userDao;
欢迎各位来对我的小项目提出各种宝贵的意见, 这对我的进步非常重要, 谢谢大家.
GitHub地址: Bngel/bngelbook