mybatis学习笔记

什么是mybatis

  • MyBatis 是一款优秀的持久层框架。
  • 它支持自定义 SQL、存储过程以及高级映射。
  • MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
  • MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

mybatis的优点

  • sql和代码分离,提高了可维护性
  • 提供映射标签,支持对象和数据库的字段关系映射
  • 提供xml标签,支持动态sql语句
  • mybatis可以简化jdbc的代码,同时可以让sql语句任意拼接。

mybatis的架构

在这里插入图片描述

CRUD(增删改查)

insert

	 <insert id="insert" parameterType="com.feng.pojo.User" >
        insert into mybatis.user(id, name, pwd) values (#{id},#{name},#{pwd});
    </insert>

id是DAo层对应的方法。parameter是参数类型

update

	<update id="update" parameterType="com.feng.pojo.User">
        update mybatis.user set name = #{name},pwd = #{pwd} where id=#{id};
    </update>

delete

<delete id="delete" parameterType="int">
        delete from mybatis.user where id = #{id};
    </delete>

select

	 <select id="getUserList" resultType="com.feng.pojo.User">
        select * from mybatis.user;
   	</select>

注意

<mapper namespace="">

 <!--namespace根据自己需要创建的的mapper的路径和名称填写-->

</mapper>

这个namespace里面的是dao层下面对应的接口名

增删改需要提交事务,查询不用,
但如果
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession(“true”);
}
该方法里面加了true,则不用写提交事务操作。

Map和模糊查询

万能的map


public interface UserMapper {
    

    //万能的map
    int insert2(Map<String,Object>map);

    
}

<insert id="insert2" parameterType="map" >
        insert into mybatis.user(id, name, pwd) values 
        (#{Id},#{userName},#{password});
 </insert>



使用了map,字段名可以不用对应,可以自己任意取名,但后面引用要使用自己取的
名字,而且可以插入自己想插入的字段,不用将所有字段写出,但是没用map的话不
行,名字也必须和数据库字段对应,不能修改。

	**注意**
	
	如果方法中有多个参数,需要使用到map或者使用@Param注解

模糊查询

第一种方式(推荐):

<select id="getUser" resultType="com.feng.pojo.User" parameterType="int">
        select * from mybatis.user
         where name like "%"#{value}"%";
 </select>

第二种:


public class UserDaoTest {
    @Test
    public void test()
    {
        //第一步,获得sqlsession对象
       SqlSession sqlSession = MybatisUtils.getSqlSession();

       //第二步,执行sql,方式一,getMapper
        UserMapper userDao = sqlSession.getMapper(UserMapper.class);


        
        List<User> users = userDao.getUserList("%李%");


        for (User user : users) {
            System.out.println(user);

        }
        sqlSession.close();
    }

  
}

配置解析

1.核心配置文件

mybatis-config.xml

在这里插入图片描述
属性(properties)

第一种直接写:

 <dataSource type="POOLED">
	<property name="driver" value="com.mysql.jdbc.Driver"/>
	<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&amp;useUnicode=false&amp;characterEncoding=UTF-8"/>
    <property name="username" value="root"/>
  	<property name="password" value="131556"/>
</dataSource>

第二种,引入外部配置条件

外部配置属性:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=false&amp;useUnicode=false&amp;characterEncoding=UTF-8
username=root
password=131556


引用
 <!--引入外部配置条件-->
    <properties resource="db.properties"/>

 <dataSource type="POOLED">
  	<property name="driver" value="${driver}"/>
    <property name="url" value="${url}"/>
    <property name="username" value="${username}"/>
    <property name="password" value="${password}"/>
 </dataSource>

类型别名(typeAliases)

类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。

   <!--给实体类取别名-->
   
  		 第一种是别名为User
  		 
    <!--方法一-->
<!--    <typeAliases>-->
<!--        <typeAlias type="com.feng.pojo.User" alias="User"/>-->
<!--    </typeAliases>-->

	第二种是一个包下面的所有文件都有别名,这个别名就是他们文件名的小写

    <!--方法二-->
    <typeAliases>
        <package name="com.feng.pojo"/>
    </typeAliases>

映射器(mappers)

我们现在就要来定义 SQL 映射语句了。 但首先,我们需要告诉 MyBatis 到哪里去找到这些语句。 在自动查找资源方面,Java 并没有提供一个很好的解决方案,所以最好的办法是直接告诉 MyBatis 到哪里去找映射文件。 ,或类名和包名等。例如:

1.每一个mapper的.xml文件都需要到核心文件中去注册(mybatis-config.xml,操作就按照下面就可以实现)
2.接口和他的mapper配置文件必须同名
3.接口和他的配置文件必须在同一包下面


<!-- 使用相对于类路径的资源引用 -->
 <mappers>
        <mapper resource="com/feng/Dao/UserMapper.xml"/>
 </mappers>
 
注意上面的方法是"/"而下面的方法是".",同时上面那种方法有文件后缀名,
下面的则没有
		
<!-- 使用扫描包进行注入绑定-->
 <mappers>
        <mapper class="com.feng.Dao.UserMapper"/>
</mappers>

生命周期和作用域

在这里插入图片描述
作用域和生命周期类别是至关重要的,因为错误的使用会导致非常严重的并发问题。

SqlSessionFactoryBuilder

  • 一旦创建了 SqlSessionFactory,就不再需要它了
  • 局部变量

SqlSessionFactory

  • 可以理解为数据库连接池
  • SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在

SqlSession

  • 连接到连接池的一个请求
  • SqlSession 的实例不是线程安全的,因此是不能被共享的
  • 每个线程都应该有它自己的 SqlSession 实例
  • 用完后关闭,防止资源占用

ResultMap结果集映射

解决属性名和字段名不一致的问题

<!--namespace=绑定一个Dao/Mapper接口-->
<mapper namespace="com.feng.Dao.UserMapper" >

   

    <select id="getUser" resultMap="UserMap" parameterType="int">
        select * from mybatis.user where id = #{id};
    </select>



    <!--结果集映射-->
    <resultMap id="UserMap" type="User">
        <!--column是数据库中的字段,property是实体类的属性-->
        <!--        <result column="id" property="id"/>-->
        <!--        <result column="name" property="name"/>-->
        <result column="pwd" property="password"/>

    </resultMap>



</mapper>

日志

ybatis 通过使用内置的日志工厂提供日志功能。内置日志工厂将会把日志工作委托给下面的实现之

 <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
</dependency>

Limit实现分页

    <select id="getUsersByLimit" parameterType="map" resultMap="UserMap">
        select * from mybatis.user limit #{startIndex},#{pageSize};
    </select>




	@Test
    public void getUsersByLimitTest()
    {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        HashMap<String,Integer> map = new HashMap<String, Integer>();
        map.put("startIndex",1);
        map.put("pageSize",2);
        List<User> users = userMapper.getUsersByLimit(map);
        for (User user : users) {
            System.out.println(user);
        }
        sqlSession.close();
    }



使用注解开发


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


    可以不需要mapper的配置文件
    
    
    
    @Insert("insert into user(id,name,pwd)values(#{id},#{name},#{password})")
    int insert(User user);

@Param()注解

  • 基本类型的参数或String类型,需要加上
  • 引用类型不用加
  • 多个参数需要使用
  • SQL中的引用名是@Param()里面定义的

Lombok的使用

@Data

省去get和set的方法

@AllArgsConstructor

省去有参构造方法

@NoArgsConstructor

省去无参构造方法

@ToString

省去输出格式方法
在这里插入图片描述

多对一

多个学生关联一个老师(对学生而言)

@Data
public class Student {

    private int id;
    private String name;

    //学生关联一个老师
    private Teacher teacher;
}


 <select id="getStudents2" resultMap="student_teacher2">
        select s.id sid,s.name sname,t.name tname
        from mybatis.student s,mybatis.teacher t
        where s.tid = t.id;
    </select>
    <resultMap id="student_teacher2" type="Student">
        <result property="id" column="sid"/>
        <result property="name" column="sname"/>
        <association property="teacher" javaType="Teacher">
            <result property="name" column="tname"/>
        </association>

    </resultMap>

一对多

集合:
一个老师对应多个学生(对老师而言)

@Data
public class Teacher {

    private int id;
    private String name;
    //一个老师有多个学生
    private List<Student> students;
}




    <select id="getStudents" resultMap="teacher_student">
        select s.id sid,s.name sname,t.id tid,t.name tname
        from mybatis.teacher t,mybatis.student s
        where s.tid = t.id and t.id = #{tid};
    </select>
    <resultMap id="teacher_student" type="Teacher">
        <result property="id" column="tid"/>
        <result property="name" column="tname"/>
        <!--复杂的属性需要特殊处理-->
        <collection property="students" ofType="Student">
            <result property="id" column="sid"/>
            <result property="name" column="sname"/>
            <result property="tid" column="tid"/>
        </collection>
    </resultMap>

动态SQL

动态SQL指的是根据不同的条件生成不同的 SQL语句

IF语句

<select id="queryBlog" parameterType="map" resultType="blog">

        select * from mybatis.blog where 1= 1
        <if test="title != null">
        	and title = #{title}
        </if>
          <if test="author != null">
        	and author = #{author}
        </if>
        
       


    </select>

WHERE标签可以去除第一个的and

<select id="queryBlog" parameterType="map" resultType="blog">

        select * from mybatis.blog
       <where>
	        <if test="title != null">
	        	 title = #{title}
	        </if>
	          <if test="author != null">
	        	and author = #{author}
	        </if>
        </where>
    </select>

SET标签
set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号

  <update id="updateBlog" parameterType="map">
        update mybatis.blog
        <set>
            <if test="title != null ">
                title = #{title},
            </if>
            <if test="author != null">
                author = #{author}
            </if>
        </set>
        where id = #{id};
    </update>

SQL标签
1.使用sql标签会抽取公共的部分

 <sql id="select">
        <if test="title != null">
            title = #{title}
        </if>
        <if test="author != null">
            and author = #{author}
        </if>
    </sql>

2.在需要的地方引用include标签即可


    <select id="queryBlog" parameterType="map" resultType="blog">

        select * from mybatis.blog
        <where>
            <include refid="select">

            </include>
        </where>


    </select>

foreach方法
动态 SQL 的另一个常见使用场景是对集合进行遍历

<!--
        select * from blog where 1=1 and(id=1 or id=2 or id=3)
        -->
    <select id="queryBlogForeach" parameterType="map" resultType="blog">
        select * from mybatis.blog
        <where>
            <foreach collection="ids" item="id" open="(" close=")" separator="or">
                id = #{id}
            </foreach>
        </where>
    </select>

choose标签
有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。
执行一个,其他不会被执行

<select id="queryBlogChoose" resultType="blog" parameterType="map">
        select * from mybatis.blog
        <where>
            <choose>
                <when test="title != null">
                    title = #{title}
                </when>
                <when test="author != null">
                    and author = #{author}
                </when>
                <otherwise>
                   and views = #{views}
                </otherwise>
            </choose>
        </where>
    </select>

缓存简介

1.什么是缓存

  • 存在内存中的临时数据
  • 将用户经常查询的数据放在缓存中,用户 不用每次去数据库文件提取数据,提高查询效率,解决高并发问题

2.为什么要用缓存

  • 减少和数据库交互次数,提高效率,减少系统开销

3.什么样的数据可以用缓存

  • 经常查询且不轻易改变的数据

mybatis缓存

  • mybatis系统默认定义了两级缓存:一级缓存和二级缓存
  • 默认情况下只有一级缓存开启,(sqlsession级别的缓存,本地缓存)
  • 二级缓存需要手动开启和配置,是namespace级别的缓存
  • 我们通过实现cache接口自定义二级缓存
  • 一级缓存的会话关闭了,一级缓存的数据会保留到二级缓存中

    <!--在当前的Mapper.xml中开启二级缓存-->

    <cache type="org.mybatis.caches.ehcache.EhcacheCache"/>


    <select id="selectUserById" resultType="user" useCache="true">
        select * from mybatis.user where id = #{uid};
    </select>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值