Mybatis

Mybatis

​ MyBatis 是一款优秀的持久层框架

准备环境

<!--mybatis依赖-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.21</version>
</dependency>
<!--mysql驱动-->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.5</version>
</dependency>

核心实例

​ MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的,通过 SqlSessionFactoryBuilder 构建出

​ MyBatis 包含一个名叫 Resources 的工具类,使得从类路径或其它位置加载资源文件

private static SqlSessionFactory sqlSessionFactory;
static {
    try {
        InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        inputStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
public static SqlSession getSqlSessionFactory() {
    return sqlSessionFactory.openSession();
}

核心配置文件

​ mybatis-config.xml

​ 包括获取数据库连接实例的数据源(DataSource)以及决定事务作用域和控制方式的事务管理器(TransactionManager)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--mybatis核心配置文件-->
<configuration> 
    <environments default="development">
        <environdement id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!--mysql驱动-->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://47.93.39.25:3306/tmy?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="TianMeng_yu123!@#"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/tmy/dao/UserMapper.xml"/>
    </mappers>
</configuration>
configuration(配置)
    properties(属性)	// 属性配置,resource="mysql.properties"
    settings(设置)	// mybatis设置:缓存设置、超时时间、驼峰命名自动映射、日志体现...
    	cacheEnabled:cacheEnabled(全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。true)
    typeAliases(类型别名)	// 在xml配置文件中使用,给java实体类设置别名或者指定包(包下实体别名为驼峰命名)
    typeHandlers(类型处理器)	
    objectFactory(对象工厂)
    plugins(插件)
    environments(环境配置)	// 配置多套数据源,默认default
    environment(环境变量)	// 具体环境变量
    transactionManager(事务管理器)	// type=JDBC(提交/回滚)
    dataSource(数据源)	// type=POOLED(连接池)
    databaseIdProvider(数据库厂商标识)	
    /*
    相对于类路径的资源引用,或完全限定资源定位符(包括 file:/// 形式的 URL),或类名和包名
    */
    mappers(映射器)	// 映射器:定义 SQL 映射语句
    <!-- 使用相对于类路径的资源引用:映射mapper.xml文件 -->
    <mapper resource="com/tmy/dao/UserMapper.xml"/>
    <!-- 使用映射器接口实现类的完全限定类名:映射mapper接口文件,使用注解 -->
    <mapper class="com.tmy.dao.UserMapper"/>
    <!-- 将包内的映射器接口实现全部注册为映射器 -->
    <package name="com.tmy.dao"/>

映射文件

/*
select
	id:	命名空间中唯一的标识符,方法名
	parameterType:参数的类全限定名或别名
	resultType:返回结果的类全限定名或别名(如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身的类型)
	
*/
User findById(Integer id);
<select id="findById" parameterType="integer" resultType="user">
    select * from user where id = #{id}
</select>
/*
insert
	session	提交事务(session.commit();)
	无返回值类型,但是返回操作行数
*/
<insert id="add" parameterType="user">
    insert into user (id, name, age, address) values (#{id},#{name},#{age},#{address})
</insert>
/*
update
	主键不能修改,这是查询的条件
*/
<update id="update" parameterType="user">
    update user set
    id = #{id},
    name = #{name},
    age = #{age},
    address = #{address}
    where id = #{id}
</update>
/*
delete
*/
<delete id="del" parameterType="user">
    delete from user where id = #{id}
</delete>
/*
map 所有参数都可以用map来定义,不一定是实体
#{id}:id与map的key值对应,传入的值取map的value
*/
<select id="findByMapId" parameterType="map" resultType="user">
    select * from user where id = #{id}
</select>

limit

​ 注意limit页数

<select id="listLimitUser" parameterType="map" resultType="user">
    select * from user limit #{pageNo},#{pageSize}
</select>

sql片段

​ sql 中还可以传递参数

<sql id="select">select * </sql>
<select id="listLimitUser" parameterType="map" resultType="user">
    <include refid="select"></include>
    from user limit #{pageNo},#{pageSize}
</select>

结果集映射(重要)

TeacherTable:id,name

StudentTable:id,name,tid(外键关联Teacher表id)


Teacher:id,name,Liststudents

Student:id,name,tid

一对多
<!--查询一个老师信息-->
<!--1、嵌套:select查询-->
<select id="findTeacher" resultMap="TeacherStudent">
	select * from teacher where id=#{id}
</select>
<resultMap id="TeacherStudent" type="Teacher">
	<collection property="students" column="id" javaType="ArrayList" ofType="Student" select="listStudent" />
</resultMap>
<select id="listStudent" resultType="student">
	select * from student where tid=#{tid}
</select>
<!--2、嵌套:结果映射处理-->
<select id="findTeacher" parameterType="int" resultMap="TeacherStudent">
	select t.id tid, t.name tname, s.id sid, s.name sname from teacher t
    left join student s
    on t.id=s.tid
    where t.id = #{id}
</select>
<resultMap id="TeacherStudent" type="Teacher">
	<result property="id" column="tid"/>
    <result Property="name" column="tname"/>
    <collection property="students" type="Student">
    	<result property="id" column="sid"/>
        <result property="name" column="sname"/>
    </collection>
</resultMap>

Student:id,name,teacher

Teacher:id,name

多对一
<!--查询所有学生信息-->
<!--1、嵌套:select查询-->
<select id="listStudent" resultMap="StudenTeacher">
	select * from student
</select>
<resultMap id="StudentTeacher" type="Student">
	<!--单独处理学生中的老师对象-->
    <association property="teacher" column="tid" javaType="Teacher" select="listTeacher" />
</resultMap>
<select id="listTeacher" resultType="Teacher">
	select * from teacher where id=#{id}
</select>
<!--2、嵌套:结果映射处理-->
<select id="listStudent" resultMap="StudentTeacher">
	select s.id sid, s.name sname, t.name tname
    from student s, left join teacher t
    on s.tid=t.id
</select>
<resultMap id="StudentTeacher">
    <result property="id" column="sid"/>
    <result property="name" column="sname"/>
    <association property="teacher" javeType="Teacher">
    	<result property="name" column="tname"/>
    </association>
</resultMap>

注解

@Select(" select * from user ")
List<User> listAll();

@Select(" select * from user where id = #{id} and name = #{name} ")
User findBy(@Param("id") Integer id, @Param("name") String name);

@Insert(" insert into user (id, name, age, address) " +
        " values (#{id}, #{name}, #{age}, #{address}) ")
int add(User user);

@Update(" update user set name = #{name}, age = #{age}, address = #{address} " +
        " where id = #{id} ")
int update(User user);

@Delete(" delete from user where id=#{id} ")
int del(@Param("id") Integer id);

动态sql

<!--if-->
where 后面有固定条件情况下 1=1
<if test="title != null">
    and title like #{title}
</if>
<!--bind-->
创建一个变量
<select id="selectBlogsLike" resultType="Blog">
  <bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
  SELECT * FROM BLOG
  WHERE title LIKE #{pattern}
</select>
<!--where-->
where只会在子元素返回才插入 “WHERE” 子句。若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。
<where>
    <if test="state != null">
        and state = #{state}
    </if>
    <if test="title != null">
        and title like #{title}
    </if>
</where>
<!--set-->
动态更新语句set,会删掉额外的逗号
update Author
<set>
    <if test="username != null">username=#{username},</if>
    <if test="password != null">password=#{password},</if>
    <if test="email != null">email=#{email},</if>
    <if test="bio != null">bio=#{bio},</if>
</set>
where id=#{id}
<!--choose-->
<where>
    <choose>
        <when test="title != null">
            AND title like #{title}
        </when>
        <when test="author != null and author.name != null">
            AND author_name like #{author.name}
        </when>
        <otherwise>
            AND featured = 1
        </otherwise>
    </choose>
</where>
<!--foreach-->
在构建 IN 条件语句
<select id="listInIds" resultType="user" parameterType="map">
  select * from user
  <where>
    <when test="title != null">
    	and title like #{title}
    </when>
	<foreach item="id" collection="ids" open="and (" separator="," close=")">
    	id = #{id}
    </foreach>
  </where>
</select>

缓存(Cache)

​ 存在内存中的临时数据

​ 解决读写问题(并发):读写分离,主从复制

​ mybatis中定义了两级缓存:一级缓存(sqlSession)、二级缓存(nameSpace),默认情况下,一级缓存开启

一级缓存

​ 本地缓存,sqlSession级别的

二级缓存

​ 全局缓存,nameSpace级别的

​ 二级缓存是事务性的。

​ SqlSession 完成并提交时,或是完成并回滚,但没有执行 flushCache=true 的 insert/delete/update 语句,缓存会获得更新。

<cache
  eviction="FIFO"
  flushInterval="60000"
  size="512"
  readOnly="true"/>
eviction 清除策略
    LRU – 最近最少使用:移除最长时间不被使用的对象。
    FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
    SOFT – 软引用:基于垃圾回收器状态和软引用规则移除对象。
    WEAK – 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象。
flushInterval(刷新间隔)
size  欲缓存对象的大小
readOnly (只读)属性可以被设置为 true 或 false。只读的缓存会给所有调用者返回缓存对象的相同实例。 因此这些对象不能被修改。这就提供了可观的性能提升。而可读写的缓存会(通过序列化)返回缓存对象的拷贝。 速度上会慢一些,但是更安全,因此默认值是 false。

​ 一级缓存的sqlSession关闭后,二级缓存开启的化,已有的缓存就会返回给二级缓存

自定义缓存

<cache type="com.domain.something.MyCustomCache"/>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值