Mybatis学习笔记(一)

https://mybatis.org/mybatis-3/zh/index.html

MyBatis 是一个可以自定义 SQL、存储过程和高级映射的持久层框架。 MyBatis 摒除了大部分的 JDBC代码、手工设置参数和结果集重获。 MyBatis 只使用简单的 XML 和注解来配置和映射基本数据类型、Map 接口和 POJO 到数据库记录。

SqlSessionFactoryBuilder

这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。 因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。 你可以重用 SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例,但最好还是不要一直保留着它,以保证所有的 XML 解析资源可以被释放给更重要的事情。

SqlSessionFactory

SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。 使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏习惯”。因此 SqlSessionFactory 的最佳作用域是应用作用域。 有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。

SqlSession

每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。 绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。 也绝不能将 SqlSession 实例的引用放在任何类型的托管作用域中,比如 Servlet 框架中的 HttpSession。 如果你现在正在使用一种 Web 框架,考虑将 SqlSession 放在一个和 HTTP 请求相似的作用域中。 换句话说,每次收到 HTTP 请求,就可以打开一个 SqlSession,返回一个响应后,就关闭它。 这个关闭操作很重要,为了确保每次都能执行关闭操作,你应该把这个关闭操作放到 finally 块中。 下面的示例就是一个确保 SqlSession 关闭的标准模式:

try (SqlSession session = sqlSessionFactory.openSession()) {
  // 你的应用逻辑代码
}

Mybatis实现 DAO的传统开发方式(不常用不关注)


举例:

1、根据用户 id 查询一个用户信息
2、根据用户名称模糊查询用户信息列表
3、添加用户信息

配置userMapper.xml

<mapper namespace="UserDao"> 

<insert id="saveUser" useGeneratedKeys="true" keyProperty="id" parameterType="cn.itcast.entity.User">
<!--         <selectKey order="AFTER" resultType="java.lang.Integer" keyProperty="id">
            select last_insert_id();
        </selectKey> -->
        insert into user (username,sex,birthday,address) values ( #{username} ,#{sex},#{birthday},#{address} )
</insert>
编写userDao的接口和实现类

public int save(User user) {
        //1.创建SqlSession对象
        SqlSession session = sessionFactory.openSession();
        //2.通过session保存用户
        /**
         * 第一个参数:mapperid
         * 第二个参数:用户对象
         */
        int result = session.insert("UserMapper.saveUser", user);
        
        //在保存用户之后,立即使用保存的用户的主键(id)
        System.out.println("保存的用户主键:"+user.getId());
        
        
        session.commit();
        //释放资源
        session.close();
        return result;
    }

在编写实现类中方法时,要注意所调用的 selectOne()的参数是由 namespace+id 一起来构成,但 namespace 和 id
的取值是我们自己去起名,不要求像我们前面通过 Mapper 代理方式一样,必须与包名和方法相同。

Mybatis 实现 DAO 代理开发方式


Mapper 接口开发需要遵循以下规范:
1、 Mapper.xml 文件中的 namespace 与 mapper 接口的类路径相同。
2、 Mapper 接口方法名和 Mapper.xml 中定义的每个 statement 的 id 相同
3、 Mapper 接口方法的输入参数类型和 mapper.xml 中定义的每个 sql 的 parameterType 的类型相同
4、 Mapper 接口方法的输出参数类型和 mapper.xml 中定义的每个 sql 的 resultType 的类型相同

原理实现

发现在调用 SqlSession 接口的 getMapper()方法时,它的底层进一步调用了 JDK 动态代理方式来生成代理子类对象的
 

Mybatis 的连接池技术

SqlMapConfig.xml 配置文件中, 通过 <dataSource type=”pooled”>来实现 Mybatis 中连接池的配置

UNPOOLED 不使用连接池的数据源
 POOLED 使用连接池的数据源
 JNDI 使用 JNDI 实现的数据源

Mybatis 中连接的获取
真正连接打开的时间点,只是在我们执行 SQL 语句时,才会进行
 Mybatis 的事务控制

Mybatis 框架因为是对 JDBC 的封装,所以 Mybatis 框架的事务控制方式,本身也是用 JDBC的 setAutoCommit()方法来设置事务提交方式的,在连接池中取出的连接,都会将调用 connection.setAutoCommit(false)方法
 


Mybatis 自动提交事务的设置

sqlSessionFactory.openSession(true)

Mybatis 的参数
传递 pojo 对象
Mybatis 使用 ognl 表达式解析对象字段的值, #{}或者${}括号中的值为 pojo 属性名称
Mybatis 的输出结果封装
resultType 可以指定 pojo 将查询结果映射为 pojo,但需要 pojo 的属性名和 sql 查询的列名一致
resultMap 可以实现将查询结果映射为复杂类型的 pojo,比如在查询结果映射对象中包括 pojo


和 list 实现一对一查询和一对多查询。
动态 SQL 之<if>标签
<if>标签的 test 属性中写的是对象的属性名,如果是包装类的对象要使用 OGNL 表达式的写法
<where />可以自动处理第一个 and
<foreach>标签用于遍历集合,它的属性:
collection:代表要遍历的集合元素,注意编写时不要写#{}

//注意事项
      //当传入的时一个List集合时,只能写collection:list(小写)
       //当传入的是一个对象是,要写集合在对象中的属性名称collection:ids
open:代表语句的开始部分
close:代表结束部分
item:代表遍历集合的每个元素,生成的变量名
sperator:代表分隔符
<include refid="namespace.sql 片段”/>


Mybatis 延迟加载策略
要在 Mybatis 的配置文件 SqlMapConfig.xml 文件中添加延迟加载的配置
        或者直接在下面的属性中开启
            <settings>
                <setting name="LazyloadingEnabled" value="true"/>
            </settings> 
            <resuletMap id="" type="">
                <id  column=""  property=""/>
                <result column="" property="">
                
                <association property="" javaType="" select="调用的映射的id" column="填写要传递给 select 映射的字段 " fetchType="lazy">
                </association>
                <collection property="" oftype="" select="调用的映射的id" column="填写要传递给 select 映射的字段 " fetchType="lazy">
                </collection>
            </resuletMap>    

Mybatis 缓存
Mybatis 中缓存分为一级缓存,二级缓存
一级缓存是 SqlSession 级别的缓存,只要 SqlSession 没有 flush 或 close,它就存在
当调用 SqlSession 的修改,添加,删除, commit(), close()等方法时,就会清空一级缓存
二级缓存是 mapper 映射级别的缓存,多个 SqlSession 去操作同一个 Mapper 映射的 sql 语句,多个 SqlSession
可以共用二级缓存,二级缓存是跨 SqlSession 的。

注意事项
         1.实体类对象需要实现序列化接口
            2.需要在核心配置文件中开启二级缓存
            <settings>
                <setting name="cacheEnabled" value="true"/>
            </settings>
            3.需要在mapper配置文件中开启使用二级缓存
                <cache />标签表示当前这个 mapper 映射将使用二级缓存,区分的标准就看 mapper 的 namespace 值
            4.需要在缓存的sql语句配置中配置使用二级缓存
                <select>标签中设置 useCache=”true
            5.操作的过程中需要提交之后才会存入到缓存中

Mybatis 注解开发
@Results:可以与@Result 一起使用,封装多个结果集 
            value={
                @Result(column=" ",property="",one=@One(select=""))
            }
        
         @Result 中 属性介绍: column 数据库的列名 Property 封装对象的属性名 javatype 封装对象.class
                                one  需要使用的@One 注解 many  需要使用的@Many 注解
                                @One:实现一对一结果集封装 
                                    属性select  指定用来多表查询的 sqlmapper
                                        fetchType 会覆盖全局的配置参数 lazyLoadingEnabled。
                                @Many:实现一对多结果集封装 
                                        属性select  指定用来多表查询的 sqlmapper
                                        fetchType 会覆盖全局的配置参数 lazyLoadingEnabled。
            注意:一对多时需要指定映射的 Java 实体类的属性,属性的 javaType(一般 为 ArrayList)但是注解中可以不定义

@SelectProvider: 实现动态 SQL映射 
                属性:type 查询语句的类字节码
                    method:对应的方法名称
                        注意事项:方法参数要一致


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值