粗谈Mybatis

Mybatis

入门

        框架是软件开发的解决方案,不同框架解决不同问题:mybatis解决持久化层,SpringMVC解决表现层。
        简单来说,框架可以提高效率,简化实现功能。

三层架构:
        表现层:展示数据
        业务层:业务需求
        持久层:和数据库交互

关于持久层技术的解决方案:
        1、JDBC技术:Connection、PreparedStatement、ResultSet
        2、Spring的JdbcTemplate:Spring对JDBC的简单封装
        3、Apache的DBUtils:和JDBCTemplate很像,也是对JDBC的简单封装
他们不是框架?

JDBC是规范,Spring的JdbcTemplate和Apache的DBUtils都只是工具类。

注意:mybatis用xml文件或者注解实现Statement的配置,并且通过动态sql返回java对象。

mybatis概述:
        mybatis是一个持久化层框架,用java写的。
        它封装了jdbc,开发者只需要关注sql本身。
        它使用了ORM思想实现了结果集的封装。
什么是ORM?
        Object Relational Mapping ---- 对象关系映射
        简单来说,就是把数据库表和实体类及实体类的属性对应起来。那么,我们可以通过操作实体类就可以操作数据库表。即实体类的属性和数据库表的字段名称保持一致。

环境搭建注意事项:

  1. 在mybatis中它把持久层的操作接口名称和映射文件也叫做:Mapper。
  2. mybatis的映射配置文件位置必须和dao接口的包结构相同。
  3. 映射配置文件的mapper标签namespace属性的取值必须是dao接口的全限定类名。
  4. 映射配置文件的操作配置,id属性的取值必须是dao接口的方法名。

关于在resources下配置userdao的文件时,有两种方式:xml文件和注解。
        1、xml文件:在创建userdao.xml,具体看idea里面的配置。在SqlMapConfig.xml里面的mappers标签下的mapper标签里 使用resource=””(包/userdao类)。
        2、注解:无需userdao.xml文件,在SqlMapConfig.xml里面的mappers标签下的mapper标签里使用class=””(userdao类的全限定名)。

注意

在UserDao.xml文件中的模糊查询:
1、select * from user where username like #{username}采用的是preparedStatement(编译预处理)
2、select * from user where username like ‘%${value}%’采用的Statement
综上所述,应该用第一条语句进行模糊查询更好。

获取当前插入语句的id:
        插入语句…
        select last_insert_id();
        具体配置看idea里的userdao.xml

mybatis使用ognl表达式解析对象字段的值,#{}或者${}括号中的值为pojo属性名称。
什么是OGNL表达式:
        Object Graphic Navigation Language
        对象          图          导航          语言
        apache开发的,它是通过对象的取值方法来获取数据。在写法上把get省略了。
        例如: 类中:user.getUsername();
                OGNL表达式写法:user.username
        mybatis中为什么能直接写username,而不用user. 呢?
                因为parameterType中已经提供了属性所属的类。

注意:mybatis中实体类的属性和mysql中的列名应该一致(在WINDOWS下无所谓大小写),如果列名不一致,那么在查询语句中,无法将属性对应封装成对象。

那么真不一样怎么办?
1、SQL层面:可以在userdao.xml文件中通过SQL语句的取别名来避免与mysql的列名不一致。
2、mybatis层面:在userdao.xml中配置查询结果的列名和实体类的属性名的对应关系,

<resultMap  id=”userMap”  type=”对应实体类名”>

	<!-- 主键字段的对应 -->
	<id  property=”实体类属性”  column=”mysql列名”></id>

	<!-- 非主键字段对应 -->
	<result  property=”实体类属性”  column=”mysql列名”></result>
</resultMap>

并且标签里不能用resultType=””,而应使用resultMap=””。

mybatis的连接池提供了3种方式的配置:
        配置位置:主配置文件SqlMapConfig.xml中的dataSource标签,type属性表示何种连接方式。
        type属性的取值:

                1、POOLED:采用javax.sql.DataSource规范中的连接池,mybatis有针对的实现。
                2、UNPOOLED:采用传统的获取连接的方式,虽然也实现了javax.sql.DataSource接口,但是并没有使用池的思想,也就不会有容器的概念。
                3、JNDI:采用服务器提供的JNDI技术实现,来获取DataSource对象,不同的服务器所能拿到DataSource是不一样的。
                        注意:如果不是web或者maven的war工程,是不能使用的。
                        我们使用的tomcat服务器,采用的连接池是dbcp连接池。

mybatis中的事务:
事务的四大特性:原子性、一致性、隔离性、持久性。
四种隔离级别:读未提交、读已提交、可重复读(mysql默认)、串行化。
造成的问题:脏读、不可重复读、幻读、安全但效率低。

Mybatis中的事务是通过sqlsession对象的commit方法和rollback方法实现事务的提交和回滚。

细节:在获取sqlsession对象的时候,是通过工厂对象的opensession( )方法获取的,然而mybatis默认是事务手动提交,如果想要自动提交的话,就需要opensession( )的重载方法,opensession( true )来设置自动提交。

配置userdao.xml文件时,如果使用条件查询,可以使用标签.。

  • 第一种方式:在where 1=1后面加上多个标签
    粗谈Mybatis_第1张图片
  • 第二种方式:去掉where 1=1 ,直接改用标签去嵌套标签
    粗谈Mybatis_第2张图片

使用查询语句时,如果仅仅使用参数对象的一个属性查询直接可以:类名+属性名;当使用参数对象的一个集合属性时,这时候就可以使用 标签
标签用于集合的遍历,它的属性:
      collection:代表要遍历的集合元素,注意编写时不要写#{}
      open:代表语句的开始部分
      close:代表结束部分
      item:代表遍历集合的每个元素,生成的变量名
      sperator:代表分隔符

mybatis中的多表操作:mybatis中的延迟加载、缓存和注解开发(环境搭建、单表CRUD操作、多表查询、缓存配置)。

延迟加载:在真正使用数据时才发起查询,不用的时候不查询。按需加载(懒加载)。
立即加载:不管用不用,一旦调用方法,就立即查询。
时机

  • 一对多,多对多:通常情况下我们都是采用延迟加载。
  • 多对一,一对一:通常情况下我们都是采用立即加载。

为什么使用缓存?

  • 减少和数据库交互的次数,提高执行效率。

使用缓存的时机:

  • 经常查询并且不经常改变。
  • 数据的正确与否对最终结果影响不大的。

相反,不适用缓存的时机:

  • 经常改变的数据。
  • 数据的正确与否对最终结果影响很大。
  • 例如:商品的库存、银行的汇率、股市的牌价。

mybatis的一级缓存和二级缓存:

一级缓存:
指的是SqlSession对象的缓存。

当我们执行查询后,查询结果会同时存入到SqlSession为我们提供的一块区域中。该区域的结构是一个Map。当我们再次查询同样的数据,mybatis会先去sqlsession中查询是否有,有的话直接用。
当SqlSession对象消失时,mybatis的一级缓存也就消失了。
当你执行了一次查询操作,此时sqlsession对象是有缓存的,但是当你之后执行了一次数据库更改操作,那么缓存就会消失。

二级缓存:
它指的是mybatis中SqlSessionFactory对象的缓存。由同一个SqlSessionFactory对象创建的SqlSession共享其缓存。

二级缓存的使用步骤:
1、让mybatis框架支持二级缓存(在SqlMapConfig.xml中配置)
2、让当前的映射文件支持二级缓存(在UserDao.xml中配置)
3、让当前的操作支持二级缓存(在select标签中配置)
二级缓存存放的内容是数据,而不是对象。所以判断其是否为缓存时,只执行了一次查询,但是否为同一对象时返回的结果是false;所以相当于每一次访问二级缓存时,都new一个对象,然后将存放的数据填充进对象中。

你可能感兴趣的:(java)