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提供的标签。

一对一表查询:

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

public class Goods {
  private int id;
  private int imgId;
  private String name;
  private String content;
  private int status;
  private String createTime;
  private String updateTime;
  private Category category;
 
}

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

public interface GoodCategoryDao {
    public List<Goods> findAllGoodsWithCate();
}

书写sql语句:

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

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

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

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

public class Category {
    private int categoryId;
    private String categoryName;
    private List<Goods> goodsList;
}

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

public interface GoodCategoryDao {
    public List<Goods> findAllGoodsWithCate();
    public List<Category> findAllCateWithGoods();
}

Select方法:

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

动态sql拼接:

 <select id="findStudentByCondition" resultType="Student">
        select * from student where 1=1
        <if test="sName!=null">
        and s_name like #{sName}
        </if>
        <if test="sSex!=null">
        and s_sex =#{sSex}
        </if>
 
    </select>

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

sys_role

 sys_user

sys_role_user

 

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

主方法:

    public List<User> list() {
        List<User> userList = userDao.findAll();
        for (User u : userList){
            Long id = u.getId();

            List<Role> roleList = roleDao.findById(id);
            u.setRoles(roleList);
        }
        return userList;
    }

dao层 fundAll()

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

dao层 findById(id)

    public List<Role> findById(Long id) {
        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);
        return query;
    }

查询结果:

4.mybatis中#与$的区别

#占位符:

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

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

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

select id,name,age from student where id =#{id}

select id,name,age from student where id ="1"

$占位符:

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

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

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

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

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

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坐标

    <dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper</artifactId>
      <version>5.3.2</version>
    </dependency>

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

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

3> 测试

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

4> 一些相关的API

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

7.延时加载

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

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

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

<settings>
    <!-- 延迟加载总开关 -->
    <setting name="lazyLoadingEnabled" value="false"/>
</settings>

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

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

<settings>
    <!-- 延迟加载总开关 -->
    <setting name="lazyLoadingEnabled" value="true"/>
    <!-- 侵入式延迟加载开关 -->
    <setting name="aggressiveLazyLoading" value="true"/>
</settings>

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

<settings>
    <!-- 延迟加载总开关 -->
    <setting name="lazyLoadingEnabled" value="true"/>
    <!-- 侵入式延迟加载开关 -->
    <setting name="aggressiveLazyLoading" value="false"/>
</settings>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值