提交
This commit is contained in:
parent
93634c2453
commit
26b4c46206
340
source/_posts/Mybatis基本介绍.md
Normal file
340
source/_posts/Mybatis基本介绍.md
Normal file
@ -0,0 +1,340 @@
|
|||||||
|
# Mybatis
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
## Maven引入Mybatis
|
||||||
|
|
||||||
|
版本号最好去Maven Repository中查找
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<properties>
|
||||||
|
<mybatis.version>3.5.7</mybatis.version>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mybatis</groupId>
|
||||||
|
<artifactId>mybatis</artifactId>
|
||||||
|
<version>${mybatis.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Mybatis配置文件 *mybatis-config.xml*
|
||||||
|
|
||||||
|
```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>
|
||||||
|
<!--<typeAlias type="com.crx.entity.User" alias="user"></typeAlias>-->
|
||||||
|
<!-- 默认值就是类型首字母小写 -->
|
||||||
|
<package name="com.wyd.mybatis20210702.entity"/>
|
||||||
|
</typeAliases>
|
||||||
|
|
||||||
|
<environments default="development">
|
||||||
|
<environment id="development">
|
||||||
|
<transactionManager type="JDBC"></transactionManager>
|
||||||
|
<dataSource type="POOLED">
|
||||||
|
<property name="driver" value="com.mysql.jdbc.Driver"/>
|
||||||
|
<property name="url" value="jdbc:mysql://localhost:3306/ssm?useSSL=false&useUnicode=true&characterEncoding=utf8"/>
|
||||||
|
<property name="username" value="root"/>
|
||||||
|
<property name="password" value="123456"/>
|
||||||
|
</dataSource>
|
||||||
|
</environment>
|
||||||
|
</environments>
|
||||||
|
|
||||||
|
<!-- 注册mapper映射文件 -->
|
||||||
|
<mappers>
|
||||||
|
<mapper resource="mapper/UserMapper.xml"></mapper>
|
||||||
|
<!-- 注册接口 -->
|
||||||
|
<!--<mapper class="com.wyd.dao.UserMapper2"></mapper>-->
|
||||||
|
</mappers>
|
||||||
|
|
||||||
|
</configuration>
|
||||||
|
```
|
||||||
|
## Springboot中 *application.yml*
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
spring:
|
||||||
|
datasource:
|
||||||
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
|
url: jdbc:mysql://localhost:3306/ssm?useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
|
||||||
|
username: root
|
||||||
|
password: 123456
|
||||||
|
|
||||||
|
mybatis:
|
||||||
|
type-aliases-package: com.wyd.mybatis20210702.entity
|
||||||
|
mapper-locations: classpath*:/mapper/*.xml
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Mybatis interface *UserMapper*
|
||||||
|
|
||||||
|
```java
|
||||||
|
package com.wyd.mybatis20210702.dao;
|
||||||
|
|
||||||
|
import com.wyd.mybatis20210702.entity.User;
|
||||||
|
|
||||||
|
public interface UserMapper {
|
||||||
|
User selectUserById(Integer id);
|
||||||
|
|
||||||
|
int insertUser(User user);
|
||||||
|
|
||||||
|
int updateUser(User user);
|
||||||
|
|
||||||
|
int deleteUser(Integer id);
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
每个Mapper接口都有对应的xml映射文件,如果idea安装有MybatisX插件可以单击类名 ALT+ENTER 快捷键即可创建对应xml映射文件
|
||||||
|
|
||||||
|
映射文件夹一般命名为mapper 存放于resources文件夹下
|
||||||
|
|
||||||
|
在Mapper接口每声明一个方法可以通过MybatisX创建对应的映射,但命名需遵循一定规范,否则需自己选择crud
|
||||||
|
|
||||||
|
## Mybatis xml映射文件 ***UserMapper.xml***
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<?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.wyd.mybatis20210702.dao.UserMapper">
|
||||||
|
<select id="selectUserById" resultType="user">
|
||||||
|
SELECT id,username,PASSWORD,birthday FROM USER
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<insert id="insertUser" parameterType="com.crx.entity.User">
|
||||||
|
insert into user (username,password) values (#{username},#{password})
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<update id="updateUser" parameterType="com.crx.entity.User">
|
||||||
|
update user set username = #{username},password = #{password},birthday = #{birthday} where id = #{id}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<delete id="deleteUser">
|
||||||
|
delete from user where id = #{id}
|
||||||
|
</delete>
|
||||||
|
</mapper>
|
||||||
|
```
|
||||||
|
|
||||||
|
可以发现xml映射文件头跟mybatis-config.xml配置文件头很像
|
||||||
|
|
||||||
|
就有一个单词不同
|
||||||
|
|
||||||
|
一个是config 一个是mapper,这决定了这个xml文件可以写什么语句
|
||||||
|
|
||||||
|
每个参数都接#{},{}里就写接口中的参数名
|
||||||
|
|
||||||
|
重点来了
|
||||||
|
|
||||||
|
### #{}和${}的区别
|
||||||
|
|
||||||
|
学过jdbc知道有Statement和PreparedStatement
|
||||||
|
|
||||||
|
一个是固定好的sql语句,一个是预处理语句
|
||||||
|
|
||||||
|
PreparedStatement #{}就很像 ? 后面接参数名,这就很好地防止了 Sql Injection 也就是sql'注入
|
||||||
|
|
||||||
|
我这些sql语句都没有写${}就是因为防止sql注入,开发时严谨使用
|
||||||
|
|
||||||
|
1、Statement和PreparedStatement区别是一样
|
||||||
|
2、#代表使用的底层是PreparedStatement。占位符的写法,预加载
|
||||||
|
3、$代表使用的底层是Statement。字符串的拼接的写法。SQL注入
|
||||||
|
|
||||||
|
那么什么时候使用${}呢?最多的是模糊查询,但是也不推荐这样用
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<select id="selectAllUsersByUsername" parameterType="string" resultType="com.crx.entity.User">
|
||||||
|
select id,username,password,birthday from user where username like '%${username}%'
|
||||||
|
</select>
|
||||||
|
```
|
||||||
|
|
||||||
|
为了拼接上参数就必须使用${}来固化sql
|
||||||
|
|
||||||
|
应该在Java代码上来实现模糊查询
|
||||||
|
|
||||||
|
```java
|
||||||
|
String username = ;
|
||||||
|
if(username != null && !"".equals(username.trim())){
|
||||||
|
username = "%" + username + "%";
|
||||||
|
}else{
|
||||||
|
username = "%%";
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
这样就可以避免sql注入
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
resultType 就是 返回的数据类型,有点儿Java方法中的return 不过这是返回的类型而不是变量名
|
||||||
|
|
||||||
|
parameterType 就是参数类型,实体类要写包名类名
|
||||||
|
|
||||||
|
而Java基本数据类型,比如int就直接写int就行了,引用数据类型比如Integer,String 要把首字目小写,integer,string,这是因为用到了别名,也可以像实体类一样写java.lang.Integer,java.lang.String
|
||||||
|
|
||||||
|
## Mybatis xml映射文件特性
|
||||||
|
|
||||||
|
动态sql
|
||||||
|
|
||||||
|
应用场景,条件查询
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<select id="selectUsers" resultType="com.crx.entity.User">
|
||||||
|
select id,username,password,birthday from user
|
||||||
|
<!-- if标签相当于多重if,只要条件全都满足,所有满足的sql代码块都会执行 -->
|
||||||
|
<where>
|
||||||
|
<if test="id != null">
|
||||||
|
and id = #{id}
|
||||||
|
</if>
|
||||||
|
<if test="username != null">
|
||||||
|
and username = #{username}
|
||||||
|
</if>
|
||||||
|
<if test="password != null">
|
||||||
|
and password = #{password}
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
</select>
|
||||||
|
```
|
||||||
|
|
||||||
|
<where>标签可动态拼接条件,如果where后条件字段都为null,则where以及后面语句都不会拼接
|
||||||
|
|
||||||
|
<if test="">标签则相当于if判断,test等于约束条件,需要注意的是其中只要写字段名即可
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<select id="selectUsers" resultType="com.crx.entity.User">
|
||||||
|
select id,username,password,birthday from user
|
||||||
|
/*
|
||||||
|
when,choose,otherwise相当于if...else if....else if
|
||||||
|
otherwise相当于else,
|
||||||
|
当满足第一个条件时,不再向下执行判断
|
||||||
|
*/
|
||||||
|
<where>
|
||||||
|
<choose>
|
||||||
|
<when test="username != null and username != ''">
|
||||||
|
and username = #{username}
|
||||||
|
</when>
|
||||||
|
<when test="password != null and password != ''">
|
||||||
|
and password = #{password}
|
||||||
|
</when>
|
||||||
|
<otherwise>
|
||||||
|
and id = #{id}
|
||||||
|
</otherwise>
|
||||||
|
</choose>
|
||||||
|
</where>
|
||||||
|
</select>
|
||||||
|
```
|
||||||
|
|
||||||
|
<choose>标签有点像Java中的switch语句,其中的<when>标签则向当于case,但这个case中是带有break的,也就是说每满足一个<when test>条件则此<choose>标签后续语句都不会执行,有一点需要说的是<where>中可以有多个<choose>,满足一个<when test>则会跳出这个<choose>标签,继续执行后续语句,如果<when test>都不满足,如果有<otherwise>标签,则会执行,这有点儿像default语句了
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<select id="selectUsers" resultType="com.crx.entity.User">
|
||||||
|
select id,username,password,birthday from user
|
||||||
|
/*
|
||||||
|
有时候我们需要去掉一些特殊的SQL语法,比如说and,or,where,
|
||||||
|
此时可以使用trim标签,
|
||||||
|
*/
|
||||||
|
<!--<trim prefix="where" prefixOverrides="and">
|
||||||
|
<if test="username != null and username != '' ">
|
||||||
|
username = #{username}
|
||||||
|
</if>
|
||||||
|
<if test="password != null and password != ''">
|
||||||
|
and password = #{password}
|
||||||
|
</if>
|
||||||
|
</trim>-->
|
||||||
|
</select>
|
||||||
|
```
|
||||||
|
|
||||||
|
这个例子中,<trim>标签中的**prefix**属性会使*where* 元素会动态地在行首插入 where关键字,**prefixOverrides**属性会删掉额外的and(这些and是在使用条件语句给列赋值时引入的)
|
||||||
|
|
||||||
|
如果<if test>都不满足则不会插入where关键字
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Update同样适用动态sql
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<update id="updateUser" parameterType="com.crx.entity.User">
|
||||||
|
update user
|
||||||
|
<set>
|
||||||
|
<if test="username != null and username != '' ">
|
||||||
|
username = #{username}
|
||||||
|
</if>
|
||||||
|
<if test="password != null and password != ''">
|
||||||
|
,password = #{password}
|
||||||
|
</if>
|
||||||
|
where id = #{id}
|
||||||
|
</set>
|
||||||
|
</update>
|
||||||
|
```
|
||||||
|
|
||||||
|
这个例子中,*set* 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。
|
||||||
|
|
||||||
|
也相当于上面<trim>标签
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<trim prefix="SET" suffixOverrides=",">
|
||||||
|
<if test="username != null and username != '' ">
|
||||||
|
username = #{username}
|
||||||
|
</if>
|
||||||
|
<if test="password != null and password != ''">
|
||||||
|
,password = #{password}
|
||||||
|
</if>
|
||||||
|
where id = #{id}
|
||||||
|
</trim>
|
||||||
|
```
|
||||||
|
|
||||||
|
动态 SQL 的另一个常见使用场景是对集合进行遍历
|
||||||
|
|
||||||
|
|
||||||
|
Mapper接口
|
||||||
|
|
||||||
|
```java
|
||||||
|
List<User> selectUserByIds(@Param("ids") List<Integer> ids);
|
||||||
|
```
|
||||||
|
|
||||||
|
这里需要注意的是@Param注解必须加上,Mybatis内部解析参数时,会把接口中的方法形参列表当作一个Map
|
||||||
|
当参数不是一个时,key是arg0,arg1,...或param1,param2,...
|
||||||
|
```xml
|
||||||
|
<select id="selectUserByIds" resultType="com.crx.entity.User">
|
||||||
|
<include refid="selectUser"></include>
|
||||||
|
where id in
|
||||||
|
<foreach collection="ids" open="(" close=")" separator="," item="id">
|
||||||
|
#{id}
|
||||||
|
</foreach>
|
||||||
|
</select>
|
||||||
|
```
|
||||||
|
|
||||||
|
这里看到<include>标签不要慌,这是引入公共sql语句,很像Java中的引包,多用于重复的sql语句,减少代码量,增加简洁性
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<sql id="selectUser">
|
||||||
|
select id,username,password,birthday from user
|
||||||
|
</sql>
|
||||||
|
```
|
||||||
|
|
||||||
|
使用<sql>标签来定义公共sql,其中**id**属性是这个公共sql独有的命名,切忌命名不能重复
|
||||||
|
|
||||||
|
引用就看上面的集合遍历实例
|
||||||
|
|
||||||
|
再继续看集合遍历实例
|
||||||
|
|
||||||
|
先把想要生成的sql语句写上
|
||||||
|
|
||||||
|
select id,username,password,birthday from user where id in(1,2,3,5)
|
||||||
|
|
||||||
|
看到in了吧,这是包含,意思是查询id 是1,2,3,5符合条件的行
|
||||||
|
|
||||||
|
相当于 id = 1 or id =2 or id = 3 or id = 5
|
||||||
|
|
||||||
|
这里用到了<foreach>标签是不是很熟悉,确实很像JavaScript中的forEach,这个标签中**collection**属性就是需要遍历的对象名,
|
||||||
|
|
||||||
|
那么后面的**open**和**close**属性是干啥的,顾名思义,前者相当于前缀suffix,后者就是后缀了presuffix了,相当于这个<foreach>标签最终生成的sql语句前后都有(),**separator**属性每遍历出一个元素就会在元素后加上逗号最后的元素不加,**item**属性就是生成sql语句参数名
|
||||||
|
|
||||||
|
也就是往#{id}中传值
|
||||||
Loading…
x
Reference in New Issue
Block a user