Mybatis 框架教程笔记

¡獨╰&丶殤¿ 2021-01-21 12:58:46
mybatis 教程 框架 笔记


 

框架

定义:

 

即:是软件开发中的一套解决方案,不同的框架解决的是不同的问题;

ORG思想

定义:Object Relational Mapping 对象关系映射

即:实体类和数据库表中的属性一一对应;让我们操作实体类就可以操作数据库表

MVC思想

Mybatis

 

学习之前的注意事项:

  1. 在 Windows 系统下,Mybatis 不区分大小写。Mac 系统下,Mybatis 区分大小写

  2.  

 

mybatis的入门

环境搭建

 

1.第一步:创建 Maven 工程并导入坐标

2.第二步:创建实体类和 dao 接口

3.第三步:创建Mybatis的主配置文件

SqlMapConfig.xml

4.第四步:创建映射配置文件

IUserDao.xml

环境搭建的注意事项:

第一个:创建 IUserDao.xml 和 IUserDao.java 时名称是为了和我们之前的知识保持一致。

在Mybatis中它把持久层的操作接口名称和映射文件也叫做:Mapper

所以: IUserDao 和 IUserMapper 是一样的

第二个:在IDEA中创建目录的时候,它和包是不一样的

包在创建时:com.itheima.mybatis 是三级目录

目录在创建时:com.itheima.mybatis是一级目录

第三个: Mybatis 的映射配置文件位置必须和 dao 接口的包结构相同

第四个:映射配置文件的 mapper 标签 namespace 属性的取值必须是 dao 接口的全限定类名

第五个:映射配置文件的操作配置(select),id 属性的取值必须是 dao 接口的方法名

当我们遵从了第三,四,五点之后,开发中便无需编写 dao 的实现类

mybatis 的入门案例

第一步:读取配置文件

InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");

第二步:创建 SqlSessionFactory 工厂

SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);

第三步:创建 SqlSession

SqlSession session = factory.openSession();

第四步:创建 Dao 接口的代理对象

UserDao userdao = session.getMapper(UserDao.class);

第五步:执行 dao 中的方法

List<User> list = userdao.findAll();

第六步:释放资源

sesssion.close();
io.close();

注意事项:不要忘记在映射配置中告知mybatis要封装到那个实体类;

配置的方式:指定实体类的全限定类名

 

 

2020-12-05_16h51_57

 

mybatis 基于注解的入门案例:

把 IUserDao.xml 移除,在 dao 接口苦的方法上使用 @Select 注解,并且指定 SQL 语句

同时需要在 SqlMapConfig.xml 中的 Mapper 配置时,使用 class 属性指定 dao 接口苦的全限定类名

入门案例解析

image-20201205172212623

image-20201205172314352

 

 

配置文件(resources下)

log4j.properties

# Set root category priority to INFO and its only appender to CONSOLE.
# log4j.rootCategory=INFO, CONSOLE         debug info warn error fatal
log4j.rootCategory=debug,CONSOLE, LOGFILE

log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE

log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n

log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d:\axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n

以上文件无需修改,拷贝到 resources 下即可

mybatis 的主配置文件(SqlMapConfig.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="mysql">
       <!-- 配置mysql的环境-->
       <environment id="mysql">
           <!-- 配置事务的类型 -->
           <transactionManager type="JDBC"></transactionManager>
           <!-- 配置数据源(连接池) -->
           <dataSource type="POOLED">
               <!-- 配置数据库的4个基本信息-->
               <property name="driver" value="com.mysql.jdbc.Driver"/>
               <property name="url" value="jdbc:mysql://localhost:3306/exercise"/>
               <property name="username" value="root"/>
               <property name="password" value="root"/>
           </dataSource>
       </environment>
   </environments>


   <!--指定配置文件的位置,映射配置文件指的是每个独立Dao独立的配置文件-->
   <mappers>
       <mapper resource="com/dream/dao/UserDao.xml"/>
   </mappers>
   
</configuration>

实体类的配置文件

<?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.dream.dao.UserDao">
<!-- 配置查询所有-->
<select id="findAll" resultType="com.dream.domain.User">
select * from user
</select>
<!-- 配置插入新数据-->
<insert id="saveUser" parameterType="com.dream.domain.User">
insert into user (username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
</insert>
</mapper>

在 mapper 内添加需要用到的 SQL 语句

 

模糊查询

有两种方式

一、在查询语句中添加 “%”

接口内

image-20201205174937716

实体配置文件

image-20201205174927539

测试类

2020-12-05_17h45_28

注意:

若使用第一种方式,则与其他语句相似操作即可

若采用第二种方式,即在配置文件中添加 “%” ,需要注意的是:必须使用 ‘%%’,源码中此处采用了 map 的方式,键值为 value,所以此处必须为 value

 

入门案例中设计模式的分析

mybatis 使用了哪些模式

image-20201205175818049

优点:

构建者模式:把对象的创建细节隐藏,使用者直接调用方法即可拿到对象

工厂模式:解耦(降低类之间的依赖关系)

代理模式:不修改源码的基础上,对已有方法增强

读取XML配置文件

XML文件的解析有多种方法

1、DOM解析(java官方提供)

2、SAX解析(java官方提供)

3、JDOM解析(第三方提供)

4、DOM4J提供(第三方提供)

mybatis 使用的是 DOM4J 方式来解析 XML 配置文件

文件的读取路径

读取文件的路径方法有:

1、相对路径

2、绝对路径

3、类加载器

4、Select

  • 在本地使用相对路径和绝对路径

  • 在项目中使用类加载器和 Select

在 mybatis 中,XML 文件的读取使用 SelectContext 对象的 getReadPath();

 

自定义 Mybatis 的分析:

Mybatis 在使用代理 dao 的方式实现增删改查时做什么事呢?

只有两件事:

第一:创建代理对象

第二:在代理对象中调用 selectList

 

Mybatis 的 CRUD

 

 

 

Mybatis 中的参数深入及结果集的深入

 

 

Mybatis 中基于传统 dao 的方式(编写 dao 的实现类)

 

 

 

 

Mybatis 中的配置(主配置文件:SqlMapConfig.xml)

 

 

 

 

OGNL 表达式

Object Graphic Navigation Language

对象 图 导航 语言

使用

它是通过对象的取值方法来获取数据,在写法上把 get 省略了

 

eg:

我们获取用户的名称

类中的写法: user.getUsername();

OGNL表达式的写法:user.username;

mybatis 中为什么能直接写 username,而不用 user. 呢?

因为在 parameterType 中已经提供了属性所属的类,所以此时不需要写对象名

 

SqlMapConfig.xml 配置文件

配置内容

配置 properties

可以在标签内部配置连接数据库的信息,也可以通过属性应用外部配置文件信息

一、

resource 属性: 常用

用于指定配置文件的位置,是按照类路径的写法来写,并且必须存于类路径下

2020-12-08_16h41_54

2020-12-08_16h42_10

 

二、

url 属性:

是要求按照 url 的写法来写地址

URL:Uniform Resoures Locator 统一资源定位符。它是可以唯一标识一个资源的位置

它的写法:

http://localhost:8080/mybatisserver/demo1Servlet

协议 主机 端口 URI

URI:Uniform Resource Identifier 统一资源标识符。他是在应用中可以唯一定位一个资源的。

2020-12-08_16h47_32

 

配置 typeAliases

typeAliases 配置别名,他只能配置 domain 中类的别名

一、

typeAlias 用于配置别名,type属性指定的是实体类全限定类名;alias 属性指定别名,当指定别名就不在区分大小写

2020-12-08_17h08_47

2020-12-08_17h10_46

 

二、

package 用于指定要配置别名的包,当指定之后,该包下的实体类都会注册别名,并且类名就是别名,不再区分大小写

2020-12-08_17h15_00

2020-12-08_17h10_46

 

配置 Mappers

package 标签用于指定 dao 接口所在的包,当指定之后就不需要在写 mapper以及 resource 或者 class 这里没有运行出来

2020-12-08_17h36_24

 

 

 

 

 

 

 

连接池

优点

在实际开发中都会使用连接池

因为他可以减少我们获取连接所消耗的时间

Mybatis 中的连接池

Mybatis 中连接池的配置

配置的位置:

主配置文件 SqlMapConfig.xml 中 dataSource 标签,type 属性就是表示采用何种连接池方式

type 属性的取值:

 ##### POOLED

采用传统的 javax.sql.DataSource 规范中的连接池,mybatis中有针对规范的实现

 ##### UNPOOLED

采用传统的获取连接的方式,虽然也实现了 javax.sql.DataSource 接口,但是并没有使用池的思想

 ##### JNDI

采用服务为其提供的JNDI 技术实现,来获取 DataSource 对象,不同的服务器所能拿到的 DataSource 是不一样的

注意:如果不是web或者maven工程,是不能使用的

 

 

 

事务

定义:

 

 

 

事务的特性

原子性(Atomocity)

隔离性(Consistency)

一致性(Isolation)

持久性(Durability)

 

 

不考虑隔离性会产生的3个问题

读未提交 (Read Uncommited)

读已提交 (Read Committed)

可重复读 (Repeatable Read)

串行化 (Serialization)

 

 

 

解决办法:

四种隔离级别

 

它是通过 sqlsession 对象的 commit 方法和 rollback 方法实现事务的提交和回滚

 

 

 

Mybatis 中映射文件的深入

if 标签

根据实体类的不同取值,使用不同的 SQL 语句来进行查询,比如在 id 如果不为空时可以根据 id 查询,如果 username 不同空时还要加入用户名作为条件。这种情况在多条件组合查询中经常碰到

2020-12-09_00h49_06

2020-12-09_00h49_22

 

注意:多条件查询时,并列条件组合必须用 and ,而不能用 &&

2020-12-09_01h00_40

2020-12-09_01h00_51

 

where 标签

根据实体类的不同取值,使用不同的 SQL 语句来进行查询,但是查询条件不确定。而查询条件又多的时候,我们可以通过 where 标签来实现多条件,且不确定条件查询

2020-12-09_00h49_06

2020-12-09_00h53_48

2020-12-09_00h52_56

 

 

foreach 标签

根据实际开发要求,应对需要查询多 ID 时,此时需要将 ID 包装到集合中,通过包装类来实现映射

2020-12-09_15h50_53

2020-12-09_15h50_30

2020-12-09_15h45_46

 

Result 标签

配置文件中:

result 标签中

property 表示 实体类中 get 和 set 方法后面的属性

colum 表示 SQL 语句查询结果中的结果列

2020-12-12_11h54_58

 

抽取重复的 SQL 语句

抽取重复的 SQL 语句为其添加别名

注意:若在 if 标签或 where 标签中引用,不能在 SQL 标签中的 SQL 语句中添加分号2020-12-09_18h12_24

 

 

mybatis 中的多表查询

表之间的关系

一对多

多对一

一对一

多对多

 

mybatis 中的多表查询

示例:用户和账户

一个用户有多个账户

一个账户只能属于一个用户(多个账户也可以属于同一个用户)

步骤

1、建立两张表

让用户表和账户表之间具备一对多的关系:需要使用外键在账户表中添加

2、建立两个实体类:用户表,账户表

让用户和账户的实体类能体现出一对多的关系

3、建立两个配置文件

用户的配置文件

账户的配置文件

4、实现配置

当我们查询用户时,可以同时得到用户下包含的账户信息

当我们查询账户时,可以同时得到账户下的所属用户信息

 

一对一

第一种方式:(较古老)

添加第三张表信息,在第三张表中加入需要的字段信息。使用及应用于之前类似

2020-12-10_10h00_56

2020-12-10_09h59_59

 

第二种方式

一、在从表中添加主表的实体属性

2020-12-10_11h40_57

二、然后在从表的映射配置文件中添加映射信息

2020-12-10_11h33_11

 

 

一对多

一、在主表中添加从表的集合引用

2020-12-10_12h17_58

 

二、主表映射配置文件的参数设置

2020-12-10_12h19_31

 

三、 SQL 语句查询结果

2020-12-10_12h19_49

注意:mybatis是很智能且强大的,它会在查询结果中将重复的数据删除,只保留一条

 

多对多

示例:用户和角色

一个用户有多个角色

一个角色可以赋予多个用户

步骤

1、建立两张表

用户表

角色表

用户表和角色表具有多对多的关系,需要使用中间表,中间表包含各自的主键,在中间表中是外键

image-20201212110747902

2、建立两个实体类:

用户实体类

角色实体类

让用户和角色能体现多对多的关系,各自包含对方一个集合引用

2020-12-12_10h55_11

2020-12-12_11h09_37

3、建立两个配置文件

用户的配置文件

2020-12-12_11h30_47

角色的配置文件

2020-12-12_10h56_45

配置文件中:

result 标签中

property 表示 实体类中 get 和 set 方法后面的属性

colum 表示 SQL 语句查询结果中的结果列

开发注意:

实际开发中,在SQL语句很长,很复杂的情况下,必须在每行尾或者行头添加空格,以防止字符串拼接操作,导致的错误

4、实现配置

当我们查询用户时,可以同时得到用户下包含的角色信息

image-20201212112157782

2020-12-12_11h45_52

当我们查询角色时,可以同时得到角色所赋予的用户信息

image-20201212112012933

2020-12-12_11h14_37

 

 

JNDI

JNDI

Java Naming And Directory Interface

是 SUN 公司推出的一套规范,属于 JavaEE 技术之一 。目的是模仿 Windows 系统中的注册表。

 

。。。。。。。。。。。

 

 

 

 

Mybatis 的延迟加载

问题:

在一对多中,当我们有一个用户,他有100个账户。

在查询用户的时候,要不要把关联的账户查出来?

在查询账户的时候,要不要把关联的用户查出来?

解决:

在查询用户是,用户下的账户信息,什么时候用,什么时候查询

在查询账户时,账户所属用户信息,随着账户查询时一起查询出来

 

延迟加载和立即加载

延迟加载

在真正使用数据是才发起查询,不用的时候不查询,按需加载(懒加载)

立即加载

不管用不用,只要一调用方法,马上发起查询

 

在对应四中表关系中:一对一;一对多;多对一;多对多

一对;多对:通常情况下都是采用延迟加载

多对;一对:通常情况下都是采用立即加载

 

Mybatis 中的缓存

什么是缓存

存在于内存中的临时数据

 

为什么使用缓存

减少和数据库的交互次数,提高执行效率

 

什么样的数据能使用缓存,什么样的数据不适合用缓存

适用于缓存:

经常查询并且不经常改变的

数据的正确与否对最后结果影响不大的

不适用于缓存

经常改变的数据

数据的正确与否对最终结果影响很大的

例如:商品的库存,银行的汇率,股市的牌价

 

Mybatis 中的一级缓存和二级缓存

一级缓存(默认无需设置)

它指的是Mybatis中SqlSession对象的缓存

当我们执行查询之后,查询的结果会同时存入到SqlSession为我们提供的一块区域中。

该区域的结构是一个Map。当我们在此查询到同样的数据,mybatis会先去sqlSession中查询是否有,有的话直接拿出来用。

 

当SqlSession对象消失时,Mybatis的一级缓存也就消失了

SqlSession 范围的缓存,当调用 SqlSession 的修改,添加,删除,commit() , close() 等方法时,就会清空一级缓存

image-20201220204603702

 

二级缓存(需设置)

它指的是 Mybatis 中 SqlSessionFactory 对象的缓存。由同一个 SqlSessionFactory 对象创建的 SqlSession 共享其缓存

二级缓存的使用步骤:

第一步:让 Mybatis 框架支持二级缓存(在 SqlMapConfig.xml) 中配置

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

第二步:让当前的映射文件支持二级缓存(在 IUserDao.xml) 中配置

<cache/>

第三步:让当前的操作支持二级缓存(在 Select 标签中配置)

<select id="findById" parameterType="int" resultTyp="user" useCache="true">
select * ferm user where id=#{uid}
</select>

主配置文件

image-20201220211108395

实体类配置文件

image-20201220211305373

测试类

image-20201220211010374

注意:

再次强调:二级缓存内存放的是数据,而不是对象。当每次从二级缓存中拿取数据时,会重新进行封装对象操作,所以从二级缓存内取到的对象不是同一个

 

Mybatis 中的注解开发

在 Mybatis 框架中,只能存在一种解析方式,即要么使用配置文件方式,要么使用注解方式,不能两者同时存在

 

前期准备

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.itheima.mybatis</groupId>
<artifactId>day05_mybatis_annotation02</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.4.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

Mybatis 所需要的配置文件

jdbcConfig.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/exercise?useSSL=false
jdbc.username=root
jdbc.password=root

log4j.properties

log4j.rootCategory = debug,CONSOLE,LOGFILE
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
log.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x -%m\n
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d:\axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x -%m\n

SqlMapConfig.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="jdbcConfig.properties"></properties>
<!-- 配置别名 -->
<typeAliases>
<package name="com.lgl.mybatis.domain.User"/>
</typeAliases>
<!-- 配置环境 -->
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- 指定带有注解的 dao 接口所在位置-->
<mappers>
<package name="com.lgl.mybatis.dao"/>
</mappers>
</configuration>

 

CRUD 操作

实体类

package com.lgl.mybatis.Test;
import java.io.Serializable;
import java.util.Date;
public class User implements Serializable {
private int id;
private String username;
private String address;
private Date birthday;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", address='" + address + '\'' +
", birthday=" + birthday +
'}';
}
}

实体类 dao 接口

package com.lgl.mybatis.dao;
import com.lgl.mybatis.Test.User;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
public interface IUserDao {
/**
* 查询所有用户方法
* @return
*/
@Select("select * from user")
List<User> findAll();
/**
* 通过主键 id 查询该用户所有信息
* @param id
* @return
*/
@Select("select * from user where id=#{id}")
User findOne(int id);
/**
* 添加新用户信息
* @param user
*/
@Insert("insert into user(username,address,birthday) values (#{username},#{address},#{birthday})")
Boolean saveUser(User user);
@Delete("delete from user where id=#{id}")
/** 通过主键删除用户信息 */
Boolean deleteUser(int id);
@Update("update user set username=#{username},address=#{address},birthday=#{birthday} where id=#{id}")
Boolean updateUser(User user);
/**
* 查询用户数据条数
* @return
*/
@Select("select count(*) from user ")
int findTotal();
/**
* 查询用户名相似的用户集合
* @param name
* @return
*/
// @Select("select * from user where username like #{name}")
@Select("select * from user where username like '%${value}%' ")
List<User> findByName(String name);
}

 

测试类

package com.lgl.mybatis.Test;
import com.lgl.mybatis.dao.IUserDao;
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.After;
import org.junit.Before;
import org.junit.Test;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
public class MybatisAnoTest {
private InputStream in;
private SqlSessionFactory factory;
private SqlSession session;
private IUserDao dao;
@Before
public void before() throws Exception{
in = Resources.getResourceAsStream("SqlMapConfig.xml");
factory = new SqlSessionFactoryBuilder().build(in);
session = factory.openSession();
dao = session.getMapper(IUserDao.class);
}
@After
public void after() throws Exception{
session.commit();
session.close();
in.close();
}
@Test
public void TestFind(){
List<User> all = dao.findAll();
for(User a : all){
System.out.println(a);
}
}
@Test
public void TestFindOne(){
User one = dao.findOne(1);
System.out.println(one);
}
@Test
public void TestUpdate(){
User u = new User();
u = dao.findOne(56);
System.out.println(u);
u.setUsername("cnm");
u.setBirthday(new Date());
u.setAddress("YN");
System.out.println(u);
System.out.println(dao.updateUser(u));
}
@Test
public void TestSave(){
User u = new User();
u.setAddress("aa");
u.setBirthday(new Date());
u.setUsername("bb");
System.out.println(dao.saveUser(u));
}
@Test
public void TestDelete(){
System.out.println(dao.deleteUser(65));
}
@Test
public void TestTotal(){
System.out.println(dao.findTotal());
}
@Test
public void TestFindByName(){
// List<User> byName = dao.findByName("%王%");
List<User> byName = dao.findByName("王");
for(User u:byName){
System.out.println(u);
}
}
}

 

别名的 CRUD 操作

说明

  • 配置文件与上同

  • 此开发方法存在于数据库的列名与实体类的属性名不相同时

 

实体类

package com.lgl.mybatis.domain;
import java.io.Serializable;
import java.util.Date;
public class User implements Serializable {
private int userId;
private String userName;
private String userAddress;
private Date userBirthday;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserAddress() {
return userAddress;
}
public void setUserAddress(String userAddress) {
this.userAddress = userAddress;
}
public Date getUserBirthday() {
return userBirthday;
}
public void setUserBirthday(Date userBirthday) {
this.userBirthday = userBirthday;
}
@Override
public String toString() {
return "User{" +
"userId=" + userId +
", userName='" + userName + '\'' +
", userAddress='" + userAddress + '\'' +
", userBirthday=" + userBirthday +
'}';
}
}

实体类 dao 接口

image-20201220222956434

image-20201220223615281

package com.lgl.mybatis.dao;
import com.lgl.mybatis.domain.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
public interface IUserDao {
/**
* 查询所有用户方法
* @return
*/
@Select("select * from user")
@Results(id="userMap" ,value = {
@Result(id = true,column = "id",property = "userId"),
@Result(column = "username",property = "userName"),
@Result(column = "address",property = "userAddress"),
@Result(column = "birthday",property = "userBirthday")
})
List<User> findAll();
/**
* 通过主键 id 查询该用户所有信息
* @param id
* @return
*/
@Select("select * from user where id=#{id}")
@ResultMap(value={"userMap"})
User findOne(int id);
/**
* 添加新用户信息
* @param user
*/
@Insert("insert into user(username,address,birthday) values (#{userName},#{userAddress},#{userBirthday})")
@ResultMap(value={"userMap"})
Boolean saveUser(User user);
@ResultMap(value={"userMap"})
@Delete("delete from user where id=#{id}")
/** 通过主键删除用户信息 */
Boolean deleteUser(int id);
@ResultMap(value={"userMap"})
@Update("update user set username=#{userName},address=#{userAddress},birthday=#{userBirthday} where id=#{userId}")
Boolean updateUser(User user);
/**
* 查询用户数据条数
* @return
*/
@Select("select count(*) from user ")
int findTotal();
/**
* 查询用户名相似的用户集合
* @param name
* @return
*/
@ResultMap("userMap")
// @Select("select * from user where username like #{name}")
@Select("select * from user where username like '%${value}%' ")
List<User> findByName(String name);
}

 

测试类

package com.lgl.mybatis.domain;
import com.lgl.mybatis.dao.IUserDao;
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.After;
import org.junit.Before;
import org.junit.Test;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
public class MybatisAnoTest {
private InputStream in;
private SqlSessionFactory factory;
private SqlSession session;
private IUserDao dao;
@Before
public void before() throws Exception{
in = Resources.getResourceAsStream("SqlMapConfig.xml");
factory = new SqlSessionFactoryBuilder().build(in);
session = factory.openSession();
dao = session.getMapper(IUserDao.class);
}
@After
public void after() throws Exception{
session.commit();
session.close();
in.close();
}
@Test
public void TestFind(){
List<User> all = dao.findAll();
for(User a : all){
System.out.println(a);
}
}
@Test
public void TestFindOne(){
User one = dao.findOne(1);
System.out.println(one);
}
@Test
public void TestSaveUser(){
User u = new User();
u.setUserName("aa");
u.setUserAddress("云南");
u.setUserBirthday(new Date());
System.out.println(dao.saveUser(u));
}
@Test
public void TestDelete(){
Boolean aBoolean = dao.deleteUser(67);
System.out.println(aBoolean);
}
@Test
public void TestUpdate(){
User u = new User();
u.setUserId(66);
u.setUserName("bb");
u.setUserBirthday(new Date());
u.setUserAddress("贵州");
System.out.println(dao.updateUser(u));
}
@Test
public void TestFindTotal(){
System.out.println(dao.findTotal());
}
@Test
public void TestFindName(){
System.out.println(dao.findByName("王"));
}
}

 

注解开发一对一(一对多)

前期准备

  • 添加实体类 Account

 

实体类:

image-20201220231405015

package com.lgl.mybatis.domain;
import java.io.Serializable;
public class Account implements Serializable {
private int id;
private int aid;
private double money;
// 多对一(mybatis中称之为一对一的映射);一个账户只能属于一个用户
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAid() {
return aid;
}
public void setAid(int aid) {
this.aid = aid;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
@Override
public String toString() {
return "account{" +
"id=" + id +
", aid=" + aid +
", money=" + money +
'}';
}
}
package com.lgl.mybatis.domain;
import java.io.Serializable;
import java.util.Date;
public class User implements Serializable {
private int userId;
private String userName;
private String userAddress;
private Date userBirthday;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserAddress() {
return userAddress;
}
public void setUserAddress(String userAddress) {
this.userAddress = userAddress;
}
public Date getUserBirthday() {
return userBirthday;
}
public void setUserBirthday(Date userBirthday) {
this.userBirthday = userBirthday;
}
@Override
public String toString() {
return "User{" +
"userId=" + userId +
", userName='" + userName + '\'' +
", userAddress='" + userAddress + '\'' +
", userBirthday=" + userBirthday +
'}';
}
}

实体类 dao 接口

image-20201220232245994

 

IAccountDao.java

package com.lgl.mybatis.dao;
import com.lgl.mybatis.domain.Account;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;
import java.util.List;
public interface IAccountDao {
/**
* 查询所有账户,并且获取每个账户下用户的所属信息
* @return
*/
@Select("select * from account")
@Results(id = "accountMap",value = {
@Result(id = true,column = "id",property = "id"),
@Result(column = "aid",property = "aid"),
@Result(column = "money",property = "money"),
@Result(property = "user",column = "aid",
one = @One(select = "com.lgl.mybatis.dao.IUserDao.findOne",
fetchType = FetchType.EAGER))
})
List<Account> findAll();
}

IUserDao.java

package com.lgl.mybatis.dao;
import com.lgl.mybatis.domain.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
public interface IUserDao {
/**
* 查询所有用户方法
* @return
*/
@Select("select * from user")
@Results(id="userMap" ,value = {
@Result(id = true,column = "id",property = "userId"),
@Result(column = "username",property = "userName"),
@Result(column = "address",property = "userAddress"),
@Result(column = "birthday",property = "userBirthday")
})
List<User> findAll();
/**
* 通过主键 id 查询该用户所有信息
* @param id
* @return
*/
@Select("select * from user where id=#{id}")
@ResultMap(value={"userMap"})
User findOne(int id);
/**
* 添加新用户信息
* @param user
*/
@Insert("insert into user(username,address,birthday) values (#{userName},#{userAddress},#{userBirthday})")
@ResultMap(value={"userMap"})
Boolean saveUser(User user);
@ResultMap(value={"userMap"})
@Delete("delete from user where id=#{id}")
/** 通过主键删除用户信息 */
Boolean deleteUser(int id);
@ResultMap(value={"userMap"})
@Update("update user set username=#{userName},address=#{userAddress},birthday=#{userBirthday} where id=#{userId}")
Boolean updateUser(User user);
/**
* 查询用户数据条数
* @return
*/
@Select("select count(*) from user ")
int findTotal();
/**
* 查询用户名相似的用户集合
* @param name
* @return
*/
@ResultMap("userMap")
// @Select("select * from user where username like #{name}")
@Select("select * from user where username like '%${value}%' ")
List<User> findByName(String name);
}

测试类

AccountTest.java

package com.lgl.mybatis.domain;
import com.lgl.mybatis.dao.IAccountDao;
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.After;
import org.junit.Before;
import org.junit.Test;
import java.io.InputStream;
import java.util.List;
public class AccountTest {
private InputStream in;
private SqlSessionFactory factory;
private SqlSession session;
private IAccountDao dao;
@Before
public void before() throws Exception{
in = Resources.getResourceAsStream("SqlMapConfig.xml");
factory = new SqlSessionFactoryBuilder().build(in);
session = factory.openSession();
dao = session.getMapper(IAccountDao.class);
}
@After
public void after() throws Exception{
session.commit();
session.close();
in.close();
}
@Test
public void TestFind(){
List<Account> all = dao.findAll();
for (Account a:all){
System.out.println("-------------每个账户信息---------------");
System.out.println(a);
System.out.println(a.getUser());
}
}
}

 

注解开发一对多(多对多)

实体类

User.java

package com.lgl.mybatis.domain;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
public class User implements Serializable {
private int userId;
private String userName;
private String userAddress;
private Date userBirthday;
// 一对多:一个用户有多个账户信息
private List<Account> accounts;
public List<Account> getAccounts() {
return accounts;
}
public void setAccounts(List<Account> accounts) {
this.accounts = accounts;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserAddress() {
return userAddress;
}
public void setUserAddress(String userAddress) {
this.userAddress = userAddress;
}
public Date getUserBirthday() {
return userBirthday;
}
public void setUserBirthday(Date userBirthday) {
this.userBirthday = userBirthday;
}
@Override
public String toString() {
return "User{" +
"userId=" + userId +
", userName='" + userName + '\'' +
", userAddress='" + userAddress + '\'' +
", userBirthday=" + userBirthday +
'}';
}
}

 

实体类 dao 接口

IAccountDao.java

package com.lgl.mybatis.dao;
import com.lgl.mybatis.domain.Account;
import org.apache.ibatis.annotations.*;
import java.util.List;
public interface IAccountDao {
/**
* 查询所有账户,并且获取每个账户下用户的所属信息
* @return
*/
@Select("select * from account")
@Results(id = "accountMap",value = {
@Result(id = true,column = "id",property = "id"),
@Result(column = "aid",property = "aid"),
@Result(column = "money",property = "money")
})
List<Account> findAll();
/**
* 根据用户主键查询账户信息
* @param id
* @return
*/
@Select("select * from account where aid=#{aid}")
Account findByAid(int id);
}

IUserDao.java

package com.lgl.mybatis.dao;
import com.lgl.mybatis.domain.User;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;
import java.util.List;
public interface IUserDao {
/**
* 查询所有用户方法
* @return
*/
@Select("select * from user")
@Results(id="userMap" ,value = {
@Result(id = true,column = "id",property = "userId"),
@Result(column = "username",property = "userName"),
@Result(column = "address",property = "userAddress"),
@Result(column = "birthday",property = "userBirthday"),
@Result(property = "accounts",column = "id",
many = @Many(select = "com.lgl.mybatis.dao.IAccountDao.findByAid",
fetchType=FetchType.LAZY))
})
List<User> findAll();
/**
* 通过主键 id 查询该用户所有信息
* @param id
* @return
*/
@Select("select * from user where id=#{id}")
@ResultMap(value={"userMap"})
User findOne(int id);
/**
* 添加新用户信息
* @param user
*/
@Insert("insert into user(username,address,birthday) values (#{userName},#{userAddress},#{userBirthday})")
@ResultMap(value={"userMap"})
Boolean saveUser(User user);
@ResultMap(value={"userMap"})
@Delete("delete from user where id=#{id}")
/** 通过主键删除用户信息 */
Boolean deleteUser(int id);
@ResultMap(value={"userMap"})
@Update("update user set username=#{userName},address=#{userAddress},birthday=#{userBirthday} where id=#{userId}")
Boolean updateUser(User user);
/**
* 查询用户数据条数
* @return
*/
@Select("select count(*) from user ")
int findTotal();
/**
* 查询用户名相似的用户集合
* @param name
* @return
*/
@ResultMap("userMap")
// @Select("select * from user where username like #{name}")
@Select("select * from user where username like '%${value}%' ")
List<User> findByName(String name);
}

测试类

package com.lgl.mybatis.domain;
import com.lgl.mybatis.dao.IUserDao;
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.After;
import org.junit.Before;
import org.junit.Test;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
public class UserTest {
private InputStream in;
private SqlSessionFactory factory;
private SqlSession session;
private IUserDao dao;
@Before
public void before() throws Exception{
in = Resources.getResourceAsStream("SqlMapConfig.xml");
factory = new SqlSessionFactoryBuilder().build(in);
session = factory.openSession();
dao = session.getMapper(IUserDao.class);
}
@After
public void after() throws Exception{
session.commit();
session.close();
in.close();
}
@Test
public void TestFind(){
List<User> all = dao.findAll();
for(User a : all){
System.out.println("----------每个用户的信息---------------");
System.out.println(a);
System.out.println(a.getAccounts());
}
}
}

效果图

image-20201220235826523

 

注解开发二级缓存

image-20201221001452128

在需要开启二级缓存的实体类 dao 上添加注解

@CacheNamespace(blocking=true)
package com.lgl.mybatis.dao;

import com.lgl.mybatis.domain.User;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;
import java.util.List;

/*
  开启二级缓存
*/

@CacheNamespace(blocking = true)
public interface IUserDao {
   /**
    * 查询所有用户方法
    * @return
    */
   @Select("select * from user")
   @Results(id="userMap" ,value = {
           @Result(id = true,column = "id",property = "userId"),
           @Result(column = "username",property = "userName"),
           @Result(column = "address",property = "userAddress"),
           @Result(column = "birthday",property = "userBirthday"),
           @Result(property = "accounts",column = "id",
                   many = @Many(select = "com.lgl.mybatis.dao.IAccountDao.findByAid",
                           fetchType=FetchType.LAZY))
  })
   List<User> findAll();

   /**
    * 通过主键 id 查询该用户所有信息
    * @param id
    * @return
    */
   @Select("select * from user where id=#{id}")
   @ResultMap(value={"userMap"})
   User findOne(int id);

   /**
    * 添加新用户信息
    * @param user
    */

   @Insert("insert into user(username,address,birthday) values (#{userName},#{userAddress},#{userBirthday})")
   @ResultMap(value={"userMap"})
   Boolean saveUser(User user);

   @ResultMap(value={"userMap"})
   @Delete("delete from user where id=#{id}")
   /** 通过主键删除用户信息 */
   Boolean deleteUser(int id);

   @ResultMap(value={"userMap"})
   @Update("update user set username=#{userName},address=#{userAddress},birthday=#{userBirthday} where id=#{userId}")
   Boolean updateUser(User user);

   /**
    * 查询用户数据条数
    * @return
    */
   @Select("select count(*) from user ")
   int findTotal();

   /**
    * 查询用户名相似的用户集合
    * @param name
    * @return
    */
   @ResultMap("userMap")
//   @Select("select * from user where username like #{name}")
   @Select("select * from user where username like '%${value}%' ")
   List<User> findByName(String name);
}

 

 

 

版权声明
本文为[¡獨╰&amp;丶殤¿]所创,转载请带上原文链接,感谢
https://www.cnblogs.com/liangls/p/14307384.html

  1. 【计算机网络 12(1),尚学堂马士兵Java视频教程
  2. 【程序猿历程,史上最全的Java面试题集锦在这里
  3. 【程序猿历程(1),Javaweb视频教程百度云
  4. Notes on MySQL 45 lectures (1-7)
  5. [computer network 12 (1), Shang Xuetang Ma soldier java video tutorial
  6. The most complete collection of Java interview questions in history is here
  7. [process of program ape (1), JavaWeb video tutorial, baidu cloud
  8. Notes on MySQL 45 lectures (1-7)
  9. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  10. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  11. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  12. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  13. 【递归,Java传智播客笔记
  14. [recursion, Java intelligence podcast notes
  15. [adhere to painting for 386 days] the beginning of spring of 24 solar terms
  16. K8S系列第八篇(Service、EndPoints以及高可用kubeadm部署)
  17. K8s Series Part 8 (service, endpoints and high availability kubeadm deployment)
  18. 【重识 HTML (3),350道Java面试真题分享
  19. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  20. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  21. [re recognize HTML (3) and share 350 real Java interview questions
  22. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  23. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  24. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  25. RPC 1: how to develop RPC framework from scratch
  26. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  27. RPC 1: how to develop RPC framework from scratch
  28. 一次性捋清楚吧,对乱糟糟的,Spring事务扩展机制
  29. 一文彻底弄懂如何选择抽象类还是接口,连续四年百度Java岗必问面试题
  30. Redis常用命令
  31. 一双拖鞋引发的血案,狂神说Java系列笔记
  32. 一、mysql基础安装
  33. 一位程序员的独白:尽管我一生坎坷,Java框架面试基础
  34. Clear it all at once. For the messy, spring transaction extension mechanism
  35. A thorough understanding of how to choose abstract classes or interfaces, baidu Java post must ask interview questions for four consecutive years
  36. Redis common commands
  37. A pair of slippers triggered the murder, crazy God said java series notes
  38. 1、 MySQL basic installation
  39. Monologue of a programmer: despite my ups and downs in my life, Java framework is the foundation of interview
  40. 【大厂面试】三面三问Spring循环依赖,请一定要把这篇看完(建议收藏)
  41. 一线互联网企业中,springboot入门项目
  42. 一篇文带你入门SSM框架Spring开发,帮你快速拿Offer
  43. 【面试资料】Java全集、微服务、大数据、数据结构与算法、机器学习知识最全总结,283页pdf
  44. 【leetcode刷题】24.数组中重复的数字——Java版
  45. 【leetcode刷题】23.对称二叉树——Java版
  46. 【leetcode刷题】22.二叉树的中序遍历——Java版
  47. 【leetcode刷题】21.三数之和——Java版
  48. 【leetcode刷题】20.最长回文子串——Java版
  49. 【leetcode刷题】19.回文链表——Java版
  50. 【leetcode刷题】18.反转链表——Java版
  51. 【leetcode刷题】17.相交链表——Java&python版
  52. 【leetcode刷题】16.环形链表——Java版
  53. 【leetcode刷题】15.汉明距离——Java版
  54. 【leetcode刷题】14.找到所有数组中消失的数字——Java版
  55. 【leetcode刷题】13.比特位计数——Java版
  56. oracle控制用户权限命令
  57. 三年Java开发,继阿里,鲁班二期Java架构师
  58. Oracle必须要启动的服务
  59. 万字长文!深入剖析HashMap,Java基础笔试题大全带答案
  60. 一问Kafka就心慌?我却凭着这份,图灵学院vip课程百度云