MyBatis02——mybatis基础使用|缓存机制|sqlMapper文件|单参数和多参数传递|Statement和PreparedStatement

目录

一、搭建环境

二、核心配置文件

三、核心类 (测试类)

四、缓存机制

一级缓存

二级缓存

清理缓存

五、sqlMapper文件

六、单参数和多参数的传递

6.1取别名

 6.2 测试新增返回自增主键

七、mybatis中Statement和PreparedStatement

作业

1、掌握环境搭建

2、掌握单个参数、多个参数的增删改查

3、缓存机制 (一级、二级缓存特点)

4、mybatis核心配置文件 常见的配置项

5、#和$的区别?(重点)

6、sqlMapper文件新增返回自增主键

7、预习 动态sql和多表关联映射

动态sql

高级结果映射


一、搭建环境

1、引入jar包

mysql.jar
mybatis.jar

2、补全结构

com.hl.pojo
com.hl.mapper
mybatis-config.xml
sqlMapper.xml

3、测试类

加载myabtis核心配置文件,得到IO流  Resources
创建sqlSessionFactory   SqlsessionFactoryBuilder
SqlSession session = sqlSessionFactory.openSession()
//获取mapper接口
调用mapper方法
//关闭流

二、核心配置文件

mybatis-config.xml

<Configuration>
   //1、
    <properties resource="db.properties"></properties>
    //2、
    <environments default="test">
        <environment>
            <transactionManager  type="jdbc"/>
             <dataSource type="POOLED">
                    <property  name="url" value="" ></property>
                    username
                    password
                    driver
             </dataSource>
        </environment>
    </environments>
    //3、
    <mappers>
         <mapper resource="com/hl/mybatis01/mapper/AccountMapper.xml"/>
    </mappers>
    
</Configuration>

 补充完整代码

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<!--配置-->
<configuration>
    <!--引入外部配置文件-->
    <properties resource="db.properties"></properties>
​
    <!--设置-->
    <settings>
        <!--下划线到驼峰式命名法自动映射-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
​
    <!--类型起别名-->
    <typeAliases>
        <!--type="类型" alias="别名"-->
        <!--针对每一个javabean分别起别名-->
<!--        <typeAlias type="com.hl.mybatis02.pojo.Student" alias="student"></typeAlias>-->
        <!--统一起别名   别名默认为类名  不区分大小写-->
        <package name="com.hl.mybatis02.pojo" />
    </typeAliases>
    <!--数据库环境-->
    <environments default="dev">
        <environment id="dev">
            <transactionManager type="jdbc"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    <!--mappers映射器-->
    <mappers>
        <!--sqlMapper文件位置-->
<!--        <mapper resource="com/hl/mybatis02/mapper/GoodsMapper.xml"></mapper>-->
        <!--指向mapper接口位置-->
<!--        <mapper class="com.hl.mybatis02.mapper.GoodsMapper"></mapper>-->
<!--        <mapper class="com.hl.mybatis02.mapper.ItemMapper"></mapper>-->
        <!--指向mapper包的位置,统一扫描该包下所有接口-->
        <package name="com.hl.mybatis02.mapper"/>
    </mappers>
</configuration>

三、核心类 (测试类)

package com.hl.mybatis02;
​
import com.hl.mybatis02.mapper.StudentMapper;
import com.hl.mybatis02.pojo.Student;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
​
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
​
class Mybatis02ApplicationTests {
​
    @Test
    void contextLoads() throws IOException {
        InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        SqlSession session = factory.openSession();
        StudentMapper studentMapper = session.getMapper(StudentMapper.class);
​
        Student student = new Student(0,"admin",
                "男","2020-1-5",1001,
                null,null,null);
        int num = studentMapper.insertStudent(student);
        System.out.println("受影响的数据行数:"+num);
        System.out.println("自增主键值为:"+student.getStudentId());
        session.commit();
        session.close();
    }
​
    @Test
    void query() throws IOException {
        InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        SqlSession session = factory.openSession();
        StudentMapper studentMapper = session.getMapper(StudentMapper.class);
        List<Student> list = studentMapper.listAll();
        System.out.println(list);
​
        session.commit();
        session.close();
    }
​
}

四、缓存机制

缓存:多次执行相同dql,第一次走数据库表查询,第二次不再执行sql语句,直接从缓存区中获取数据。

一级缓存

默认已开启,可以直接使用,属于sqlSession级别的缓存。

二级缓存

默认没有开启,需要手动在mybatis配置文件中开启,属于sqlSessionFactory级别的缓存。

<!--开启当前命名空间的二级缓存-->
<cache></cache>

清理缓存

java代码清理缓存

session.clearCache();

sqlMapper文件清理缓存

        useCache="false"  禁用当前sql语句的二级缓存
        flushCache="true"  清空缓存区数据  导致一级缓存和二级缓存失效

<!--    //查询 下划线到驼峰式命名法的映射-->
<!--    public List<Student> listAll();
        useCache="false"  禁用当前sql语句的二级缓存
        flushCache="true"  清空缓存区数据  导致一级缓存和二级缓存失效
-->
    <select id="listAll" resultType="student"  useCache="false">
        select * from student
    </select>

示例:

  @Test
    void firstCache() throws IOException {
        InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        SqlSession session = factory.openSession();
        StudentMapper studentMapper = session.getMapper(StudentMapper.class);
​
        List<Student> list = studentMapper.listAll();
        System.out.println(list);
        //清理缓存
//        session.clearCache();
        List<Student> list2 = studentMapper.listAll();
        System.out.println(list2);
​
        session.commit();
        session.close();
    }
    @Test
    void secondCache() throws IOException {
        InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        SqlSession session = factory.openSession();
        StudentMapper studentMapper = session.getMapper(StudentMapper.class);
        List<Student> list = studentMapper.listAll();
        System.out.println(list);
        session.close();
​
​
        SqlSession session2 = factory.openSession();
        StudentMapper studentMapper2 = session2.getMapper(StudentMapper.class);
        List<Student> list2 = studentMapper2.listAll();
        System.out.println(list2);
        session2.close();
​
        SqlSession session3 = factory.openSession();
        StudentMapper studentMapper3 = session3.getMapper(StudentMapper.class);
        List<Student> list3 = studentMapper3.listAll();
        System.out.println(list3);
        session3.close();
    }
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--命名空间 唯一标识-->
<mapper namespace="com.hl.mybatis02.mapper.StudentMapper">
​
    <!--开启当前命名空间的二级缓存-->
    <cache></cache>

五、sqlMapper文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--命名空间 唯一标识-->
<mapper namespace="com.hl.mybatis02.mapper.StudentMapper">
        <!--    测试自增主键的生成
        useGeneratedKeys="true"  获取自动生成的主键
        keyProperty="studentId"  主键对应的属性名
        -->
<!--    public int insertStudent(Student student);-->
    <insert id="insertStudent" useGeneratedKeys="true" keyProperty="studentId">
        insert into student(name,gender,birth_date,class_id,enrollment_date)
        values (#{name},#{gender},#{birthDate},#{classId},now())
    </insert>
​
<!--    //查询 下划线到驼峰式命名法的映射-->
<!--    public List<Student> listAll(); -->
    <select id="listAll" resultType="student">
        select * from student
    </select>
</mapper>

六、单参数和多参数的传递

6.1取别名

Mapper接口

测试新增主键的生成,对象也可以取别名
多个参数,给参数起别名,将不再使用系统默认的arg0、arg1等
单个参数,也可以取别名,之后#{里面不能随便写了只能写别名}
 

//测试新增主键的生成,对象也可以取别名
    public int insertStudent(@Param("stu")Student student);
//    查询 下划线到驼峰式命名法的映射
    public List<Student> listAll();

//    多个参数,给参数起别名,将不再使用系统默认的arg0、arg1等
    public List<Student> findStudent(@Param("name")String name, @Param("phone")String phone);
//    单个参数,也可以取别名,之后#{里面不能随便写了只能写别名}
    public Student findStudentById(int id);

 6.2 测试新增返回自增主键

Mapper映射文件里面

测试新增主键的生成:
useGeneratedKeys="true"    获取自动生成的主键
keyProperty="studentId"    主键对应的属性名
对象在接口中取别名之后,调用对象的属性名,应该写成:别名.属性名

<!--命名空间  唯一标识-->
<mapper namespace="com.hl.mybatis02.mapper.StudentMapper">

<!--    //测试新增主键的生成
useGeneratedKeys="true"    获取自动生成的主键
keyProperty="studentId"    主键对应的属性名
对象在接口中取别名之后,调用对象的属性名,应该写成:别名.属性名
-->
<!--    public int insertStudent(Student student);-->
    <insert id="insertStudent" useGeneratedKeys="true" keyProperty="studentId">
        insert into student(name,gender,birth_date,class_id,enrollment_date)
        values (#{stu.name},#{stu.gender},#{stu.birthDate},#{stu.classId},now())

    </insert>


<!--    //    查询 下划线到驼峰式命名法的映射-->
<!--    public List<Student> listAll();-->
    <select id="listAll" resultType="student">
        select * from student
    </select>

    
<!--    //    多个参数-->
<!--    public List<Student> findStudent(String name,String phone);-->
    
<!--    select * from student where name = #{arg0} and phone = #{arg1}-->
    
<!--    <select id="findStudent" resultType="student">-->
<!--        select * from student where name = #{name} and phone = #{phone}-->
<!--    </select>-->
<!--    模糊查询-->
        <select id="findStudent" resultType="student">

            select * from student where name like concat('%',#{name},'%') or phone = #{phone}
        </select>
    
    
<!--    单个参数-其实识别的不是id是里面的第一个参数-->
<!--    public List<Student> findStudentByName(int id);-->
    <select id="findStudentById" resultType="student">

        select * from student where student_id = #{iaa}
    </select>
    
</mapper>

七、mybatis中Statement和PreparedStatement

statementType="PREPARED"  默认  使用预编译(防止sql注入)

statementType="STATEMENT" sql 字符串拼接

statementType="CALLABLE"   调用存储过程

<!-- //多个参数
public List<Student> findStudents(String name,String phone);
statementType="PREPARED" 默认 使用预编译
               STATEMENT sql字符串拼接
               CALLABLE  调用存储过程
-->
<select id="findStudents" resultType="Student">
    select * from student where name like concat('%',#{name},'%') or phone=#{phone}
</select>
<!--public Student findStudentById(int id);-->
<select id="findStudentById" resultType="Student" statementType="STATEMENT">
    select * from student where student_id=${id}
</select>

作业

1、掌握环境搭建

2、掌握单个参数、多个参数的增删改查

3、缓存机制 (一级、二级缓存特点)

4、mybatis核心配置文件 常见的配置项

5、#和$的区别?(重点)

  1. 预处理方式不同

    • #{}:使用预编译(PreparedStatement)方式,参数会被替换为 ?,能有效防止 SQL 注入

    • ${}:使用字符串拼接方式,直接将参数值替换到 SQL 语句中

  2. 安全性

    • #{}:安全,能防止 SQL 注入

    • ${}:不安全,存在 SQL 注入风险

  3. 参数处理

    • #{}:会对传入的参数自动添加引号(字符串类型)

    • ${}:原样替换,不会添加引号

6、sqlMapper文件新增返回自增主键

见6.2

7、预习 动态sql和多表关联映射

动态sql

  • if

  • choose (when, otherwise)

  • trim (where, set)

  • foreach

高级结果映射

MyBatis 创建时的一个思想是:数据库不可能永远是你所想或所需的那个样子。 我们希望每个数据库都具备良好的第三范式或 BCNF 范式,可惜它们并不都是那样。 如果能有一种数据库映射模式,完美适配所有的应用程序,那就太好了,但可惜也没有。 而 ResultMap 就是 MyBatis 对这个问题的答案。

比如,我们如何映射下面这个语句?

<!-- 非常复杂的语句 -->
<select id="selectBlogDetails" resultMap="detailedBlogResultMap">
  select
       B.id as blog_id,
       B.title as blog_title,
       B.author_id as blog_author_id,
       A.id as author_id,
       A.username as author_username,
       A.password as author_password,
       A.email as author_email,
       A.bio as author_bio,
       A.favourite_section as author_favourite_section,
       P.id as post_id,
       P.blog_id as post_blog_id,
       P.author_id as post_author_id,
       P.created_on as post_created_on,
       P.section as post_section,
       P.subject as post_subject,
       P.draft as draft,
       P.body as post_body,
       C.id as comment_id,
       C.post_id as comment_post_id,
       C.name as comment_name,
       C.comment as comment_text,
       T.id as tag_id,
       T.name as tag_name
  from Blog B
       left outer join Author A on B.author_id = A.id
       left outer join Post P on B.id = P.blog_id
       left outer join Comment C on P.id = C.post_id
       left outer join Post_Tag PT on PT.post_id = P.id
       left outer join Tag T on PT.tag_id = T.id
  where B.id = #{id}
</select>

你可能想把它映射到一个智能的对象模型,这个对象表示了一篇博客,它由某位作者所写,有很多的博文,每篇博文有零或多条的评论和标签。 我们先来看看下面这个完整的例子,它是一个非常复杂的结果映射(假设作者,博客,博文,评论和标签都是类型别名)。 不用紧张,我们会一步一步地来说明。虽然它看起来令人望而生畏,但其实非常简单。

<!-- 非常复杂的结果映射 -->
<resultMap id="detailedBlogResultMap" type="Blog">
  <constructor>
    <idArg column="blog_id" javaType="int"/>
  </constructor>
  <result property="title" column="blog_title"/>
  <association property="author" javaType="Author">
    <id property="id" column="author_id"/>
    <result property="username" column="author_username"/>
    <result property="password" column="author_password"/>
    <result property="email" column="author_email"/>
    <result property="bio" column="author_bio"/>
    <result property="favouriteSection" column="author_favourite_section"/>
  </association>
  <collection property="posts" ofType="Post">
    <id property="id" column="post_id"/>
    <result property="subject" column="post_subject"/>
    <association property="author" javaType="Author"/>
    <collection property="comments" ofType="Comment">
      <id property="id" column="comment_id"/>
    </collection>
    <collection property="tags" ofType="Tag" >
      <id property="id" column="tag_id"/>
    </collection>
    <discriminator javaType="int" column="draft">
      <case value="1" resultType="DraftPost"/>
    </discriminator>
  </collection>
</resultMap>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值