Mybtis核心学习

时间:2021-03-08 13:18:58   收藏:0   阅读:0

Mybatis

1、简介

1.1、Mybaits简介

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

1.2、持久化

数据持久化

为什么需要持久化?

1.3、持久层

Dao层,Servlet层、Controller层、、、

1.4、为什么需要使用Mybatis?

2、第一个Mybaits程序

2.2、搭建数据库

2.2、创建一个模块

public class MybatisUtils {

    private static SqlSessionFactory sqlSessionFactory = null;

    static {
        //获取sqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public static SqlSession getSqlSession() {
        return sqlSessionFactory.openSession();

    }
}

2.3、编写代码

2.4、测试

注意

org.apache.ibatis.binding.BindingException: Type interface com.bing.dao.Mapper is not known to the MapperRegistry.

技术图片

    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

3、CRUD

1、select

    <select id="getUserList" resultType="com.bing.pojo.User">
        select *
        from mybatis.user
    </select>
    <select id="getUserById" resultType="com.bing.pojo.User" parameterType="int">
        select *
        from mybatis.user
        where id = #{id}
    </select>

2、insert

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

3、update

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

4、delete

    <delete id="deleteUser" parameterType="com.bing.pojo.User">
        delete
        from mybatis.user
        where id = #{id}
    </delete>

注意点:增删改需要提交事务

5、万能Map

  int getUserById2(Map<String, Object> map);


   @Test
    public void inseMap() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        Map<String, Object> map = new HashMap<String, Object>();

        map.put("userid", 6);
        map.put("username", "98");
        mapper.getUserById2(map);

        sqlSession.commit();
        sqlSession.close();
    }

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

6、模糊查询

1、Java代码执行的时候,传递通配符% %

List<User> userList = mapper.getUserLike("%张%");

2、在sql拼接字符串

 where name LIKE "%"#{value }"%"

4、配置解析

1、核心配置文件

2、环境配置(environments)

MyBatis 可以配置成适应多种环境

掌握

Mybatis默认是事务管理器是JDBC 连接池:POOLED

3、属性(properties)

我们可以通过properties属性来实现引用配置文件

这些属性可以在外部进行配置,并可以进行动态替换。你既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置【db.properties】

编写一个配置文件

db.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf-8
username=root
password=123456

在核心文件引入映射

   <!--    引入外部配置文件-->
    <properties resource="db.properties">
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
    </properties>

4、类型别名(typeAliases)

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

   <!--    可以给实体类起别名-->
    <typeAliases>
        <typeAlias type="com.bing.pojo.User" alias="User"/>
    </typeAliases>

也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean

在扫描实体类的包,它的默认别名是这个类名的首字母的小写

<!--    可以给实体类起别名-->
<typeAliases>
   <package name="com.bing.pojo"/>
</typeAliases>

注解别名

@Alias("user")
public class User 

5、设置(settings)

这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。

技术图片

技术图片

6、其他配置

7、映射器(mappers)

Mapper

  <mappers>
        <mapper resource="com/bing/dao/UserMapper.xml"/>
    </mappers>

方式二使用class文件绑定注册

    <mappers>
        <mapper class="com.bing.dao.UserMapper"/>
    </mappers>

注意点:

方式三:使用扫描包

 <mappers>
        <package name="com.bing.dao"/>
    </mappers>

8、生命周期和作用域

作用域 、生命周期类别是至关重要的,因为错误的使用会导致非常严重的并发问题。

SqlSessionFactoryBuilder

SqlSessionFactory

SqlSession

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

数据库的字段

技术图片

public class User {

    private int id;
    private String name;
    private String password;
}

技术图片

select * from mybatis.user where id = #{id}

解决方法:

6、日志

6.1、日志工厂

如果一个数据库操作,出现了异常,我们需要排错,日志就是最好的帮手

技术图片

标准的STDOUT_LOGGING 日志

    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

技术图片

6.2、 LOG4J

什么是LOG4J?

  1. 先导入 LOG4J 的包
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

7、分页

为什么要分页?

7.1、使用Limit分页

语法 :select * from user limit startIndex,pageSize

接口

List<User> getUserLimit(Map<String, Integer> map);

Mapper.xml

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

7.2、RowBounds分页

接口

List<User> getUserRowBounds();

mapper.xml

<select id="getUserRowBounds"  resultMap="UserMap">
    select *
    from mybatis.user
</select>

测试

@Test
public void getUserByRowBounds() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();

    RowBounds rowBounds = new RowBounds(1, 2);
    
    //通过java代码层面实现分页
    List<User> userList = sqlSession.selectList("com.bing.dao.UserMapper.getUserRowBounds", null, rowBounds);
    for (User user : userList) {
        System.out.println(user);
    }
}

8、使用注解开发

1、注解在接口上实现

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

2、在核心文件配置

<!--绑定接口-->
<mappers>
    <mapper class="com.bing.dao.UserMapper"/>
</mappers>

3、测试

@Test
public void test() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    List<User> users = mapper.getUsers();
    for (User user : users) {
        System.out.println(user);
    }
    sqlSession.close();
}

8.3、CRUD

我们可以在工具类自动提交事务

开启自动提交事务

public static SqlSession getSqlSession() {
    return sqlSessionFactory.openSession(true);
}
 @Select("select *from user")
    List<User> getUsers();

    @Select("select * from user where id=#{id}")
    User getUserById(@Param("id") int id);


    @Insert("insert into user (id,name,pwd) values (#{id},#{name},#{password})")
    int addUser(User user);

    @Update("update user set name=#{name} ,pwd=#{password} where id=#{id}")
    int updateUser(User user);

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

必须将接口注册绑定到注册中心

<!--绑定接口-->
<mappers>
    <mapper class="com.bing.dao.UserMapper"/>
</mappers>

@Param注解

{}预编译的 ,能防止SQL注册

${}直接编译的,无法预防SQL注解

9、Lombok

project lombok是一个java库,它可以自动插入到编辑器和构建工具中,提高java的效率。

永远不要再编写另一个getter或equals方法,使用一个注释,您的类有一个功能齐全的生成器,自动记录变量,等等。

使用步骤:
1、在IDEA中安装Lombok插件

2、导入依赖

 <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>

        </dependency>
@Getter and @Setter
@FieldNameConstants
@ToString
@EqualsAndHashCode
@AllArgsConstructor, @RequiredArgsConstructor and @NoArgsConstructor
@Log, @Log4j, @Log4j2, @Slf4j, @XSlf4j, @CommonsLog, @JBossLog, @Flogger, @CustomLog
@Data
@Builder
@SuperBuilder
@Singular
@Delegate
@Value
@Accessors
@Wither
@With
@SneakyThrows
@val
@var
experimental @var
@UtilityClass
Lombok config system
Code inspections
Refactoring actions (lombok and delombok)
@Data:无参构造,get,set,toString,

10、多对一处理

多对一:就好比多个学生对一个老师

对于学生而言,就是多对一,多个学生关联一个

对于老师而言,就是一对多,集合 一个老师有很多学生

技术图片

SQL:

测试环境搭建

  1. 导入Lombok
  2. 新建实体类Teacher,Student
  3. 建立Mapper接口
  4. 建立Mapper.xml
  5. 在核心配置文件中绑定注册我们的Mapper接口或者文件
  6. 测试能否成功

按照查询嵌套处理

  <resultMap id="StudentTeacher" type="com.bing.pojo.Student">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <!--        复杂的属性,我们需要单独处理
                对象:association
                集合:collection
        -->
        <association property="teacher" column="tid" javaType="com.bing.pojo.Teacher" select="getTeacher"/>

    </resultMap>
    <select id="getStudent" resultMap="StudentTeacher">
        select * from student
    </select>
<select id="getTeacher" resultType="com.bing.pojo.Teacher">
    select * from teacher where id = #{id}
</select>

按照结果嵌套处理

  <select id="getStudent2" resultMap="StudentTeacher2">
        select s.id sid, s.name sname, t.name tname
        from student s,
             teacher t
        where s.tid = t.id
    </select>
    <resultMap id="StudentTeacher2" type="com.bing.pojo.Student">
        <result property="id" column="sid"/>
        <result property="name" column="sname"/>
        <association property="teacher" javaType="com.bing.pojo.Teacher" >
            <result property="name" column="tname"/>

        </association>
    </resultMap>

MySQL多对一查询方式

  1. 子查询
  2. 链表查询

11、一对多

例如:老师对应多个学生

按照结果嵌套查询

<select id="getTeacher" resultMap="TeacherStudent">
    select s.id sid, s.name sname, t.name tname, t.id tid
    from teacher t,
         student s
    where s.tid = t.id
      and t.id = #{tid}
</select>
<resultMap id="TeacherStudent" type="com.bing.pojo.Teacher">
    <result property="id" column="tid"/>
    <result property="name" column="tname"/>
    <collection property="students" ofType="com.bing.pojo.Student">
        <result property="id" column="sid"/>
        <result property="name" column="sname"/>
        <result property="tid" column="tid"/>

    </collection>

</resultMap>

按照查询嵌套

<select id="getTeacher2" resultMap="TeacherStudent2">
    select *
    from teacher
    where id = #{tid}
</select>
<resultMap id="TeacherStudent2" type="com.bing.pojo.Teacher">
    <collection property="students" javaType="ArrayList" ofType="com.bing.pojo.Student" column="id"
                select="getStudentByTeacherId">
    </collection>
</resultMap>
<select id="getStudentByTeacherId" resultType="com.bing.pojo.Student">
    select *
    from student
    where tid = #{tid}
</select>
  1. 关联-association 【多对一】
  2. 集合-collection 【一对多】
  3. JavaType & ofType
    1. JavaType用来指定实体类中的类型
    2. ofType用来指定映射到List或者集合中的POJO类型,泛型中的约束类型

注意:

12、动态 SQL

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

如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。

if
choose (when, otherwise)
trim (where, set)
foreach

搭建环境

编写数据库

创建工程

  1. 导入包
  2. 修改配置文件
  3. 编写实体类

IF

<select id="queryBlogIF" parameterType="map" resultType="com.bing.pojo.Blog">
    select * from mybatis.blog where 1=1
    <if test="title!=null ">
        and title =#{title}
    </if>
    <if test="author!=null">
        and aothor =#{aothor}
    </if>
</select>

choose (when, otherwise)

<select id="queryBlogChoose" resultType="com.bing.pojo.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>

trim (where, set)

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

SQL片段

使用SQL标签抽取公共部分

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

在需要使用地方使用include标签

select * from mybatis.blog
<where>
    <include refid="if-title"></include>
</where>

foreach

<select id="queryBlogForeach" resultType="com.bing.pojo.Blog" parameterType="map">
    select * from blog
    <where>
        <foreach collection="ids" item="id" open="and (" close=")" separator="or">
            id=#{id}
        </foreach>

    </where>
</select>
@Test
public void TestForEach(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BiogMapper mapper = sqlSession.getMapper(BiogMapper.class);

    HashMap map = new HashMap();
    ArrayList<Integer> ids = new ArrayList<Integer>();
    ids.add(1);
    ids.add(2);
    ids.add(3);
    map.put("ids",ids);
    List<Blog> blogs = mapper.queryBlogForeach(map);
    for (Blog blog : blogs) {
        System.out.println(blog);
    }


    sqlSession.close();
}

动态SQL就是在拼接SQL语句,我们只要保证SQL的正确性,按照SQL的格式,去排列组合就好了

MySQL引擎

INNODB底层原理

索引

索引优化

13、缓存

查询:连接数据库,耗资源
	一次查询的结果,给它暂存在一个可以直接取到的地方!-->内存:缓存
	
我们再次查询直接走缓存,就快很多

13.1、介绍

1.什么是缓存 (读写分离,主从复制

2.为什么要使用缓存?

3.什么样的数据能使用缓存

13.2Mybatis缓存

13.3、一级缓存

测试:

1.开启日志

2.测试在一个SqlSession中查询两次相同记录

3.查看结果

技术图片

缓存失效:

  1. 执行增删改都会失效
  2. 手动清理

一级缓存就是一个map

13.4、二级缓存

步骤:

  1. 开启全局缓存

    <!--开启全局缓存-->
    <setting name="cacheEnabled" value="true"/>
    
  2. 在需要开启的地方使用自定义参数

    <!--  在当前Mapper.xml文件中使用二级缓存  -->
    <cache
            eviction="FIFO"
            flushInterval="60000"
            size="512"
            readOnly="true"/>
    
  3. 测试

    1. 问题:我们徐将实体类序列化,否则会报错

      public class User implements Serializable
      

小结:

13.5、缓存的原理

技术图片

13.6、自定义缓存-EhCache

Ehcache是一种广泛使用的开源Java分布式缓存。主要面向通用缓存,Java EE和轻量级容器。

<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!