MyBatis (底层是基于JDBC的)是⼀款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 去除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。它是一个ORM(对象关系映射框架–通过操作程序中的类和对象,来间接的操作数据库中的表和字段)
简单来说 MyBatis 是更简单完成程序和数据库交互的工具(框架),也就是更简单的操作和读取数据库工具(框架)
这里我用的是mysql
进去之后把下面四个删了
然后右键下图的步骤1,点击步骤2
然后删除 .RELEASE
删除完了之后点击
到这里了之后,启动还是会报错,因为没给程序说明具体是哪个数据库,比如mysql数据库,我的电脑有一台,我的腾讯云也有一个,程序不知道连接哪个
#设置数据库的相关链接信息
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mycnblog?characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=021018
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#设置 Mybatis 的 xml 保存路径
mybatis.mapper-locations=classpath:mybatis/*Mapper.xml
#配置mybatis执行时打印sql语句(可选配置,且以下两句需要联合出现,否则没有用)
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
logging.level.com.example.demo=debug
# 将数据库中的下换线转换成驼峰,比如 user_name -> userName
mybatis-plus.configuration.map-underscore-to-camel-case=true
常规的写法包含两个文件
1.接口:方法的定义(声明)(给其他层(service)调用)
先创建一个接口
2.XML:实现接口
在这个包底下创建xml文件,文件名字必须叫xxxMapper.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.example.demo.mapper.UserMapper">
</mapper>
DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.dao.UserMapper">
<select id="getAll" resultType="com.example.demo.model.Userinfo">
select * from userinfo
select>
mapper>
namespace是关联你要实现的接口的
id就是你要实现的接口方法,resultType就是你要返回的数据类型
到这里就写完了,那么我们写的生效了吗?用单元测试来写一下
在你想测试的类或接口的页面右键,选generate,点test
测试类代码如下
@SpringBootTest
//这个注解不能省略,是告诉当前的测试程序,目前项目是运行在spring boot容器中的
class UserMapperTest {
@Autowired
private UserMapper userMapper;
@Test
void getAll()
{
List<Userinfo> list=userMapper.getAll();
System.out.println(list);
}
}
为了方便开发MyBatis,实现xml和对应的接口之间的快速跳转,咱们可以安装一个MyBatisX插件
装完了之后
接口代码
@Mapper
//Mapper是数据持久层的标志,代替了五大类注解中的Repository
//添加了Mapper就变成了mybatis的interface了
public interface UserMapper
{
//查询全部
List<Userinfo> getAll();
//根据id查询user
//这里传到最好用包装类来接收,因为包装类接受空值
//@Param("id")最好加上,如果不加的话,10个人有9个人可以通过,但是总有一个是通过不了的
Userinfo getUserById(@Param("id") Integer id);
}
xml配置
DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.dao.UserMapper">
<select id="getAll" resultType="com.example.demo.model.Userinfo">
select * from userinfo
select>
<select id="getUserById" resultType="com.example.demo.model.Userinfo">
select * from userinfo where id=${id}
#这个${id}对应的是@Param("id")
select>
mapper>
xml的配置还可以
第一种配置
及时执行
第二种配置
预执行
测试代码
class UserMapperTest {
@Autowired
private UserMapper userMapper;
@Test
void getAll()
{
List<Userinfo> list=userMapper.getAll();
System.out.println(list);
}
@Test
void getUserById()
{
Userinfo userinfo=userMapper.getUserById(1);
System.out.println(userinfo.toString());
}
}
预执行相比于及时执行来说最大的好处就是它的执行是安全的,防止sql注入
什么是sql注入呢?
就是通过非法,非正规手段获取到数据库的相关信息,见下图,密码应该是admin,但是我输入的不是admin还是能获取到正确的密码
说明如果使用的是$,那么就可以用这个命令登录任何系统
下面用另一种方式进行sql语句的查询,不是用xml了,是用注解了
使用动态sql的目的就是有时候一个字段对应的值,我想让它没有,但是如果不使用动态sql,就得把这个字段对应的值赋成null,有动态sql我就可以只给我想赋的字段赋值,不想赋的字段不管就行
比如有三个字段id name password
有动态sql values(1,‘小白’)
没有动态sql values(1,‘小白’,null)
<insert id="add2">
insert into userinfo(username,password
<if test="photo!=null">
,photo
if>
)values(#{username},#{password}
<if test="photo!=null">
,#{photo}
if>
)
insert>
比如这三个字段都是可有可无的,就用trim标签
<insert id="add3">
insert into userinfo
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="username!=null">
username,
if>
<if test="password!=null">
password,
if>
<if test="photo!=null">
photo,
if>
trim>
values
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="username!=null">
#{username},
if>
<if test="password!=null">
#{password},
if>
<if test="photo!=null">
#{photo},
if>
trim>
insert>
prefix:表示整个语句块,以prefix的值作为前缀
suffix:表示整个语句块,以suffix的值作为后缀
prefixOverrides:表示整个语句块要去除掉的前缀
suffixOverrides:表示整个语句块要去除掉的后缀
上述xml代码基于 prefix 配置,开始部分加上 (
基于 suffix 配置,结束部分加上 )
多个 组织的语句都以 , 结尾,在最后拼接好的字符串还会以 , 结尾,会基于 suffixOverrides 配置去掉最后⼀个 ,
配合where查询来用的,如果where标签里面有东西,标签就会生成一个where来查询标签里面的东西,如果where标签里面的字段都是空的,就不会生成where来查询了,就是全表select查询
<select id="getAllByWhere" resultType="com.example.demo.model.Userinfo">
select * from userinfo
<where>
<if test="id>0">
id=#{id}
if>
<if test="username!=null">
and username=#{username}
if>
<if test="password!=null">
and password=#{password}
if>
<if test="photo!=null">
and photo=#{photo}
if>
where>
select>
假如id没传过来,只传了username,也不会报错,因为where标签会自动的把前面的and去掉,因此如果想加and,只能按照上述代码这样加
上述代码等同于下图代码
用来修改用户的
<update id="update2">
update userinfo
<set>
<if test="username!=null">
username=#{username},
if>
<if test="password!=null">
password=#{password},
if>
<if test="photo!=null">
photo=#{photo}
if>
set>
where id=#{id}
update>
set标签可以自动去除最后一个逗号
配合删除语句来使用的
int deleteByIds(List<Integer> ids);
下面代码的collection的ids要跟上面的一样
<delete id="delByIds">
delete from userinfo
where id in
<foreach collection="ids" open="(" close=")" item="id" separator=",">
#{id}
foreach>
delete>
上面这段代码类似
delete from userinfo where id in(1,2,3,4);