mybatis的深入理解

Mybatis的三大对象的生命周期
SqlSessionFactoryBuilder

SqlSessionFactoryBuilder一旦创建了SqlSessionFactory之后就被销毁了,最佳作用域就是方法作用域就是局部方法变量

SqlSessionFactory

SqlSessionFactory一旦被创建就应该在应用运行的时候一直存在,没有理由丢弃它,除非要连接另一个数据库才会重新创建一个新的实例,在运行期间不要重复创建多次,建议放到静态代码块中

SqlSession

每个线程都应该有自己的SqlSession实例,SqlSession的实例不是线程安全的,因此是不能被共享的,所以他的它的最佳作用域是请求作用域

Mybatis的动态生成实现类

mybatis中实际上采用了代理模式,在内存中生成Dao接口的代理类,然后创建代理类的实例

Mybatis面向接口编程的两个一致

  • 映射文件的namespace和mapper接口的全类名一致
  • 映射文件中sql语句的id和mapper接口的方法名一致
Mybatis的小技巧
#{}和${}的区别

#{}:底层是使用PreparedStatement。特点:先进行SQL语句的编译,然后给SQL语句的占位符?传值

${}:底层是使用Statement。特点是先进行SQL语句的拼接,再进行SQL语句的编译

Statement存在SQL注入的现象

如果需要SQL语句的关键字放到SQL语句当中就要使用${}

#{}是以值的形式放到SQL语句当中的

批量删除

批量删除有两种方式

  • 用or的方式

    delete from t_car
    where id=1 or id=2 or id=3

  • 用in的方式

    delete from t_car
    where id in(${ids})

模糊查询
  1. 模糊查询传参数的时候要用${}接收

  2. 模糊查询还可以用concat来拼接字符串

    select *
    from t_car
    where brand like concat('%',#{brand},'%')

Mybatis的起别名

在核心配置文件当中可以添加typeAliases标签,要写在properties后面,别名不区分大小写

namespace不能用别名机制,resultType可以用别名机制

alias可以省略,省略alias的别名就是类的简名

复制代码
<typeAliases>
<typeAliase type="指定给哪个类型起别名",alias="指定别名"></typeAliase>
</typeAliases>
指定包名的方式

将这个包下的所有类都起别名,都是类的简名

复制代码
<typeAliases>
<package name=""/>
</typeAliases>
Mapper的配置

mapper的标签属性有三个

  • resource:这种方式是从类的根路径下查找文件

  • url:是从盘符下开始查找文件

  • class:提供的是mapper接口的全限定接口名,必须带有包名,如果采用这种方式,必须保证SqlMapper.xml文件和mapper接口在同一个包下

  • 在开发中一般使用package,前提是接口和xm文件必须在同一个包下,并且名字一致

    <mappers> <package name=""/> </mappers>
插入数据时获取自动生成的主键

加上 useGeneratedKeys="true"表示可以使用获取的自增的id值

keyProperty="id"表示将获取的主键赋到对象的哪个属性上

复制代码
 <insert id="insertCarUseGenerateKeys" useGeneratedKeys="true" keyProperty="id">
        insert into t_Car values (null,#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType})
    </insert>

public void insertCatUseGenerateKeysTest() throws IOException {
                SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("org/example/mapper/mybatis-config.xml"));
                SqlSession sqlSession = sqlSessionFactory.openSession();
                //获取mapper对象
                CarMapper mapper = sqlSession.getMapper(CarMapper.class);
                Car car = new Car(null,"11111","奥迪a8",200.00,"2023-12-12","新能源");
                mapper.insertCarUseGenerateKeys(car);
                sqlSession.commit();
                sqlSession.close();
                System.out.println(car);
            }

注意:mapper的方法应该和映射文件当中的sql的id对应

Mybatis的参数处理
单个简单类型参数

parameterType属性的作用是:告诉方法的参数类型是什么类型

mybatis框架自身带有类型自动推断机制,所以大部分情况下,parameterType属性是省略不写的

Map类型单个参数

当传入的是Map参数的时候,映射文件中sql语句中的#{}写的是map中的key

复制代码
<insert id="insertStudentByMap" parameterType="Map">
        insert into t_student (id,name,age,height,birth,sex) values (null,#{姓名},#{年龄},#{身高},#{出生日期},#{性别});
    </insert>

public void testInsertStudentByMap(){
        SqlSession sqlSession = SqlSessionUtils.openSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        Map<String,Object> map = new HashMap<>();
        map.put("姓名","赵六");
        map.put("年龄",18);
        map.put("身高",1.82);
        map.put("出生日期",new Date());
        map.put("性别",'男');
        mapper.insertStudentByMap(map);
        sqlSession.commit();
        sqlSession.close();
    }
实体类参数

当传入的参数是POJO实体类的时候,映射文件中的sql语句的#{}是实体类的属性

复制代码
 <insert id="insertByStudent">
        insert into t_student (id,name,age,height,birth,sex) values (null,#{name},#{age},#{height},#{birth},#{sex});
    </insert>
多个参数

mybatis框架会自动创建map集合,并且map集合是以map的方式存储参数的

map.put("arg0",name)

map.put("arg1",age)

当传入的参数是多个参数是,映射文件中的sql语句的#{}是param1,param2....,param n

或者arg0,arg1,...,argn

复制代码
<select id="selectByNameSex" resultType="Student">
        select *
        from t_student
        where name=#{param1} and sex=#{param2}
    </select>
相关推荐
花月C3 分钟前
Spring IOC:容器管理与依赖注入秘籍
java·开发语言·rpc
ylfhpy9 分钟前
Java面试黄金宝典22
java·开发语言·算法·面试·职场和发展
..过云雨34 分钟前
11. 【C++】模板进阶(函数模板特化、类模板全特化和偏特化、模板的分离编译)
开发语言·c++
风象南42 分钟前
Spring Boot 实现文件秒传功能
java·spring boot·后端
橘猫云计算机设计43 分钟前
基于django优秀少儿图书推荐网(源码+lw+部署文档+讲解),源码可白嫖!
java·spring boot·后端·python·小程序·django·毕业设计
黑猫Teng1 小时前
Spring Boot拦截器(Interceptor)与过滤器(Filter)深度解析:区别、实现与实战指南
java·spring boot·后端
星河浪人1 小时前
Spring Boot启动流程及源码实现深度解析
java·spring boot·后端
佩奇的技术笔记1 小时前
中级:Maven面试题精讲
java·面试·maven
予安灵1 小时前
一文详细讲解Python(详细版一篇学会Python基础和网络安全)
开发语言·python
Lizhihao_1 小时前
JAVA-堆 和 堆排序
java·开发语言