• MyBatis


    简介

    作用于Dao层上的数据库操作框架,底层用的JDBC,是JDBC的改进升级版。

    MyBatis相比JDBC
    无需自行管理Connection、statement的关闭。
    读取数据库字段更为简便,直接返回对象集合。
    配置信息解耦,存放与xml文件中,修改配置时无需重新编译程序。

    使用步骤

    1. 在创建module时引入mybatis框架、Mysql驱动。
    2. 在resources/application.properties文件中设置数据源
    spring.datasource.driver-class-name= com.mysql.cj.jdbc.Driver
    spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test
    spring.datasource.username=root
    spring.datasource.password=123456
    
    mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl //展示sql具体操作日志,打印到STDOUT
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    1. 创建实体类,设置get/set方法。
    2. 创建Mapper接口,标记相关注解,springboot会自动生成实现类对象。
    @Mapper //自动生成Mapper接口的实现类对象,并交给IOC容器管理
    public interface UserMapper {
        @Select("select * from user")
        List<User> getUsers();
        @Delete("delete from user where uid =#{id}") 
        public int deleteById(Integer id );
    	@Options(useGeneratedKeys = true,keyProperty = "uid") //获取插入结果中数据库自动生成的主键
        @Insert("insert into user values(#{uid},#{name},#{password},#{birthday},#{salary})")//这里指User对象中的uid...
        public int insertInto(User user);
        @Update("update user set name=#{name},password=#{password},birthday=#{birthday},salary=#{salary} where uid=#{uid}")
        public int updateUser(User user);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    其中#{}占位符生成预编译sql,${}占位符生成拼接sql,存在注入安全问题。
    需要注意在select时,实体类的属性需要与数据库中的字段名相同,如果不同可以通过以下几种方式解决:

    • 给sql语句中的字段取别名
    • @Results/@Result配合手动映射封装
    • 在appliacation.properties中配置mybatis.configuration.map-underscore-to-camel-case=true(自动将user_name->userName)
    1. 在使用时直接通过@Autowire注入UserMapper接口进行数据访问。

    动态sql

    在sql查询时有时仅按uid进行查询,有时通过uid、name同时进行查询,Mybatis在XML文件中提供了where、if标签进行动态查询。

    if标签:如果满足test中的判断条件,会将if标签内的sql语句拼接到查询sql中。
    where标签:自动判断where后面是否有拼接的字段并识别去除多余的and和or,如果where后没有字段了则sql语句为select* from user;
    set标签:去除set关键字后多余的逗号

     	<select id="getUser" resultType="com.yi.mybatis_demo.domain.User">
            select * from user
           <where>
            <if test="uid!=0">
                uid=#{uid}
            if>
            <if test="name!=null">
                and name=#{name}
            if>
            where>
        select>
       
       <update id="updateUser">
            update user
            <set>
                <if test="name!=null">name=#{name},if>
                <if test="password!=null">password=#{password},if>
                <if test="birthday!=null">birthday=#{birthday},if>
                <if test="salary!=0">salary=#{salary}if>
            set>
            where
                uid=#{uid}
        update>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    使用foreach标签遍历集合删除删除元素

    foreach标签可以遍历集合中的元素,并将元素拼接成sql语句

    foreach属性
    collection:遍历的集合
    separator:拼接时的分隔符
    open/close:添加开始和结束的字符
    item:依次遍历出来的元素/项

    Mapper方法:

    public int deleteByList(List<Integer>Ids);
    
    • 1
    //XML:  delete from user where uid in (item1,item2...)
    <delete id="deleteByList">
            delete from user
            where uid in
                <foreach collection="Ids" separator="," open="(" close=")" item="id">
                    #{id}
                foreach>
        delete>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    sql、include标签

    sql标签:将常用sql语句使用id变量保存
    include标签:引用sql标签保存的sql语句

    	<sql id="selectCommon">
            select name,password from user
        sql>
        <select id="getAccount">
            <include refid="selectCommon"/>
            where uid=#{uid}
        select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    事务

    加入@Transactional即可开启事务自动提交。
    @Transactional注解默认只会回滚RuntimeException,如果要选择回滚所有异常需要配置Rollbackfor属性

    @Transactional(rollbackFor = Exception.class)
    
    • 1

    事务传播配置:
    在带有@Transactional的A方法中调用带有@Transactional的B方法,是创建新的事物还是加入到原来的事物中?

    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    
    • 1

    Propagation.REQUIRED(默认) :需要事物,如果调用者已经存在事物则加入到之前的事物中,如果没有则创建新的事物。

    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
    
    • 1

    Propagation.REQUIRES_NEW:创建新的事物
    应用场景:删除时无论成功/失败都需要记录日志,记录日志应该新开一个事物

    切换连接池

    Mybatis默认连接池为hikari(追光者),可以将其切换成druid实现

    1.引入配置文件

       <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>1.2.19</version>
            </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.在application.properties中加入连接池配置

    spring.datasource.driver-class-name= com.mysql.cj.jdbc.Driver
    
    • 1

    lombok工具:简化实体类定义

    在每次构建实体类时都需要进行定义get/set方法、重新toString方法等等,这样定义的类会非常的冗长,lombok框架可以通过注解进行着一系列操作。

    @Getter/Setter 为所有属性设置get/set方法
    @ToString 设置易读的toString方法
    @EqualsAndHashCode 根据类中非静态字段重写equals方法与hashCode方法
    @Data =@Getter+@Setter+@ToString+@EqualsAndHashCode
    @NoArgsConstructor 提供默认无参构造
    @AllArgsConstructor 根据非静态字段提供有参构造

    引入配置文件(可以不进行,idea可以自动导入)

    在pom.xml中加入

       <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>3.0.2</version>
        </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    修改之前的实体类:

    
    public class User {
        private Integer uid;
        private String username;
        private String password;
    
        public User(Integer uid, String username, String password) {
            this.uid = uid;
            this.username = username;
            this.password = password;
        }
    
        public Integer getUid() {
            return uid;
        }
    
        public void setUid(Integer uid) {
            this.uid = uid;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "uid=" + uid +
                    ", username='" + username + '\'' +
                    ", password='" + password + '\'' +
                    '}';
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    修改后的实体类:

    @AllArgsConstructor
    @Setter
    @Getter
    @ToString
    public class User {
        private Integer uid;
        private String username;
        private String password;
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    或者使用@Data注解(=@Getter+@Setter+@ToString+@EqualsAndHashCode)

    @AllArgsConstructor
    @Data
    public class User {
        private Integer uid;
        private String username;
        private String password;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
  • 相关阅读:
    Sqlite 安装操作使用
    【string题解 C++】翻转字符串II:区间部分翻转 | 验证回文串
    自然语言处理(扩展学习1):Scheduled Sampling(计划采样)与Teacher forcing(教师强制)
    面试必问 | 一个线程从创建到消亡要经历哪些阶段?
    2024腾讯游戏安全技术竞赛-机器学习赛道
    Python 和 Ruby 谁是最好的Web开发语言?
    【Nginx 原理】进程模型、HTTP 连接建立和请求处理过程、高性能、高并发、事件处理模型、模块化体系结构
    新大陆!阿里 P9 整理出:Java 架构师“成长笔记”共计 23 版块
    函数基础学习01
    C++string—常用接口介绍+模拟实现+习题讲解
  • 原文地址:https://blog.csdn.net/weixin_44866921/article/details/133513519