狂神说MyBatis学习笔记(自整理自用)

MyBatis

MyBatis官网地址:https://mybatis.org/mybatis-3/

MyBatis官网中文版:https://mybatis.org/mybatis-3/zh/index.html

1、使用MyBatis之前的配置

第一步:在Maven项目中配置MyBatis依赖(pom.xml文件)

<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>x.x.x</version><!--x.x.x代表的是mybatis引入依赖的版本号,这里我使用的是3.5.2-->
</dependency>

第二步:配置mybatis-config.xml文件

官方模板

<?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">
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <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>
        <mapper resource="org/mybatis/example/BlogMapper.xml"/>
    </mappers>
</configuration>

实际配置

<?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">
<configuration>
    <environments default="development">
        <environment id="development">
            <!--数据库的配置-->
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=utf8"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!--每个Mappers.xml都需要在Mybatis核心配置文件中注册-->
    <mappers>
        <!--这里的文件路径为工程中src下XML文件的路径-->
        <mapper resource="org/mybatis/example/BlogMapper.xml"/>
    </mappers>
</configuration>

第三步:创建工具类

官网获取SqlSessionFatroy的方式

String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

创建名为“mybatis”的数据库

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 mybatis.user(id,name,pwd) values
(1,'张三',123456),
(2,'李四',456123)

实际创建获取SqlSession工具类的java代码

package com.company.utils;

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 java.io.IOException;
import java.io.InputStream;

public class MyBatisUtils {
    private static SqlSessionFactory sqlSessionFactory;
    static{

        try {
            //使用Mybatis第一步,获取SqlSessionFactory对象
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //既然有了SqlSessionFactory顾名思义,我们就可以从中获得SqlSession的实例。
    //SqlSession完全包含了面向数据库执行SQL指令所需的所有方法
    public static SqlSession getSqlSession(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        return sqlSession;
    }
}

2、真实的使用过程

实体类pojo

package com.company.pojo;

//定义User属性
public class User {
    private int id;
    private String name;
    private String pwd;

    public User() {
    }

    public User(int id, String name, String pwd) {
        this.id = id;
        this.name = name;
        this.pwd = pwd;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", pwd='" + pwd + '\'' +
                '}';
    }
}

接口类dao,定义接口

package com.company.dao;

import com.company.pojo.User;

import java.util.List;
import java.util.Map;

public interface UserDao {
    List<User> getUserList();
}

接口实现类UserDaoMapper.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">
<!--UserDao实现类-->
<mapper namespace="com.company.dao.UserDao">
    
    <!--sql查询语句-->
    <select id="getUserList" resultType="com.company.pojo.User">
        select * from mybatis.user
    </select>
</mapper>

配置文件的更改(pom.xml)

<!--默认UserDaoMapper.xml在resources文件夹下,放在java文件夹下要手动导入-->

<!--maven由于它的约定大于配置,配置文件无法被导出生效,解决方案,在build中配置resources来防止我们资源导出失败的问题-->
<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>

测试类test

import com.company.dao.UserDao;
import com.company.pojo.User;
import com.company.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class test {

    @Test
    public void test(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        List<User> userList = userDao.getUserList();
        for(User user:userList){
            System.out.println(user);
        }
        sqlSession.close();
    }
}

3、增删改查

3.1、增加用户信息

UserDao

void addUser(User user);

UserDaoMapper

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

Test

SqlSession sqlSession = MyBatisUtils.getSqlSession(); 
UserDao userDao = sqlSession.getMapper(UserDao.class);
userDao.addUser(new User(5,"王五","4567892"));
//提交事务
sqlSession.commit();
sqlSession.close();

3.2、删除用户信息

UserDao

void deleteUserById(int id);

UserDaoMapper

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

Test

SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserDao userDao = sqlSession.getMapper(UserDao.class);
userDao.deleteUser(5);

//提交事务
sqlSession.commit();

3.3、修改用户信息

UserDao

void updateUser(User user);

UserDaoMapper

<update id="updateUser" parameterType="int">
    update mybatis.user set name=#{name},pwd=#{pwd} where id=#{id}
</update>

Test

SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserDao userDao = sqlSession.getMapper(UserDao.class);
userDao.updateUser(new(4,"zhangsan","jds4466"));

//提交事务
sqlSession.commit();

3.4、查找用户信息

UserDao

User getUserById(int id);

UserDaoMapper

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

Test

SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserDao userDao = sqlSession.getMapper(UserDao.class);
User user = userDao.getUserById(4);
System.out.println(user);

4、万能的Map

假设实体类或数据库中的表,字段或者参数过多,我们可以考虑使用Map,来减少sql语句的的代码量怎么减少的,丝毫没有感觉到

4.1、例一:添加用户信息

UserDao接口

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

UserDaoMapper.xml

<insert id="addUser2" parameterType="map" resultType="int">
    insert into mybatis.user (id,name,pwd) values (#{userid},#{username},#{userpwd})
</insert>

Test

SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserDao userDao = sqlSession.getMapper(UserDao.class);
Map<String,Object> map = new HashMap<String,Object>();
map.put("userid",2);
map.put("username","啊呜");
map.put("userpwd","456ssfde")
userDao.addUser2(map);
sqlSession.commit();
sqlSession.close();

4.2、例二:通过用户id查找用户信息

UserDao接口

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

UserDaoMapper.xml

<select id="getUserById2" parameterType="map" resultType="com.company.pojo.User">
    select * from mybatis.user where id=#{userid} or name=#{username}
</select>

Test

SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserDao userDao = sqlSession.getMapper(UserDao.class);
Map<String,Object> map = new HashMap<String,Object>();
map.put("userid",1);
map.put("username","l")
userDao.getUserById2(map);
sqlSession.close();

5、模糊查询

UserDao

List<User> getUserLike(String value);

UserDaoMapper

<select id="getUserLike" resultType="com.company.pojo.User">
    select * from mybatis.user where name like"%"#{value}"%"
</select>

Test

SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserDao userDao = sqlSession.getMapper(UserDao.class);
List<User> userList = userDao.getUserLike("%王%");

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

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

6、配置解析

6.1、mybatis核心配置文件(mybatis-config.xml)

  1. MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。 配置文档的顶层结构如下:

  2. configuration(配置)

    • properties(属性)

    • settings(设置)

    • typeAliases(类型别名)

    • typeHandlers(类型处理器)

    • objectFactory(对象工厂)

    • plugins(插件)

    • environments(环境配置)

      • environment(环境变量)
        • transactionManager(事务管理器)
        • dataSource(数据源)
    • databaseIdProvider(数据库厂商标识)

    • mappers(映射器)

6.2、environments(环境配置)

MyBatis可以适应多种环境,这种机制有助于SQL映射应用于多种数据库中,尽管可以配置多个环境,但每个SqlSessionFactory实例只能选择一个环境。

environments元素定义了如何配置环境。

<environments default="development">
  <environment id="development">
    <transactionManager type="JDBC">
      <property name="..." value="..."/>
    </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>

注意:

  1. 默认使用的环境ID(比如:default=“development”)
  2. 每个environment元素定义的环境ID(比如:id=“development”)
  3. 事务管理器的配置(type=“JDBC”)
  4. 数据源的配置(比如:type=“POOLED”)

事务管理器(transactionManager)

在MyBatis中有两中类型的事务管理器(type="[JDBC|MANAGED]")

  • JDBC——这个配置直接使用了JDBC的提交和回滚设施,它依赖从数据源获得的连接来管理事务作用域。
  • MANAGED——这个配置几乎没做什么,它从不提交或回滚一个连接来,而是让容器来管理事物的整个生命周期,

数据源(dataSource)

dataSource元素使用标准的JDBC数据源接口来配置JDBC连接对象的资源。

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

UNPOOLED– 这个数据源的实现会每次请求时打开和关闭连接。虽然有点慢,但对那些数据库连接可用性要求不高的简单应用程序来说,是一个很好的选择。 性能表现则依赖于使用的数据库,对某些数据库来说,使用连接池并不重要,这个配置就很适合这种情形。UNPOOLED 类型的数据源仅仅需要配置以下 5 种属性:

  • driver – 这是 JDBC 驱动的 Java 类全限定名(并不是 JDBC 驱动中可能包含的数据源类)。
  • url – 这是数据库的 JDBC URL 地址。
  • username – 登录数据库的用户名。
  • password – 登录数据库的密码。
  • defaultTransactionIsolationLevel – 默认的连接事务隔离级别。
  • defaultNetworkTimeout – 等待数据库操作完成的默认网络超时时间(单位:毫秒)。查看 java.sql.Connection#setNetworkTimeout() 的 API 文档以获取更多信息。

作为可选项,你也可以传递属性给数据库驱动。只需在属性名加上“driver.”前缀即可,例如:

  • driver.encoding=UTF8

这将通过 DriverManager.getConnection(url, driverProperties) 方法传递值为 UTF8encoding 属性给数据库驱动。

POOLED– 这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。 这种处理方式很流行,能使并发 Web 应用快速响应请求。

除了上述提到 UNPOOLED 下的属性外,还有更多属性用来配置 POOLED 的数据源:

  • poolMaximumActiveConnections – 在任意时间可存在的活动(正在使用)连接数量,默认值:10
  • poolMaximumIdleConnections – 任意时间可能存在的空闲连接数。
  • poolMaximumCheckoutTime – 在被强制返回之前,池中连接被检出(checked out)时间,默认值:20000 毫秒(即 20 秒)
  • poolTimeToWait – 这是一个底层设置,如果获取连接花费了相当长的时间,连接池会打印状态日志并重新尝试获取一个连接(避免在误配置的情况下一直失败且不打印日志),默认值:20000 毫秒(即 20 秒)。
  • poolMaximumLocalBadConnectionTolerance – 这是一个关于坏连接容忍度的底层设置, 作用于每一个尝试从缓存池获取连接的线程。 如果这个线程获取到的是一个坏的连接,那么这个数据源允许这个线程尝试重新获取一个新的连接,但是这个重新尝试的次数不应该超过 poolMaximumIdleConnectionspoolMaximumLocalBadConnectionTolerance 之和。 默认值:3(新增于 3.4.5)
  • poolPingQuery – 发送到数据库的侦测查询,用来检验连接是否正常工作并准备接受请求。默认是“NO PING QUERY SET”,这会导致多数数据库驱动出错时返回恰当的错误消息。
  • poolPingEnabled – 是否启用侦测查询。若开启,需要设置 poolPingQuery 属性为一个可执行的 SQL 语句(最好是一个速度非常快的 SQL 语句),默认值:false。
  • poolPingConnectionsNotUsedFor – 配置 poolPingQuery 的频率。可以被设置为和数据库连接超时时间一样,来避免不必要的侦测,默认值:0(即所有连接每一时刻都被侦测 — 当然仅当 poolPingEnabled 为 true 时适用)。

JNDI – 这个数据源实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的数据源引用。这种数据源配置只需要两个属性:

  • initial_context – 这个属性用来在 InitialContext 中寻找上下文(即,initialContext.lookup(initial_context))。这是个可选属性,如果忽略,那么将会直接从 InitialContext 中寻找 data_source 属性。
  • data_source – 这是引用数据源实例位置的上下文路径。提供了 initial_context 配置时会在其返回的上下文中进行查找,没有提供时则直接在 InitialContext 中查找。

和其他数据源配置类似,可以通过添加前缀“env.”直接把属性传递给 InitialContext。比如:

  • env.encoding=UTF8

这就会在 InitialContext 实例化时往它的构造方法传递值为 UTF8encoding 属性。

6.3、池用完可以回收

dataSource(Type=“POOLED”)是默认的,是一种使得并发Web应用快速响应请求的流行处理方式。

TransactionManager(type=“JDBC”)

6.4、属性(properties)实现引用文件

  1. db.properties

    driver=com.mysql.jdbc.Driver
    url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&amp;characterEncoding=utf8
    username=root
    password=123456
    
  2. 在核心配置文件中引入

    <!--引入外部配置文件-->
    <properties resource="db.properties"/>
    
    <properties resource="db.properties">
        <property name="username" value="root"/>
        <prooerty name="pwd" value="123456"/>
    </properties>
    
    • 可以直接引入外部文件
    • 可以在其中增加一些属性配置
    • 如果两个文件有同一个字段,优先使用外部配置文件中的

6.5、类型别名(typeAliases)mapper文件中

类型别名是为java类型设置一个短名字

存在的意义仅在于用来减少完全限定名的冗余

<typeAliases>
    <typeAlias type="com.company.pojo.User" alias="User"/>
</typeAliases>

也可以指定一个包名,MyBatis会在包名下搜索需要的JavaBean,扫描实体类的包,它的默认别名就为这个类的类名首字母小写

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

实体类比较少时给实体类起别名,实体类比较多时给实体类的包起别名

区别:第一种可以自定义类名,第二种不可以自定义,但第二种可以在类上使用注解@Alias(“hello”)//这个类重命名为“hello”;

6.6、设置(settings)

mapUnderscoreToCamelCase:是否开启自动驼峰命名规则(camelcase)映射,即从经典数据库列名A_COLUMN到经典Java属性名aColumn的类似映射

logImpl:指定MyBatis所用日志的具体实现,未指定时将自动查找SJF4J**|LOG4J|LOG4J2|JDK_LOGGING|COMMONS_LOGGING|STDOUT_LOGGING|**NO_LOGGING

cacheEnabled:全局开启或关闭配置文件中的所有映射器已经配置的任何缓存。默认为true

lazyLoadingEnalbed:延迟加载的全局开关,当开启时所有关联对象都会延迟加载。特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态,默认为false

6.7、其他配置

typeHandler(类型处理器)

ObjectFactory(对象工厂)

plugins(插件)

mybatis-generator-core :mybatis代码自动生成

mybatis-plus

6.8、映射器(mappers)mapper文件中

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

  1. 使用相对于类路径的资源引用

    <mappers>
        <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
    </mappers>
    
  2. 使用class文件绑定注册,使用映射器接口实现类的完全限定名

    <mappers>
        <mapper class="org.mybatis.builder.AuthorMapper"/>
    </mappers>
    

注意:

接口和它的Mapper配置文件必须同名

接口和它的Mapper配置文件必须在同一包下

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

==注意:==使用扫描包进行注册绑定,必须同名且在同一包下

6.9、生命周期和作用域

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

这一块有一个流程图我给搞丢了。。。找回来回补上的。。。。

SqlSessionFactoryBuilder创建SqlSesssionFactory之后就不被需要了

6.10、属性名和字段名不一致(mapper文件中)

1、在SQL语句中给属性起别名

<select id="getUserById" resultType="com.company.pojo.User">
    select id,name,pwd as password from mybatis.user where id=#{id}
</select>

2、resultMap:结果集映射

这里select *填的是字段名还是属性名,也就是说是别名还是数据库字段名称

<resultMap id="UserMap" type="User">
    <result colum="id",property="id"/>
    <result colum="name",property="name"/>
    <result colum="pwd",property="password"/>
</resultMap>


<select id="getUserById" resultMap="UserMap">
    select * from mybatis.user where id=#{id}
</select>

resultMap元素是MyBatis中最重要的元素,对于复杂一点的语句只要描述他们的关系就好了

6.11、日志

6.11.1、日志工厂

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

logImpl:指定MyBatis所用日志的具体实现,未指定时将自动查找

SLF4J | LOG4J (掌握) | LOG4J2

JDK_LOGGING COMMONS_LOGGING STDOUT_LOGGING(掌握)

​ 控制台输出(标准日志输出)

NO_LOGGING

在MyBatis中具体使用哪一个,我们在设置中设定

<!--标准日志工厂实现配置-->
<settings>
    <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>

6.11.2、LOG4J外部类

  • 一个Apache的一个开源项目
  • 可以控制日志的输出格式
  • 通过定义每一条日志的信息级别,能细致的控制日志的生成过程
  • 通过配置文件配置,不需要修改应用代码
  1. 先导入LOG4J的包,在配置文件(pom.xml)中配置依赖

    <dependency>
        <groudId>log4j</groudId>
        <artifactId>/log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
    
  2. log4j.properties

    #log4j.rootLogger=DEBUG,console,file
    # 输入到文件中
    # log4j.appender.file.Append = ture
    #默认为true,上面一条语句添加到程序的末尾,false在每次启动时覆盖
    #一个log文件的大小超过这个大小就会生成一个日志
    #log4j.appender.file.MaxFileSize=1MB
    
    
    
    #将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码中
    log4j.rootLogger = DEBUG,console,file
    
    #控制台输入的相关设置
    log4j.appender.console = org.apache.log4j.ConsoleAppender
    log4j.appender.console.Target = System.out
    log4j.appender.console.Threshold = DEBUG
    log4j.appender.console.layout = org.apache.log4j.PatternLayout
    log4j.appender.console.layout.ConversionPatten = [%c]-%m%n
    
    #文件输出的相关设置
    log4j.appender.file = org.apache.log4j.RollingFileAppender
    log4j.appender.file.File = ./log/company.log
    log4j.appender.file.MaxFileSize = 10MB
    log4j.appender.file.Threshold = DEBUG
    log4j.appender.file.layout = org.apache.log4j.PatternLayout
    log4j.appender.file.ConversionPattern = [%P][%d{yy-MM-dd}][%c]%m%n
    
    #日志输出级别
    log4j.logger.org.mybatis = DEBUG
    log4j.logger.java.sql = DEBUG
    log4j.logger.java.sql.Statement = DUBEG
    log4j.logger.java.sql.ResultSet = DEBUG
    log4j.logger.java.sql.PreparedStatement = DEBUG
    
  3. 配置log4j为日志的实现(在mybatis-config核心配置文件里)

    <!--配置log4j为日志实现-->
    <settings>
        <setting name="logImpl" value="LOG4J"/>
    </settings>
    
  4. LOG4J的使用

    简单使用

    • 在要使用LOG4J的类中导入import org.apache.log4j.Logger;

    • 日志对象,加载参数为当前类的class

      static Logger logger = Logger.getLogger(UserTest.class);
      
  5. 日志级别

    logger.info("info:进入了testlog4j");
    logger.debug("debug:进入了testlog4j");
    logger.error("error:进入了testlog4j");
    

核心配置文件(mybatis-config.xml)

<?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">
<configuration>
    <properties resource="src/resources/db.properties"/>
    <!--配置log4j为日志实现-->
    <settings>
        <setting name="logImpl" value="LOG4J"/>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    <typeAliases>
        <!--<package name="com.company.pojo"/>-->
        <typeAlias type="com.company.pojo.User" alias="User"/>
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <!--数据库的配置-->
            <transactionManager type="JDBC"/>
            <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.xml都需要在Mybatis核心配置文件中注册-->
    <mappers>
        <mapper resource="com/company/dao/UserDaoMapper.xml"/>
    </mappers>

</configuration>

7、分页

分页的目的:减少数据处理量

7.1使用limit分页

语法:select * from user limit StartIndex,PageSize;(前闭后开区间)

dao层

List<User> getUserByLimit(Map<String,Object> map);

UserMapper.xml

<select id="getUserByLimit" parameterType="map" resultType="User">
    select * from user limit #{startIndex},#{pageSize}
</select>

test

public void getUserByLimitTest(){
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    UserDao userDao = sqlSession.openSession(UserDao.class);
    Map<String,Object> map = new HashMap<String,Object>();
    map.put("startIndex",0);
    map.put("pageSize",5);
    List<User> list = userDao.getUserByLimit(map);
}

7.2、RowBounds分页

Dao层

List<User> userList = getUserByRowBounds();

UserMapper.xml

<select id = "getUserByRowBounds" resultMap = "UserMap">
    select * from user
</select> 

Test

public void getUserByRowBoundsTest(){
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    RowBounds rowBounds = new RowBounds(1,2);
    sqlSession.selectList("com.company.dao.UserDao.getUserByRowBounds",null,rowBounds);
}

7.3、使用分页插件——mybatis PageHelper

8、使用注解开发

8.1、面向接口编程

​ 原因:解耦,可扩展,提高服用,分层开发,上层不用管具体的实现,大家都遵守共同的标准,使得开发变得更加容易,规范性好

接口:

  1. 接口从更深层次的理解,应是定义与实现分离
  2. 接口的本身反应了系统的抽象理解
  3. 接口分为两大类
    • 抽象体
    • 抽象面

三个面向:

  1. 面向过程:考虑问题时只靠路具体流程
  2. 面向对象:考虑问题时以对象为单位,考虑它的属性和方法
  3. 面向接口:接口设计和非接口设计是针对复用技术而言的,与面向对象/过程不是一个问题,更多体现就是对系统整体的架构

8.2、使用注解开发

接口

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

在核心配置文件中绑定接口

<mappers>
    <mapper class="com.company.dao.UserDao"/>
</mappers>

本质:反射机制实现

底层:动态代理

9、MyBatis执行流程

这一块有一个流程图我给搞丢了。。。找回来回补上的。。。。

10、注解增删改查(CRUD)

10.1、方法存在多个参数时:所有的基本类型参数前面必须加上@Param("")的注解

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

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

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

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

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

10.2、设置自动提交事务

public void getSqlSession(){
    //……
    return sqlSessionFactory.openSession(true);
}

10.3、@Param注解

原则:基本类型参数或String类型需要加

​ 引用类型不需要加

​ SQL中引用类型就是@Param中设定的属性名

11、Lombok

11.1、使用步骤

  1. 在idea中配置Lombok依赖插件

  2. 在项目中导入Lombok的jar包

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.10</version>
    </dependency>
    
  3. 在实体类上加注解

11.2、Lombok的优缺点

优点:

  1. 让代码变得简洁,不用过多的去关注相应的方法
  2. 能通过注解的形式自动生成构造器,get/set/equels/hashcode/toString方法,提高了一定的开发效率
  3. 属性做修改的时候不需要修改对应的get/set/equels/hashcode/toString等方法

缺点:

  1. 不支持多种参数构造器的重载

  2. 虽然省去了手动创建get/set方法的麻烦,但大大降低了源码的可读性和完整性,降低了阅读源码的舒适度

    @Data:无参构造,get,set,toString,hashcode,equals
    @AllArgsConstructor:有参构造
    @NoArgsConstructor:无参构造
    @Getter:
    @Setter:
    

12、多对一&一对多

多个学生,对应一个老师

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

对于老师而言,一个老师有很多学生(一对多)集合关系

结果映射:association——一个复杂类型的关联

collection——一个复杂类型的集合

SQL

create table 'teacher'(
    'id' int(10) no null,
    'name' varchar(20) default null,
    primary key('id'),
)engine=innodb default charset=utf8;

insert into teacher('id','name') values (1,'秦老师');

create table 'student'(
    'id' int(10) no null;
    'name' varchar(20) default null,
    'tid' int(10) default null,
    primary key('id'),
    key 'fktid'('tid'),
    constraint 'fktid' foreign key('tid') peferences 'teacher'('id')
)engine=innodb default charset=utf8;

inset into 'student'('id','name','tid')values(1,'小明''1');
inset into 'student'('id','name','tid')values(2,'小红''1')

bean层

Student实体类

Teacher实体类

Dao层

StudentDao

public interface StudentDao{
}

TeacherDao

public interface TeacherDao{
}

Mapper.xml文件

StudentMapper.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">
<mapper namespace="com.company.dao.StudentDao">

</mapper>

TeacherMapper.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">
<mapper nampspace="com.company.dao.TeacherDao">
    
</mapper>

MyBatis-config.xml核心配置文件

<?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">
<configuration>
    <properties resource="src/resources/db.properties"/>
    <!--配置log4j为日志实现-->
    <settings>
        <setting name="logImpl" value="LOG4J"/>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    <typeAliases>
<!--        <package name="com.company.pojo"/>-->
        <typeAlias type="com.company.pojo.User" alias="User"/>
    </typeAliases>

    <environments default="development">
        <environment id="development">


            <!--数据库的配置-->
            <transactionManager type="JDBC"/>
            <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.xml都需要在Mybatis核心配置文件中注册-->
    <mappers>
        <mapper resource="com/company/dao/StudentMapper.xml"/>
        <mapper class="com.company.dao.TeacherMapper.xml"/>
    </mappers>
</configuration>

12.1、多对一

bean层

Student实体类

@Data
public class Student{
    private int id;
    private String name;
    //一个学生关联一个老师
    private Teacher teacher;
}

Teacher实体类

@Data
public class Teacher{
    private int id;
    private String name;
}

StudentDao

public interface StudentDao{
    //查询所有学生信息,包括老师信息(多表联查)
    List<Student> getStudent();
    List<Student> getStudnt2();
}

StudentMapper.xml

  1. 查询所有学生信息
  2. 根据查询出来的学生信息tid去寻找对应的老师
<mapper namespace = "com.company.dao.StudentDao">
    
    <select id = "getStudent" resultMap="StudentTeacher">
        select * from student
    </select>
    
    <resultMap id = "StudentTeacher" type = "Student">
        <result property = "id" colum="id"/>
        <result property = "name" colum="name"/>
        <association property = "teacher" colum="tid" javaType="Teacher" select="getTeacher"/>
    </resultMap>
    
    <select id = "getTeacher" resultType="Teacher">
        select * from teacher where id = #{id}
    </select>
</mapper>


<!--按照结果嵌套来查询-->
<mapper namespace = "com.company.dao.StudentDao">
    <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="Student">
        <result property = "id" colum="id"/>
        <result property = "name" colum="name"/>
        <association property = "teacher" javaType="Teacher">
            <result property = "name" colum="tname"/>
        </association>
    </resultMap>
</mapper>

12.2、一对多

bean实体类

StudentDao

public interface StudentDao{
    private int id;
    private String name;
    private int tid;
}

TeacherDao

public interface TeacherDao{
    private int id;
    private String name;
    private List<Student> students;
}

TeacherDao

public interface TeacherDao{
    //获取老师
    List<Teacher> getTeachers();
    
    //获取所有老师下的所有学生及老师信息
    Teacher getTeacher(@Param("tid") int id);
}

TeacherMapper.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">
<mapper nampspace="com.company.dao.TeacherDao">
    <!--按照结果嵌套查询-->
    <select id = "getTeacher" resultMap="TeacherStudent">
        select t.id tid,t.name tname,s.id sid,s.name sname
        from student s,teacher t
        where s.tid = t.id and t.id = #{id}
    </select>
    <resultMap id = "TeacherStudent" Type="Teacher">
        <result property = "id" column = "tid"/>
        <result property = "name" column = "tname"/>
        <collection property = "Student" ofType="Student">
            <result property = "id" column = "sid"/>
            <result property = "name" colum = "sname"/>
            <result property = "tid" colum = "tid"/>
        </collection>
    </resultMap>
    
    
    <!--子查询-->
    <select id = "getTeacherById" resultMap="TeacherStudent">
        select * from mybatis.teacher where id=#{id}
    </select>
    <resultMap id = "TeacherStudent" Type = "Teacher">
        <result property = "id" colum = "id"/>
        <result property = "name" colum = "name"/>
        <collection property = "students" javaType = "ArrayList" ofType = "Student" select = "getStudentByTeacherId" colum = "id"/>
    </resultMap>
    
    <select id = "getStudentByTeacherId" resultType = "Student">
        select * from student where tid = #{id}
    </select>
</mapper>

1、关联——association

2、集合——collection

3、javaType&ofType

  • javaType用于指定实体类中属性的类型
  • ofType用来指定映射到list或者POJO类型,泛型中的约束类型

注意:

  • 保证sql的可读性,尽量保证通俗易懂
  • 注意一对多和多对一中属性名和字段名的问题
  • 如果问题不好排查错误可以使用日志,建议使用Log4j

13、动态SQL

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

MyBatis总结

Mybatis主要作用是和数据库交互,让数据能在数据库和代码接收外界输入之间做交互,我们需要定义需要实现功能的接口以及实现类,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值