• [JAVAee]MyBatis


    目录

    MyBatis简介

    MyBatis的准备工作 

    框架的添加

    连接数据库字符串的配置

    MyBatis中XML路径的配置

    ​编辑 MyBatis的使用

    各层的实现 

    进行数据库操作

    增加操作

    拓展 

    修改操作

    删除操作

    查询操作 

    结果映射

    单表查询

    多表查询 

    like模糊查询

    动态SQL

     

     /


    MyBatis简介

    MyBatis是基于JDBC的一个工具框架,能够更好帮助程序与数据库进行交互,也能更方便的进行数据库中数据的存储与读取.

    MyBatis是一个ORM(Object Relational Mapping)框架,ORM即是对象关系映射.在编程语言中,将关系型数据库中的数据与对象建立映射关系,更方便的完成数据与对象间的转换.

    一般的ORM映射关系:

     在加入了Mybatis的项目中,一般会为一张表创建一个类并进行映射,就使得像平常操作对象一般操作数据库中的数据.

    MyBatis的准备工作 

    框架的添加

    在项目中添加Mysql数据库与MyBatis相关的框架.

    如果是老的项目可以使用EditStarters插件进行添加 

    连接数据库字符串的配置

    在项目的配置文件中对数据库的连接进行配置,此处使用的是yml类型的配置文件.主要是作用是将项目与数据库能够进行连接.

    记得对URL中的目标数据库进行修改.

    1. spring:
    2. datasource:
    3. url: jdbc:mysql://localhost:3306/test1?characterEncoding=utf8&useSSL=false #连接数据库的地址
    4. username: root #数据库的用户名
    5. password: #数据库的密码
    6. driver-class-name: com.mysql.cj.jdbc.Driver

     将上述代码放置到yml配置文件中

    注意事项 :

     检查mysql-connector-java的版本号,如果是 5.x 之前的使⽤的“com.mysql.jdbc.Driver”,如果是⼤于 5.x使⽤的是“com.mysql.cj.jdbc.Driver”

    MyBatis中XML路径的配置

    在resources的目录下创建一个目录(此处我命名为mybatis).

    并在项目的配置文件中将刚刚创建的目录添加到mybatis的xml路径

    最终配置文件大致为:

     MyBatis的使用

     一般的业务的后端开发思路为:

     我们只要跟着上面的开发思路来写代码就好了.

    注意:

    下面所创建的所有类都要跟启动类放到同一个文件夹之中.

    各层的实现 

    创建实体类

    映射到一个数据库中的表.

    1. @Data
    2. public class User {
    3. private String name;
    4. private int age;
    5. private int id;
    6. private String sex;
    7. }

    创建Serveric类

    1. @Service
    2. public class UserService {
    3. @Autowired
    4. UserMapper userMapper;
    5. public User getUserByName(String name){
    6. return userMapper.getUserByName(name);
    7. }
    8. }

    创建Controller类

    1. @Controller
    2. public class UserController{
    3. @Autowired
    4. UserService userService;
    5. public User getUserByName(String name){
    6. return userService.getUserByName(name);
    7. }
    8. }

    创建Mapper

    Mapper的组成为接口+XML

    1. @Mapper
    2. public interface UserMapper {
    3. User getUserByName(@Param("name") String name);
    4. //使用Param注解,将接口方法中的参数设置成为xml中传输的参数(不写也可以,写了更严谨可以尽量避免出现bug)
    5. }

    在之前的配置文件中配置mybatis的xml的目录中创建一个对应的xml 

    (将下面的代码拷贝,更改对应的mapper标签中的namespace.在mapper标签中写上对应的sql语句)

    1. "1.0" encoding="UTF-8"?>
    2. mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybati
    3. s.org/dtd/mybatis-3-mapper.dtd">
    4. <mapper namespace="com.example.demo.Mapper.UserMapper">
    5. mapper>

    mapper标签中需要指定namespace属性,表示命名空间,为mapper接口的全限定名(包名+类名)去指定一个mapper. 

    进行数据库操作

    对应表的创建语句:

    1. create table Users(name varchar(15),
    2. age int,
    3. id int primary key auto_increment,
    4. sex varchar(6));

    在MyBatis中的SQL语句都在XML文件中搭配对应的标签来实现.

    可以在SpringBoot项目的配置文件中设置Mapper类的日志等级为debug,这样就可以在控制台中查看数据库操作的预处理语句,参数和受影响的行数了.

    (此处为yml类型配置文件的语句) 

    1. mybatis:
    2. mapper-locations: classpath:mybatis/*Mapper.xml
    3. configuration:
    4. log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    5. logging:
    6. level:
    7. com.example.demo.Mapper: debug //此处是类的路径 + 日志的等级

    增加操作

    增加操作使用标签实现

    controller类

    1. @ResponseBody//记得添上@ResponseBody,表明返回的是一个数据而不是页面
    2. @PostMapping("/add")//POST由客户端上传数据至服务器
    3. public Integer add(@RequestBody User user){//@RequestBody标签将方法中的user参数获取请求body中的json格式
    4. return userService.add(user);
    5. }

    Service类

    1. public Integer add(User user){
    2. return userMapper.add(user);
    3. }

    Mapper

    最好要使用Integer做返回值噢

    1. //增加操作,返回受影响的行数
    2. //返回类型为Integer而不是int,是因为int的默认值为0,Integer的默认值为null
    3. //使用int就不知道语句是否对数据库造成了影响,
    4. //Integer可以区分未赋值与受影响行数为0的区别
    5. Integer add(User user);

    xml

    1. "1.0" encoding="UTF-8"?>
    2. mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybati
    3. s.org/dtd/mybatis-3-mapper.dtd">
    4. <mapper namespace="com.example.demo.Mapper.UserMapper">
    5. <insert id="add">
    6. insert into Users(name,age,sex) values(#{name},#{age},#{sex});
    7. insert>
    8. mapper>

    可以看到返回值为受影响的行数. 

    拓展 

    返回受影响的行数据的主键

    当我们在某些情况下想要获取对应的主键,可以在insert标签上进行设置.

    useGeneratedKeys : 使用主键,默认值为false,

    keyProperty : 主键的属性名为(实体类中的属性)

    1. <insert id="add" useGeneratedKeys="true" keyProperty="id">
    2. insert into Users(name,age,sex) values(#{name},#{age},#{sex});
    3. insert>

     然后我们就可以直接在方法中使用对象的主键属性了,先前都是默认自增值没有对其进行赋值,

    1. @ResponseBody//记得添上@ResponseBody,表明返回的是一个数据而不是页面
    2. @PostMapping("/add")//POST由客户端上传数据至服务器
    3. public Integer add(@RequestBody User user){//@RequestBody标签将方法中的user参数获取请求body中的json格式
    4. Integer ret = userService.add(user);
    5. System.out.println("UserID为:" + user.getId());
    6. return ret;
    7. }

    修改操作

    使用标签 

    由于Controller类与Service类都大差不大就不展示啦. 

     Mapper

    Integer update(User user);
    1. <update id="update">
    2. update Users set age = #{age} where name = #{name};
    3. update>

    删除操作

    删除操作使用标签

    Mapper

    Integer delete(User user);
    1. <delete id="delete">
    2. delete from Users where id = #{id};
    3. delete>

    查询操作

    结果映射

    在上述的增加,删除以及修改操作中,一般的默认的返回值为受影响的行数.但其实可以不使用映射来接收这个参数的.

    但对于查询操作来说,不得不接收返回的参数,不然会进行报错.

    而在MyBatis中,实现结果映射的标签一共有两种返回类型与返回字典映射

    返回类型

    此标签能够适用于绝大多数的场景,其中resultType表明要返回的类型.

    可以是一个类,也可以的基本类型或引用类型.

    其中的resultType值可以为类名,或"string"或"java.lang.String"或"int"或"java.lang.Integer"...

    因为标签的使用比较麻烦也以及不常用了,就不再此处介绍了

    单表查询

    将Controller类的标签更改为get方法,并使用表单传输信息. 

    User getNameById(@Param("id") Integer id);
    1. <select id="getNameById" resultType="com.example.demo.model.User">
    2. select name from Users where id = #{id};
    3. select>
    多表查询 

    使用多表查询获取一对多,使用List来接收多个对象.但注意xml中的返回类型是单个对象的类型 

    Mapper

    List get(String name);

    XML 

    1. <select id="get" resultType="com.example.demo.model.VO.BookVO">
    2. select title,author_id,name from books left join Users on books.author_id = Users.id where Users.name = #{name};
    3. select>

    like模糊查询

    因为使用#{}会进行预处理编译,会把数据自动的加上单引号  zhangsan -> 'zhangsan'

    如果直接使用模糊查询, like  '%#{name}%' 就会变成  ->  like '%'name'%' 显然是错误的,但如果使用${}字符串替换又会有sql注入的风险,

    所以我们可以使用concat方法对%与参数进行连接.

    1. <select id="getByName" resultType="com.example.demo.model.User">
    2. select * from Users where name like concat('%',#{name},'%');
    3. select>
    动态SQL

    我们之前可能在遇到过,填写个人信息表单的时候会出现非必填项.

    此处就可以使用标签来实现非必填项的方式

    当我们填写name,age却不想写填写sex的时候,就可以使用标签来拼接SQL语句

    Mapper: 

    Integer add2(User user);

    XML: 

    1. <insert id="add2">
    2. insert into Users(name,age<if test="sex != null">,sexif>) values(#{name},#{age}<if test="sex != null">,#{sex}if>);
    3. insert>

    其中标签中的test属性填写的是传输参数的判断语句,sex是user对象的属性并非数据库中的字段.

    如果传输的user对象中sex属性为空,则不填写标签中的字符.

     对应的,因为标签的作用,预处理后的语句也没有出现sex字段

     

    上面的例子为单个非必填选项,那如果我每一个都是非必填呢?

    因为SQL语句中字段间的分隔需要逗号来实现,所以单单依靠于标签来实现是不可行的,这时候就出现了另一种标签:

    标签与标签搭配使用适用于多个字段都是非必填的场景.

    标签中有如下属性:

    • prefix:表示整个语句块,以prefix的值作为前缀
    • suffix:表示整个语句块,以suffix的值作为后缀
    • prefixOverrides:表示整个语句块要去除掉的前缀
    • suffixOverrides:表示整个语句块要去除掉的后缀  
    1. <insert id="add2">
    2. insert into Users
    3. <trim prefix="(" suffix=")" suffixOverrides=",">
    4. <if test="name != null">name,if>
    5. <if test="age != null">age,if>
    6. <if test="sex != null">sex,if>
    7. trim>
    8. <trim prefix="values (" suffix=")" suffixOverrides=",">
    9. <if test="name != null">#{name},if>
    10. <if test="age != null">#{age},if>
    11. <if test="sex != null">#{sex},if>
    12. trim>
    13. insert>

    在使用标签之后可传输的数据就会变得很灵活了 

     /

    其中还有这两个标签,其实这两个标签都是的变形

    也是同样的,只是等价于

    对集合进⾏遍历时可以使⽤该标签。标签有如下属性:

    • collection:绑定⽅法参数中的集合,如 List,Set,Map或数组对象
    • item:遍历时的每⼀个对象
    • open:语句块开头的字符串
    • close:语句块结束的字符串
    • separator:每次遍历之间间隔的字符串
    1. <delete id="deleteByIds">
    2. delete from article
    3. where id in
    4. <foreach collection="list" item="item" open="(" close=")" separator=",">
    5. #{item}
    6. foreach>
    7. delete>

    就像java里的foreach遍历一样.

    传输数组进行调试

    预处理后的样子:

     

    TIPS:

    在后端类的属性与数据库中字段名不相同时,可以在SQL语句中使用as为字段起别名

    1. <select id="getId" resultType="com.example.demo.model.Book">
    2. select author_id as authorID,title,content from books where title = #{title};
    3. select>


     

  • 相关阅读:
    random—生成随机数,time—时间标准库
    打印星堆(for循环嵌套实例)
    Java基础知识面试题
    谷粒商城10——分布式缓存Redis 分布式锁Redisson SpringCache自定义缓存配置
    uniapp编译微信小程序富文本rich-text的图片样式不生效原因
    电脑系统还原怎么操作?
    【游戏测试工程师】初识游戏测试—你了解它吗?
    C++入门(1)
    会议邀请 | 思腾合力邀您共赴PRCV 2023第六届中国模式识别与计算机视觉大会
    ToBeWritten之评估数据质量
  • 原文地址:https://blog.csdn.net/weixin_67719939/article/details/133238953