一、前期准备

1.数据库问题

    由于教程中数据库使用的是mysql,需要重新安装mysql相应文件,在一番下载后,发现mysql的调试工具无法汉化,而距离课设结束没有几天了,在咨询了同学之后使用了navicat数据库管理软件

    而在下载过后又发现需要激活,由于连接以丢失,这里不放出下载地址了。

    安装好后的navicat很好用,能够同时调用sqlserver和mysql

1.1navicat

在页面上点击连接后出现以下界面,其中连接名自己写,只是一个标识,无特殊含义。

主机名:这里是本地数据库所以直接填写localhost

端口号:默认3306

用户名和密码是在安装mysql安装时设置的

连接成功后就可以对数据库进行更改了

2.idea与数据库对接

在idea最右侧,点击DataBase,选择Data Source 点击mysql输入跟上面navicat一样的东西后测试连接

这里报了一个

错误,这是由于mysql时区没有设置导致的

进入命令窗口(Win + R),连接数据库 mysql -hlocalhost -uroot -p,回车,输入密码,回车

继续输入 show variables like'%time_zone'; (注意不要漏掉后面的分号),回车

显示 SYSTEM 就是没有设置时区

输入set global time_zone = '+8:00'; 注意不要漏掉后面的分号),回车

设置成功

3.为什么我们需要Mybatis

  • 相比JDBC,更加方便,JDBC太麻烦了
  • 简化,框架,自动化
  • 将数据存入到数据库
  • 优点
    • 简单易学
    • 灵活
    • 解除sql与代码的耦合,sql和代码的分离
    • 提供映射标签
    • 提供关系映射
    • 提供XML标签
  • 最重要的一点;用的人多

4.怎么获得Mybatis

<!--mybatis驱动-->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.2</version>
</dependency>

二、第一个Mybatis程序

思路:

  1. 搭建环境
  2. 导入Mybatis
  3. 编写代码
  4. 测试

2.1搭建环境

  • 搭建数据库
create database `mybatis`;
use `mybatis`;
create table `user`(
    `id`int(20)  not null,
    `name` varchar(30) default null,
    `pwd`varchar(30) default null,
    primary key(`id`)
)engine=InnoDB default charset = utf8;

insert into `user`(`id`,`name`,`pwd`)values
(1,'zhaox','zhaosiyu123'),
(2,'admin','123456'),
(3,'张三','1236456')
  • 导入依赖:
    1. maven
    2. mysql
    3. junit
<dependencies>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.2</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.20</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13</version>
    </dependency>
</dependencies>
  • 删除src,使其成为父工程

2.2创建一个模块

  1. 编写一个mybatis的核心配置文件
    • 创建在模块的src——resource目录下,名字叫mybatis-config.xml
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--configuration核心配置文件-->
<configuration>
    <!--配置多套环境-->
    <environments default="development">
        <environment id="development">
            <!--事务管理-->
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!--properties文件里的东西-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url"
                          value="jdbc:mysql://127.0.0.1:3306/mybatis?useSSL=true&useUnicode=true&serverTimezone=GMT&characterEncoding=utf-8"/>
                <property name="username" value="root"/>
                <property name="password" value="zhaosiyu123"/>
            </dataSource>
        </environment>
    </environments>

    <!--每一个Mapper.xml都需要在Mybatis核心配置文件中注册-->

</configuration>

url中设置数据库的位置,是否使用ssl安全连接,是否使用Unicode编码,是否使用UTF-8编码等
&为的意思最后一个不用
核心配置文件做了一件事情——连接数据库

  1. 编写Mybatis的工具类
    • 使用Mybatis第一步:获取sqlSessionFactory对象
String resource = "xxx-config.xml";//数据库配置文件
InputStream inputStream = Resources.getResourceAsStream(resource);//通过配置得到一个输入流
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//通过工厂构造器得到工厂
//sqlSessionFactory——>sqlSession
public class MybatisUtils {
    private static SqlSessionFactory sqlSessionFactory;
    static{
        String resource = "mybatis-config.xml";//数据库配置文件
        InputStream inputStream = null;//通过配置得到一个输入流
        try {
            inputStream = Resources.getResourceAsStream(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//通过工厂构造器得到工厂
    }
}
public static SqlSession getSqlSession() {
       return sqlSessionFactory.openSession();
}//得到SqlSession

先静态通过工厂构造器加载变成了流的数据库配置文件,创建一个工厂,注意提升作用域,static块里的只在块内有效。
然后创建一个得到sqlsession的方法。

2.3编写代码

  • 实体类
    • 写实体类注意,要与数据库的属性名字对应,不能变
  • Dao接口
  • Dao实现

以上是以前没有mybatis的时候我们写底层数据库交互的方法,需要大量各种参数,还要手动关闭资源,不过现在mybatis都帮我们做了

现在可以直接写一个UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!--namespace=绑定一个对应的Dao/Mapper接口-->
<mapper namespace="com.zhaox.dao.FBMapper">
    <!--查询语句-->
    <!--id:对应方法名字,相当于接口实现类的方法名字-->
    <!--resultType: -->
    <select id="getFBList" resultType="com.zhaox.pojo.FB">
        select * from zhaox.FB;
    </select>
</mapper>

接口实现类由原来的impl变成一个mapper配置文件

2.4测试

注意几个问题

  1. 首先要注意每一个Mapper必须要注册,感觉有点麻烦

  2. 其次,由于这个是xml文件,而maven默认的xml文件在resource目录下,约定大于配置,如果我们不去maven里进行配置,我们会遇上一个初始化失败的额问题

    <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. 有可能遇上绑定接口出错的问题

  4. 命名空间出错(别直接复制啦!):在命名空间中绑定的时候必须用‘.’点!

  5. 与上面不同,在核心配置文件中配置mapper,必须用'/'斜杠!

衍生问题:在项目里遇见了1字节utf-8报错问题

编码格式错误,可以在idea中设置一下UTF-8编码

三、CRUD

3.1查询

  1. 先去UserMapper写接口
//根据id查询用户
User getUserById(int id);
  1. 再去xml里写sql语句:注意几点
    1. id是方法名字
    2. resultType是返回值类型
    3. parameterType是参数类型
<select id="getUserById" resultType="com.zhaox.pojo.User" parameterType="int">
    select * from mybatis.user where id = #{id}
</select>

3.2增加

切记!增删改要提交事务!

从这里开始代码基本就是重复的了,实现起来基本都是接口加xml

<!--对象中的属性可以直接取出来-->
<insert id="addUser" parameterType="com.zhaox.pojo.User">
    insert into mybatis.user (id, name, pwd) values (#{id},#{name},#{pwd});
</insert>

在这里的参数是一个实体类,这个实体类的参数是可以用#{}直接提取出来的,注意,括号内的名字必须与实体类的属性名字相同

3.3删除

删除用户只需要传入一个id就可以了

<!--删除用户-->
<delete id="deleteUser" parameterType="int">
    delete from mybatis.user where id = #{id};
</delete>

3.4更改

<!--更新用户数据-->
<update id="updateUser" parameterType="com.zhaox.pojo.User">
    update mybatis.user set name=#{name},id=#{id},pwd=#{pwd} where id = #{id} ;
</update>

有增加功能代码几乎一致

测试类不变的代码

SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);

//中间是增删改查代码

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

万能Map

​ 在进行增删改的时候虽然通过XML很方便就能做到,但是经常有传入类型为User的情况,比如修改用户信息的方法就是传入了一个User,如果用户的字段少还好说,如果字段为100个,我们就需要一个一个去赋值,十分的麻烦,如果我们是真的想修改全部字段还好,如果我们只想修改一个字段却不得不写99个其他无用的字段就实在是太得不偿失了。

​ 因此,我们使用一个万能的map。

​ 首先,我们在传入参数的部分将参数类型设置为map

//通过map的方式修改用户
int updateUserByMap(Map<String,Object> map);

​ 然后,我们在XML中只需要根据map的key进行修改就可以了

<!--通过map更新用户数据-->
<update id="updateUserByMap" parameterType="map">
    update mybatis.user set name=#{MapName} where id = #{id} ;
</update>
 HashMap<String, Object> map = new HashMap<>();
        map.put("id",1);
        map.put("name","zhaoxxx");

        mapper.updateUserByMap(map);

当然,如果传入参数不是User,只是基本类型,那么同样可以用map来传入多个参数。

或者用注解

模糊查询

  1. 第一种,在传入的时候输入百分号占位符
List<user> userList  = mapper.getUserLike(%李%);
  1. 第二种,直接在sql语句写四
select * from mybatis.user where name like "%"#{value}"%"

四、配置解析

1. 核心配置文件

核心配置文件里要用“/”来分包

1.1环境配置Environments

<environments default="development">
    <environment id="development">
        <!--事务管理-->
        <transactionManager type="JDBC"/>
        <dataSource type="POOLED">
            <!--properties文件里的东西-->
            <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/>
            <property name="username" value="root"/>
            <property name="password" value="zhaosiyu123"/>
        </dataSource>
    </environment>
</environments>

environments下可以写多套环境。

不过要记住:尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。

environments后的default代表默认选择的环境,是根据id来选择的

  • transactionManager:事务管理器

    事务管理器有两种:JDBC,MANAGED

  • dataSource:数据源

    数据源是用来连接数据库的

    有三种内建的数据源类型(也就是 type="[UNPOOLED|POOLED|JNDI]")

    • POOLED:数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;
    • UNPOOLED:这个数据源的实现会每次请求时打开和关闭连接。
    • JNDI

mybtais默认事务管理器是JDBC,数据源类型默认是POOLED

1.2properties(属性)

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

<dataSource type="POOLED">
            <!--properties文件里的东西-->
            <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/>
            <property name="username" value="root"/>
            <property name="password" value="zhaosiyu123"/>
        </dataSource>

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

  1. 编写一个配置文件db.properties
    driver=com.mysql.cj.jdbc.Driver
    url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8
    username=root
    password=zhaosiyu123
    
  2. 在核心配置文件中映入

  • 注意:在核心配置文件中必须遵守顺序,所以properties标签必须排在第一个
    <!--引入properties文件-->
       <properties resource="db.properties">
    
  • 因为我们是在resource文件夹下写的properties文件,所以不需要去写前面的路径

    之前写MapperXML文件的时候,必须要在核心文件中配置路径,就是因为这个XML文件来应该是写在Resource文件夹下的,同理,Maven无法导出XML文件也是同一个原因

  • 配置完文件之后是可以不在外部配置文件中全部写完的。

    <!--引入properties文件-->
    <properties resource="db.properties">
       <property name="username" value="asdasdasd"/>
    </properties>
    

    虽然我感觉有点脱裤子放屁的嫌疑不过还是先记上吧

    另外核心配置文件默认是优先读取外部配置文件的属性的。

注意:在核心配置文件中url需要&作为转义字符,而在properties文件是不需要的,要去掉。

总结:

  1. 属性是可以引入外部问价的。
  2. 同时也可以在内部加一些字段
  3. 如果两者冲突以外部为准
  4. 在引入时要注意:
    1. 在核心配置文件中必须遵守顺序,所以properties标签必须排在第一个
    2. 因为我们是在resource文件夹下写的properties文件,所以不需要去写前面的路径

2.别名优化

com.zhaox.pojo.User,这种对象名字,很反人类,所以要优化

第一种优化方式:

<!--别名优化-->
<typeAliases>
    <typeAlias type="com.zhaox.pojo.User" alias="User"/>
</typeAliases>

这样就可以在Mapper里直接写User了

第二种方式:

<!--别名优化-->
<typeAliases>
    <package name="com.zhaox.pojo"/>
</typeAliases>

它会自动扫描这个包,它会自动读取类的名字,名字首字母小写就是他的别名

第一种是自定义别名

第二种如果有注解,则别名为注解值@Alias("a")

另外基本类型的别名要注意:基本类型前面要加__,不加则代表他的包装类型:

_byte byte
_long long
_short short
_int int
_integer int
_double double
_float float
_boolean boolean
string String
byte Byte
long Long
short Short
int Integer
integer Integer
double Double
float Float
boolean Boolean
date Date
decimal BigDecimal
bigdecimal BigDecimal
object Object
map Map
hashmap HashMap
list List
arraylist ArrayList
collection Collection
iterator Iterator

3.设置

mybatis中极为重要的调整设置,它们会改变Mybatis的运行时行为


开启缓存和懒加载。


一个配置完整的 settings 元素的示例如下:

<settings>
  <setting name="cacheEnabled" value="true"/>
  <setting name="lazyLoadingEnabled" value="true"/>
  <setting name="multipleResultSetsEnabled" value="true"/>
  <setting name="useColumnLabel" value="true"/>
  <setting name="useGeneratedKeys" value="false"/>
  <setting name="autoMappingBehavior" value="PARTIAL"/>
  <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
  <setting name="defaultExecutorType" value="SIMPLE"/>
  <setting name="defaultStatementTimeout" value="25"/>
  <setting name="defaultFetchSize" value="100"/>
  <setting name="safeRowBoundsEnabled" value="false"/>
  <setting name="mapUnderscoreToCamelCase" value="false"/>
  <setting name="localCacheScope" value="SESSION"/>
  <setting name="jdbcTypeForNull" value="OTHER"/>
  <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>

4.插件

这些是能提高Mybatis效率的插件

  • Mybatis-generatop-core
  • Mybatis-plus
  • 通用Mapper

5.映射器(Mappers)

MapperRegistry:注册绑定我们的Mapper文件:

方式一:使用相对路径【推荐使用】

<!--每一个Mapper.xml都需要在Mybatis核心配置文件中注册-->
<mappers>
    <mapper resource="com/zhaox/Mapper/UserMapper.xml"/>
</mappers>

方式二:使用接口实现类

<mappers>
    <!--        <mapper resource="com/zhaox/Mapper/UserMapper.xml"/>-->
    <mapper class="com.zhaox.Mapper.UserMapper"/>
</mappers>

如果使用这种方式要注意:

  1. 接口和他的Mapper要同名
  2. 两者必须在同一个包下

方式三:同过Packeg扫描

<mappers>
    <!--        <mapper resource="com/zhaox/Mapper/UserMapper.xml"/>-->
    <!--        <mapper class="com.zhaox.Mapper.UserMapper"/>-->
    <package name="com.zhaox.Mapper"/>
</mappers>

也要注意以下两点:

  1. 接口和他的Mapper要同名
  2. 两者必须在同一个包下


醉后不知天在水,满船清梦压星河