ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[mybatis]mybatis重点知识总结

2022-07-23 18:04:34  阅读:153  来源: 互联网

标签:总结 name public 知识 appender log4j perple mybatis id


mybatis

什么是 MyBatis?

  • MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。

  • MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。

  • MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

  • MyBatis本是apache的一个开源项目iBatis,2010年这个项目由apache software foundation迁移到了[google code](https://baike.baidu.com/item/google code/2346604),并且改名为MyBatis。2013年11月迁移到Github

持久层

  • 持久化就是将程序的数据在持久状态转化的过程
  • 内存,断电即逝

为什么需要mybatis

  • 帮助程序员将数据存到数据库中。

  • 方便

  • 传统的jdbc代码太复杂了,简化,框架,自动化

  • 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件。

  • 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。

  • 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰。sql和代码的分离,提高了可维护性。

  • 提供映射标签,支持对象与数据库的orm字段关系映射。

  • 提供对象关系映射标签,支持对象关系组建维护。

  • 提供xml标签,支持编写动态sql。

一个mybatis程序

1.创建一个数据库

2.导入依赖文件

    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.29</version>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.1</version>
    </dependency>

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.9</version>
</dependency>

3.编写mybatis核心配置文件

<?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/jdbc?useSSL=false&amp;useUnicode=true&amp;characterEncoding=utf-8"/>
                <property name="username" value="root"/>
                <property name="password" value="123123"/>
            </dataSource>
        </environment>
    </environments>
    
</configuration>

4.编写操作数据库要用的SQLSession对象并且封装成一个工具类

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;

/**
 * @author panglili
 * @create 2022-07-21-14:49
 */
public class MybatisUtil {
    static SqlSessionFactory build;
    static {
        String resource="mybatis-config.xml";
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream(resource);

            build = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    //通过sqlSessionFactoryBuild创建拿到了工厂,由这个工厂就可以拿到sqlSession了
    //sqlSession中封装了所有操作数据库的代码
    public static SqlSession getSqlSession(){
        SqlSession sqlSession = build.openSession();

        return sqlSession;
    }
}

5.与数据库对应的实体类

package pojo;

import java.util.Date;

/**
 * @author panglili
 * @create 2022-07-21-15:01
 */
public class perple {
    private int id;
    private String name;
    private int age;
    private Date birth;

    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 int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Date getBirth() {
        return birth;
    }

    public void setBirth(Date birth) {
        this.birth = birth;
    }

    @Override
    public String toString() {
        return "perple{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", birth=" + birth +
                '}';
    }
}

6.接口与接口的配置

package mapper;

import pojo.perple;

import java.util.List;

/**
 * @author panglili
 * @create 2022-07-21-15:07
 */
public interface perpleMapper {

    //查询所有信息
    List<perple> perples();

    //通过id查询某个用户
    perple queryById();
}
<?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="mapper.perpleMapper">

    <select id="perples" resultType="pojo.perples">
        select * from perple;
    </select>
</mapper>

7.注册到mybatis配置文件

<mappers>
        <mapper resource="mapper/perpleMapper.xml"></mapper>
    </mappers>

8.测试

package mapper;
import org.apache.ibatis.session.SqlSession;
import pojo.perple;
import util.MybatisUtil;
import java.util.List;
/**
 * @author panglili
 * @create 2022-07-21-15:16
 */
public class perpleTest {
    public void test(){
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        perpleMapper mapper = sqlSession.getMapper(perpleMapper.class);
        List<perple> perples = mapper.();
        for(int i=0;i<perples.size();i++){
            System.out.println(perples.get(i));
        }

    }
}

最后可能会遇到静态资源过滤的问题需要在pom配置文件加上处理

 <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>

完整的增删改查

package mapper;

import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import pojo.perple;
import util.MybatisUtil;

import javax.print.attribute.standard.DateTimeAtCompleted;
import java.util.Date;
import java.util.List;

/**
 * @author panglili
 * @create 2022-07-21-15:16
 */
public class perpleTest {
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    perpleMapper mapper = sqlSession.getMapper(perpleMapper.class);

    @Test
    public void test(){
         List<perple> perples = mapper.queryAll();
        for(int i=0;i<perples.size();i++){
            System.out.println(perples.get(i));
        }
    }
    //通过id查询
    @Test
    public void test1(){
        perple perple = mapper.queryById(1);
        System.out.println(perple);
    }

    //删除
    @Test
    public void test2(){
        mapper.deleteById(1);
        sqlSession.commit();
    }

    //增加
    @Test
    public void test3(){

        perple perple=new perple(2,"tata",13,"2002-1");
        mapper.add(perple);
        //大坑 一定要开启提交事务
        sqlSession.commit();
    }


    //修改
    @Test
    public void test4(){
        perple perple=new perple(2,"tata",18,"2002-1");
        mapper.update(perple);
        sqlSession.commit();
    }
}

一定要记得开启事务!!!

3.配置解析

configuration(配置)
properties(属性)
settings(设置)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
databaseIdProvider(数据库厂商标识)
mappers(映射器)

属性(properties)

这些属性可以在外部进行配置,并可以进行动态替换。你既可以在典型的 Java 属性文件中配置这些属性,也可以在 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>

设置(settings)

这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。 下表描述了设置中各项设置的含义、默认值等。

<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>

类型别名(typeAliases)

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

<typeAliases>
  <typeAlias alias="Author" type="domain.blog.Author"/>
  <typeAlias alias="Blog" type="domain.blog.Blog"/>
  <typeAlias alias="Comment" type="domain.blog.Comment"/>
  <typeAlias alias="Post" type="domain.blog.Post"/>
  <typeAlias alias="Section" type="domain.blog.Section"/>
  <typeAlias alias="Tag" type="domain.blog.Tag"/>
</typeAliases>

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

<typeAliases>
  <package name="domain.blog"/>
</typeAliases>

每一个在包 domain.blog 中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。 比如 domain.blog.Author 的别名为 author;若有注解,则别名为其注解值.

@Alias("author")
public class Author {
    ...
}

映射器(mappers)

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

可以使用相对于类路径的资源引用,或完全限定资源定位符(包括 file:/// 形式的 URL),或类名和包名等。

方式一

<!-- 使用相对于类路径的资源引用 -->
<mappers>
  <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
  <mapper resource="org/mybatis/builder/BlogMapper.xml"/>
  <mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>

方式二(不咋用)

<!-- 使用完全限定资源定位符(URL) -->
<mappers>
  <mapper url="file:///var/mappers/AuthorMapper.xml"/>
  <mapper url="file:///var/mappers/BlogMapper.xml"/>
  <mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>

方式三

<!-- 使用映射器接口实现类的完全限定类名 -->
<mappers>
  <mapper class="org.mybatis.builder.AuthorMapper"/>
  <mapper class="org.mybatis.builder.BlogMapper"/>
  <mapper class="org.mybatis.builder.PostMapper"/>
</mappers>

方式四

<!-- 将包内的映射器接口实现全部注册为映射器 -->
<mappers>
  <package name="org.mybatis.builder"/>
</mappers>

注意点:

  • 方式三四,接口和mapper配置文件必须同名
  • 方式三四,接口和mapper配置文件必须在同一包下

结果映射

resultMap 元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBC ResultSets 数据提取代码中解放出来,并在一些情形下允许你进行一些 JDBC 不支持的操作。

  • 解决字段名和属性名不一样的冲突

解决方法:

  • 1.给数据库字段起个别名和属性名相同

  • 2.使用resultMap结果集映射

<--添加resultMap进行映射 -->
<select id="selectUsers" resultMap="userResultMap">
  select user_id, user_name, hashed_password
  from some_table
  where id = #{id}
</select>
<-- id对应上面的sql-->
<resultMap id="userResultMap" type="User">
  <id property="id" column="user_id" />
  <result property="username" column="user_name"/>
  <result property="password" column="hashed_password"/>
</resultMap>

4.日志

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

  • SLF4J
  • Apache Commons Logging
  • Log4j 2
  • Log4j
  • JDK logging

配置日志在mybatis配置文件中:

<configuration>
  <settings>
    ...
    <setting name="logImpl" value="LOG4J"/>
    ...
  </settings>
</configuration>

log4j的使用

Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台。

可以控制每一条日志的输出格式;

通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。

可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

(1)导包

<!-- https://mvnrepository.com/artifact/log4j/log4j -->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>

(2)配置文件

### 设置###
log4j.rootLogger = DEBUG,console,file,D,E,datasource

### 配置输出到控制台 ###
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern =  %d{ABSOLUTE} %5p %c{ 1 }:%L - %m%n

### 配置输出到文件 ###
log4j.appender.file = org.apache.log4j.RollFileAppender
log4j.appender.file.File = ./log/logs.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Append = true
log4j.appender.file.Threshold = DEBUG
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n



### 设置输出sql的级别,其中logger后面的内容全部为jar包中所包含的包名 ###
log4j.logger.org.apache=DEBUG
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG



### 配置输出到文件,且大小到达指定尺寸的时候产生一个新的文件 ###
#log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender
#log4j.appender.ROLLING_FILE.Threshold=ERROR
#log4j.appender.ROLLING_FILE.File=rolling.log
#log4j.appender.ROLLING_FILE.Append=true
#log4j.appender.ROLLING_FILE.MaxFileSize=10KB
#log4j.appender.ROLLING_FILE.MaxBackupIndex=1
#log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout
#log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
#
#### 配置输出到邮件 ###
#log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender
#log4j.appender.MAIL.Threshold=FATAL
#log4j.appender.MAIL.BufferSize=10
#log4j.appender.MAIL.From=chenyl@yeqiangwei.com
#log4j.appender.MAIL.SMTPHost=mail.hollycrm.com
#log4j.appender.MAIL.Subject=Log4J Message
#log4j.appender.MAIL.To=chenyl@yeqiangwei.com
#log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout
#log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
#
#### 配置输出到数据库 ###
#log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender
#log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/test
#log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver
#log4j.appender.DATABASE.user=root
#log4j.appender.DATABASE.password=
#log4j.appender.DATABASE.sql=INSERT INTO LOG4J (Message) VALUES ('[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n')
#log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout
#log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
#log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
#log4j.appender.A1.File=SampleMessages.log4j
#log4j.appender.A1.DatePattern=yyyyMMdd-HH'.log4j'
#log4j.appender.A1.layout=org.apache.log4j.xml.XMLLayout
#
#### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
#log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
#log4j.appender.D.File = E://logs/log.log
#log4j.appender.D.Append = true
#log4j.appender.D.Threshold = DEBUG
#log4j.appender.D.layout = org.apache.log4j.PatternLayout
#log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
#
#### 输出ERROR 级别以上的日志到=E://logs/error.log ###
#log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
#log4j.appender.E.File =E://logs/error.log
#log4j.appender.E.Append = true
#log4j.appender.E.Threshold = ERROR
#log4j.appender.E.layout = org.apache.log4j.PatternLayout
#log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

(3)配置log4j

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

(4)使用

5.分页

  • 减少数据的处理量

使用limit分页:

select * from  tableName limit i,n
--tableName : 为数据表;

--i : 为查询结果的索引值(默认从0开始);

--n : 为查询结果返回的数量
--不带 i 时,表示查询n条数据。

使用RowBounds实现:

(1)接口方法

//分页
perple getRowBounds();

(2)sql调用

<select id="getRowBounds"  resultType="pojo.perple">
    select * from jdbc.perple;
</select>

(3)方法实现

@Test
//分页
public void test5(){
    //rowbounds实现分页 从第几个开始,到几个结束
    RowBounds rowBounds = new RowBounds(1, 2);


    List<perple> list = sqlSession.selectList("mapper.perpleMapper.getRowBounds",null,rowBounds);
    for(perple p:list){
        System.out.println(p);
    }

    sqlSession.close();
}

6.使用注解开发

用注解给接口添加sql语句:

//查询所有信息
@Select("select * from perple")
List<perple> queryAll();

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

<mappers>
    
    <mapper class="mapper.perpleMapper"></mapper>
</mappers>

7.多对一与一对多处理

  • 多个学生,对应一个老师
  • 对于学生而言,关联……一个老师
  • 对于老师而言,集合……多个学生

先创建两张表,学生表中对应tid是老师表的属性

CREATE TABLE `teacher` (
`id`  int(10) NOT NULL ,
`name`  varchar(30) NULL ,
PRIMARY KEY (`id`)
)
INSERT INTO `teacher` (`id`, `name`) VALUES ('1', '王方')
INSERT INTO `teacher` (`id`, `name`) VALUES ('2', '秦明')

CREATE TABLE `student` (
`id`  int(10) NOT NULL ,
`name`  varchar(30) NULL ,
`tid`  int(10) NULL ,
PRIMARY KEY (`id`),
CONSTRAINT `tid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
)
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('1', '小米', '1')
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('2', '小镇', '2')
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('3', '小王', '1')
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('4', '小兰', '1')
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('5', '小红', '2')
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('6', '小青', '1')



创建老师和学生实体类,学生实体类中老师的id必须先给一个老师对象,不能为int

package com.demo2.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author panglili
 * @create 2022-07-22-20:01
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private int id;
    private String name;
    private Teacher tid;
}
package com.demo2.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author panglili
 * @create 2022-07-22-20:01
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Teacher {
    private int id;
    private String name;

}

报错处理

java.io.IOException: Could not find resource mybatis_config.xml

如果程序中报无法找到某个资源文件的错误:

解决方案:

(1)在引用的地方查看资源文件路径

(2)检查是否在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)检查target生成文件是否有静态资源

没有的话手动复制一份过去

再次启动试试看!

查询所有的学生对应的老师的信息:

sql:

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

<!--查询学生的信息和对应的老师名
     1.查询所有的学生
     2.查询学生的id对应的tid的老师
     3.根据tid找到老师的名字-->
    <!--方式一 子嵌套 -->
    <select id="getStudents" resultMap="student">
        select * from student
    </select>
    <resultMap id="student" type="com.demo2.pojo.Student">
        <result property="id" column="id"></result>
        <result property="name" column="name"></result>
        <!--当遇到属性是对象的时候用association -->
        <association property="teacher" column="tid" javaType="com.demo2.pojo.Teacher" select="getTeacher"></association>
    </resultMap>

    <!--方式二 -->
     <!-- 按照结果嵌套处理-->
    <select id="getStudents2" resultMap="studen2">
        select student.id sid,student.name sname,teacher.name tname
        from student,teacher
        where student.tid=teacher.id
    </select>
    <resultMap id="student2" type="com.demo2.pojo.Student">
        <result property="id" column="sid"></result>
        <result property="name" column="sname"></result>
        <association property="teacher" javaType="com.demo2.pojo.Teacher">
            <result property="name" column="tname"></result>
        </association>
    </resultMap>
    <select id="getTeacher" resultType="com.demo2.pojo.Teacher">
        select * from teacher where id=#{id}
    </select>
</mapper>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.demo2.mapper.TeacherMapper">
<select id="getTeacher" resultType="Teacher">
    select * from teacher where id=#{id}
</select>

</mapper>

查询某个老师包含的所有的学生信息:

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

8.动态sql

根据不同的环境生成不同的sql

  • if

  • choose (when, otherwise)

  • trim (where, set)

  • foreach

    if

    • 使用动态 SQL 最常见情景是根据条件包含 where 子句的一部分。

    如果传入name就根据name查询,如果输入age就根据age查询,如果不输入就全部查询。

    这里还使用了一对标签主要作用是在判断条件时自动去掉一个或多个end,确保程序正常运行!

<select id="getPerpleByIf" parameterType="Map" resultType="pojo.perple">
    select * from perple 
    <where>
   <if test="name!=null" >
        name=#{name}
   </if>
    <if test="age!=null">
    and age=#{age}
    </if>
        </where>
@Test
public void test(){
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    prepleMapper mapper = sqlSession.getMapper(prepleMapper.class);
    Map map= new HashMap();
   // map.put("name","tata");
    map.put("age","18");
    List<perple> perpleByIf = mapper.getPerpleByIf(map);
    for(perple perple:perpleByIf){
        System.out.println(perple);
    }
}
}

choose、when、otherwise

​ 不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。

 <select id="getPerpleByChoose" parameterType="Map" resultType="pojo.perple">
        select * from perple
        <where>
            <choose>
                <when test="name!=null">
                    name=#{name}
                </when>
                <when test="age!=null">
                    age=#{age}
                </when>
                <otherwise>
                    birth=#{birth}
                </otherwise>
            </choose>
        </where>
    </select>
@Test
public void test1(){
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    prepleMapper mapper = sqlSession.getMapper(prepleMapper.class);
    Map map= new HashMap();
 //   map.put("name","tata");
    map.put("age",13);
    map.put("birth","2022-1");
    List<perple> perpleByChoose = mapper.getPerpleByChoose(map);
    for(perple perple:perpleByChoose){
        System.out.println(perple);
    }
}

trim、where、set

set跟where标签作用相似,是为了在修改的时候根据传递的参数去掉多余的逗号!

 <update id="updateSet" parameterType="Map">
        update perple 
        <set>
            <if test="id!=null">
                id=#{id},
            </if>
            <if test="name!=null">
                name=#{name},
            </if>
            <if test="age!=null">
                age=#{age} ,  
            </if>
            <if test="birth!=null">
                birth=#{birth},
            </if>
        </set> where id=#{id}
    </update>
@Test
public void test2(){
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    prepleMapper mapper = sqlSession.getMapper(prepleMapper.class);
    Map map= new HashMap();
    //   map.put("name","tata");
   map.put("age",22);
   map.put("id",3);
   // map.put("birth","2022-1");
    mapper.updateSet(map);

    sqlSession.commit();
}

sql脚本抽取公共部分进行复用

1.使用sql标签进行抽取

<sql id="if">
        <if test="name!=null">
            name=#{name}
        </if>
        <if test="age!=null">
          and age=#{age}
    </if>
    </sql>

2.使用include插入

<select id="getPerple" parameterType="String" resultType="perple">
    select * from perple
    <where>
        <include refid="if"></include>
    </where>
</select>

foreach

动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)。

sql语句

<select id="getPerpleByForeach" parameterType="Map" resultType="pojo.perple">
    select * from perple
    <where>
        <foreach collection="ids" item="id" open="and (" close= ")" separator="or">
            id=#{id}
        </foreach>
    </where>
</select>

测试类

@Test
public void test3(){
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    prepleMapper mapper = sqlSession.getMapper(prepleMapper.class);
    Map map= new HashMap();
    ArrayList<Integer> ids = new ArrayList<Integer>();
    ids.add(2);
    ids.add(3);
    map.put("ids",ids);
    List<perple> foreach = mapper.getPerpleByForeach(map);
    for(perple f:foreach){
        System.out.println(f);
    }

}

动态sql测试的所有接口方法

//通过if语句的查询
List<perple> getPerpleByIf(Map map);

//通过choose语句的查询
List<perple> getPerpleByChoose(Map map);

//通过set标签更新
int updateSet(Map map);

//通过foreach查询123号
List<perple> getPerpleByForeach(Map map);

9.缓存

因为频繁的查询会很消耗资源,所以将经常查询且不经常修改的结果暂时放在内存中,需要的时候直接取一下。

  • 一级缓存:默认开启 SQLSession级别,SQLSession关闭则失效
  • 二级缓存:手动开启,作用于一个命名空间

测试一级缓存

创建两次相同的查询,返回两个数,可以在下面的截图中看到,只创建了一次数据库的连接,并且只查询了一次,所以一级缓存默认开启调用。

@Test
public void test4(){
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    prepleMapper mapper = sqlSession.getMapper(prepleMapper.class);
    perple perple = mapper.getPerple(2);
    System.out.println(perple);
    perple perple1=mapper.getPerple(2);
    System.out.println(perple1);
}

image-20220723140446265

二级缓存测试

开启二级缓存:

<settings>
    
    <setting name="cacheEnabled" value="true"></setting>
</settings>

或者在mapper的xml文件中使用

<cache eviction="FIFO"
       flushInterval="60000"
       size="512"
       readOnly="true"/>

当一级缓存消失的时候,会自动把数据保存在开启的二级缓存之中。

@Test
public void test4(){
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    SqlSession sqlSession1 = MybatisUtil.getSqlSession();

    prepleMapper mapper = sqlSession.getMapper(prepleMapper.class);
    perple perple = mapper.getPerple(2);
    System.out.println(perple);
    sqlSession.close();


    prepleMapper mapper1 = sqlSession1.getMapper(prepleMapper.class);
    perple perple1=mapper1.getPerple(2);
    System.out.println(perple1);
    sqlSession1.close();
}

实体类需要序列化

标签:总结,name,public,知识,appender,log4j,perple,mybatis,id
来源: https://www.cnblogs.com/lumanmanqixiuyuanxi/p/16512613.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有