• MyBatis内容分析


    1.半自动与全自动的区别,MyBatis与Hibrnate的区别:

    需要手动编写 sql 来完成,称之为半自动 ORM 映射工具。

    查询关联对象或者关联集合对向象时,可以根据对象关系模型直接获取,称为orm的全自动。

    他们之间的区别在于sql语句是需要手动编写还是自动获取。

            Mybatis 在查询关联对象或关联集合对象时,需要手动编写 sql 来完成,所以,称之为半自动 ORM 映射工具。

     Hibernate属于全自动 ORM 映射工具,使用 Hibernate 查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。

    1> MyBatis 把 sql 语句从 Java 源程序中独立出来,放在单独的 XML 文件中编写,给程序的
    维护带来了很大便利。
    2> MyBatis 封装了底层 JDBC API 的调用细节,并能自动将结果集转换成 Java Bean 对象,
    大大简化了 Java 数据库编程的重复工作。
    3> 因为 MyBatis 需要程序员自己去编写 sql 语句,程序员可以结合数据库自身的特点灵活
    控制 sql 语句,因此能够实现比 Hibernate 等全自动 orm 框架更高的查询效率,能够完成复
    杂查询。

    hibernate和mybatis对比
    1相同之处
    Hibernate和mybatis都是属于持久层框架(操作数据库的框架).
    操作数据库的底层都是使用的JDBC.
    并且都是ORM类型的框架.
    通过操作对象,映射操作数据库的表。
    2不同之处
    映射关系不同:
    Hibernate:
    实体类对象 =对应=> 数据库的表
    对象的属性 =对应=> 表的列
    MyBatis:
    表dao =对应=> 映射文件
    表dao中的方法 =对应=> 映射文件中的sql语句
     

    2.了解orm框架

            对象关系映射简称ORM(Object Relational Mapping)框架采用元数据来描述对象与关系映射的细节,元数据一般采用XML格式,并且存放在专门的对象一映射文件中。简单理解为一种框架的格式。

            它是是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用的“虚拟对象数据库”。

            只要提供了持久化类与表的映射关系,ORM框架在运行时就能参照映射文件的信息,把对象持久化到数据库中。当前ORM框架主要有五种:Hibernate、iBatis、mybatis、JFinal、EclipseLink。

            简单来说ORM框架就是连接数据库的桥梁,就是将数据库类型转换成面向对象编程语言的类型,可以理解为“翻译”。

    3.动态sql:一对一、一对多、多对多

    动态SQL:

    sql的内容是变化的, 可以根据条件获取到不同的sql语句。

    主要是where部分发生变化。

    动态sql的实现, 使用的是mybatis提供的标签。

    一对一表查询:

    一对一的关系就是:一个商品对应一个商品种类。所以我们创建实体类的时候,可以这么创建:

    1. public class Goods {
    2. private int id;
    3. private int imgId;
    4. private String name;
    5. private String content;
    6. private int status;
    7. private String createTime;
    8. private String updateTime;
    9. private Category category;
    10. }

    然后我们在对应的Dao接口方法里定义函数:

    1. public interface GoodCategoryDao {
    2. public List findAllGoodsWithCate();
    3. }

    书写sql语句:

    1. <select id="findAllGoodsWithCate" resultMap="GoodsWithCate">
    2. select a.*,b.category_name from goods a join category b on a.category_id=b.category_id
    3. </select>

    通过category_id 字段相同来建立两个表一一对应的关系。

    一对多表查询:  一对多的场景为:一个商品类型对应了多个商品:

       所以我们建立实体类可以在商品类型实体类里边添加一个goods集合:

    1. public class Category {
    2. private int categoryId;
    3. private String categoryName;
    4. private List goodsList;
    5. }

    然后去添加dao接口方法和xml实现方法:

    1. public interface GoodCategoryDao {
    2. public List findAllGoodsWithCate();
    3. public List findAllCateWithGoods();
    4. }

    Select方法:

    1. <select id="findAllCateWithGoods" resultMap="CateWithGoods">
    2. select b.*,a.* from goods a right join category b on a.category_id=b.category_id
    3. </select>

    动态sql拼接:

    1. <select id="findStudentByCondition" resultType="Student">
    2. select * from student where 1=1
    3. <if test="sName!=null">
    4. and s_name like #{sName}
    5. </if>
    6. <if test="sSex!=null">
    7. and s_sex =#{sSex}
    8. </if>
    9. </select>

    多对多:涉及到三张表如下:

    sys_role

     sys_user

    sys_role_user

     

     通过sys_role_user表查询每个用户的职称

    主方法:

    1. public List<User> list() {
    2. List<User> userList = userDao.findAll();
    3. for (User u : userList){
    4. Long id = u.getId();
    5. List<Role> roleList = roleDao.findById(id);
    6. u.setRoles(roleList);
    7. }
    8. return userList;
    9. }

    dao层 fundAll()

    1. public List<User> findAll() {
    2. return jdbcTemplate.query("select * from sys_user", new BeanPropertyRowMapper(User.class));
    3. }

    dao层 findById(id)

    1. public List<Role> findById(Long id) {
    2. List<Role> query = jdbcTemplate.query("select * from sys_user_role ur, sys_role r where ur.roleId = r.id and ur.userId = ?", new BeanPropertyRowMapper<Role>(Role.class), id);
    3. return query;
    4. }

    查询结果:

    4.mybatis中#与$的区别

    #占位符:

    1> MyBatis处理 #{ } 占位符,使用的 JDBC 对象是PreparedStatement 对象,执行sql语句的效率更高。

    2> 使用PreparedStatement 对象,能够避免 sql 注入,使得sql语句的执行更加安全。

    3> #{ } 常常作为列值使用,位于sql语句中等号的右侧;#{ } 位置的值与数据类型是相关的。
    4> #传入的参数在SQL中显示为字符串(当成一个字符串),会对自动传入的数据加一个双引号。如下:

    1. select id,name,age from student where id =#{id}
    2. select id,name,age from student where id ="1"

    $占位符:

    1> MyBatis处理 ${ } 占位符,使用的 JDBC 对象是 Statement 对象,执行sql语句的效率相对于 #{ } 占位符要更低。

    2> ${ } 占位符的值,使用的是字符串连接的方式,有 sql 注入的风险,同时也存在代码安全的问题。

    3> ${ } 占位符中的数据是原模原样的,不会区分数据类型。

    4> ${ } 占位符常用作表名或列名,这里推荐在能保证数据安全的情况下使用 ${ }。
    5>$传入的参数在SqL中直接显示为传入的值。如下:

    1. select id,name,age from student where id =${id}
    2. select id,name,age from student where id =1

    5.MyBatis缓存

            MyBatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存,默认情况下,只有一级缓存默认开启。二级缓存需要手动开启和配置,他是基于namespace级别的缓存。一级缓存被称为sqlSession级别的缓存, 二级缓存被称为表级缓存。


    一级缓存:

            MyBatis的一级缓存默认是开启的,它在一个sqlSession会话里面的所有查询操作都会保存到缓存中,一般来说一个请求中的所有增删改查操作都是在同一个sqlSession里面的,所以我们可以认为每个请求都有自己的一级缓存,如果同一个sqlSession会话中2个查询中间有一个 insert 、update或delete 语句,那么之前查询的所有缓存都会清空。

            使用MyBatis开启一次和数据库的会话,MyBatis会创建出一个SqlSession对象表示一次数据库会话,在对数据库的一次会话中, 有可能会反复地执行完全相同的查询语句,每一次查询都会去查一次数据库,为了减少资源浪费,mybaits提供了一种缓存的方式(一级缓存)。

    二级缓存:

            二级缓存是全局的,也就是说;多个请求可以共用一个缓存,二级缓存需要手动开启。二级缓存针对的是同一个namespace,所以建议是在单表操作的Mapper中使用,或者是在相关表的Mapper文件中共享同一个缓存。一级缓存无过期时间,只有生命周期,缓存会先放在一级缓存中,当sqlSession会话提交或者关闭时才会将一级缓存刷新到二级缓存中;开启二级缓存后,用户查询时,会先去二级缓存中找,找不到在去一级缓存中找,然后才去数据库查询;
     

    6.分页查询插件

    使用分页助手插件有三个步骤:

    1> 导入pagehelper坐标

    1. <dependency>
    2. <groupId>com.github.pagehelper</groupId>
    3. <artifactId>pagehelper</artifactId>
    4. <version>5.3.2</version>
    5. </dependency>

    2> 在核心配置文件中配置pageHelper

    1. <plugins>
    2. <plugin interceptor="com.github.pagehelper.PageInterceptor">
    3. <!--设置方言-->
    4. <property name="helperDialect" value="mysql"/>
    5. </plugin>
    6. </plugins>

    3> 测试

    1. //设置分页相关参数
    2. //pageNum 第几页 pageSize 一页多少条数据
    3. PageHelper.startPage(2,3);
    4. List<User> all = mapper.findAll();
    5. for (User u : all) {
    6. System.out.println(u);
    7. }

    4> 一些相关的API

    1. // 获取与分页相关参数
    2. PageInfo<User> pageInfo = new PageInfo<User>(all);
    3. System.out.println("当前页:"+pageInfo.getPageNum());
    4. System.out.println("每页显示的条数:"+pageInfo.getPageSize());
    5. System.out.println("总条数:"+pageInfo.getTotal());
    6. System.out.println("总页数:"+pageInfo.getPages());
    7. System.out.println("上一页:"+pageInfo.getPrePage());
    8. System.out.println("下一页:"+pageInfo.getNextPage());
    9. System.out.println("是否是第一个:"+pageInfo.isIsFirstPage());
    10. System.out.println("是否是最后一个:"+pageInfo.isIsLastPage());
    11. System.out.println("所有参数信息:"+pageInfo.toString());

    7.延时加载

            MyBatis中的延迟加载,也称为懒加载,是指在进行关联查询时,按照设置延迟规则推迟对关联对象的select查询。延迟加载可以有效的减少数据库压力。

    延迟加载类型及设定:通过对全局参数:lazyLoadingEnabled进行设置,默认就是false。 进行设置修改延时加载状态。

    直接加载: 执行完对主加载对象的select语句,马上执行对关联对象的select查询。

    1. <settings>
    2. <setting name="lazyLoadingEnabled" value="false"/>
    3. settings>

    侵入式延迟:执行对主加载对象的查询时,不会执行对关联对象的查询。但要访问主加载对象的

    某个属性(该属性不是关联对象的属性)时,就会马上执行关联对象的select查询。

    1. <settings>
    2. <setting name="lazyLoadingEnabled" value="true"/>
    3. <setting name="aggressiveLazyLoading" value="true"/>
    4. settings>

    深度延迟:执行对主加载对象的查询时,不会执行对关联对象的查询。访问主加载对象的详情时也不会执行关联对象的select查询。只有当真正访问关联对象的详情时,才会执行对关联对象的select查询。

    1. <settings>
    2. <setting name="lazyLoadingEnabled" value="true"/>
    3. <setting name="aggressiveLazyLoading" value="false"/>
    4. settings>

  • 相关阅读:
    无线AC802.1X认证配置
    【网络安全】护网
    Pytorch使用c++调用模型
    python编程题3
    母婴行业探秘:千万级会员体量下的精准营销
    清华chatGLM2-6B windows本地安装教程
    云原生容器技术入门:Docker、K8s技术的基本原理和用途
    【考研线代】六. 二次型
    Math对象常用的方法
    关于本地项目上传到gitee的详细流程
  • 原文地址:https://blog.csdn.net/m0_59123620/article/details/127674301