Mybatis 框架教程笔记

Mybatis 框架教程笔记

如有需看图片请转到原创:https://www.cnblogs.com/liangls/p/14307384.html

定义:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Mlex4avj-1611200879896)(E:\Images\IT\kj-1.png)]

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

ORG思想

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

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

MVC思想

Mybatis

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k6cZOfYe-1611200879900)([外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nbZyVm1A-1611200880787)(https://raw.githubusercontent.com/L-LGL/ImagesCSDNBlog//CSDNBlog/20201205142434.png)]])

学习之前的注意事项:

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

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要封装到那个实体类;

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sXsHyVst-1611200879903)(https://raw.githubusercontent.com/L-LGL/ImagesCSDNBlog//CSDNBlog/20201221111223.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2bxUvO9b-1611200879907)(https://i.loli.net/2021/01/19/51t4GN8FHo3BJbL.png)]

mybatis 基于注解的入门案例:

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

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

入门案例解析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E4N1MFrR-1611200879910)(https://i.loli.net/2021/01/19/4NE5UhzHPJsDZ8q.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CE9p052u-1611200879912)(https://i.loli.net/2021/01/19/bKZpRhds3IuJqeH.png)]

配置文件(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 语句

模糊查询

有两种方式

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

接口内

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EJMRhQUI-1611200879914)(https://i.loli.net/2021/01/19/E9tOjucoPvbkZU6.png)]

实体配置文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZamagzpQ-1611200879915)(https://i.loli.net/2021/01/19/eTglYLpciWkuanJ.png)]

测试类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oKyzy8YK-1611200879918)(https://i.loli.net/2021/01/19/q1PBlLzuSaHUIfv.png)]

注意:

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

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

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

mybatis 使用了哪些模式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r3ZicD2P-1611200879920)(https://i.loli.net/2021/01/19/lQW9D27LNFTethk.png)]

优点:

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

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

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

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U06ZdeA6-1611200879922)(https://i.loli.net/2021/01/19/5BjxUIqAuWt7Cs4.png)]

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 属性: 常用

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wjhCA0tW-1611200879925)(https://i.loli.net/2021/01/19/24cRK1Ui6fr7bXq.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8qjxxfLv-1611200879927)(https://i.loli.net/2021/01/19/D2NjVxCBf6R7d8c.png)]

二、

url 属性:

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

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

它的写法:

​ http://localhost:8080/mybatisserver/demo1Servlet

​ 协议 主机 端口 URI

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FTH9yX78-1611200879929)(https://i.loli.net/2021/01/19/MFyeXfpqUlO1Q6u.png)]

配置 typeAliases

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

一、

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

2020-12-08_17h08_47

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BQHWjUvD-1611200879931)(https://i.loli.net/2021/01/19/MzuKI6R3YthwOok.png)]

二、

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m3Jly3Ch-1611200879933)(https://i.loli.net/2021/01/19/ioFm2krldHUMJB9.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X0n36b9U-1611200879934)(Mybatis 框架.assets/2020-12-08_17h10_46-1607419091568.png)]

配置 Mappers

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BdOTKHb1-1611200879937)(https://i.loli.net/2021/01/19/Q7blZPGrKJIgwNm.png)]

连接池

优点

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

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

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 不同空时还要加入用户名作为条件。这种情况在多条件组合查询中经常碰到

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H2Raf18v-1611200879938)(https://i.loli.net/2021/01/19/qgL1TP624jvUSaZ.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bg8HHf4s-1611200879940)(https://i.loli.net/2021/01/21/MDOGWAl1BSI6xXh.png)]

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CceQiXp3-1611200879941)(https://i.loli.net/2021/01/21/ZWgxKbEzyalnIMC.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cB2bOlTT-1611200879942)(https://i.loli.net/2021/01/21/xfraOyZ2IcGKpbq.png)]

where 标签

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ItFqU0lQ-1611200879945)(https://i.loli.net/2021/01/21/RFp6vOuY47gMbjk.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pHFolkBd-1611200879946)(https://i.loli.net/2021/01/21/4sDe7oiLT12BtOP.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2CGVI7LE-1611200879949)(https://i.loli.net/2021/01/21/QneYW3zPjdXKiVM.png)]

foreach 标签

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GT7RdrGW-1611200879951)(https://i.loli.net/2021/01/21/hmvfcdYjrMelziJ.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-29Lxum4C-1611200879952)(https://i.loli.net/2021/01/21/76WgeoZjPlu2Cna.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rpkYbvma-1611200879954)(https://i.loli.net/2021/01/21/IcUtudGOlSWFjnT.png)]

Result 标签

配置文件中:

​ result 标签中

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

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XaibkgtB-1611200879956)(https://i.loli.net/2021/01/21/ys7XZUvJdY2nqBh.png)]

抽取重复的 SQL 语句

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

注意:若在 if 标签或 where 标签中引用,不能在 SQL 标签中的 SQL 语句中添加分号[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a7QweoQL-1611200879957)(https://i.loli.net/2021/01/21/n3tK2yRLiWIv7la.png)]

mybatis 中的多表查询

表之间的关系

一对多

多对一

一对一

多对多

mybatis 中的多表查询

示例:用户和账户

一个用户有多个账户

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

步骤

1、建立两张表

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

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

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

3、建立两个配置文件

​ 用户的配置文件

​ 账户的配置文件

4、实现配置

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

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

一对一

第一种方式:(较古老)

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3z3dyXQv-1611200879959)(https://i.loli.net/2021/01/21/yMIXjBmtQChKgbs.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PrCeu46s-1611200879961)(https://i.loli.net/2021/01/21/au1w2BTIxvmpc4f.png)]

第二种方式

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X0hTcxZ6-1611200879962)(https://i.loli.net/2021/01/21/c6Sa4mQr9P1xgH7.png)]

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GyoPYomB-1611200879964)(https://i.loli.net/2021/01/21/hJ5lXNpui7Octqe.png)]

一对多

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DJrdU6pw-1611200879966)(https://i.loli.net/2021/01/21/L1z3748O56U9SnX.png)]

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CHrFiZdu-1611200879969)(https://i.loli.net/2021/01/21/rcLZ5u6HCxTPtVy.png)]

三、 SQL 语句查询结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3aoErfDa-1611200879970)(https://i.loli.net/2021/01/21/GbtAIYMXLVB6l4U.png)]

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

多对多

示例:用户和角色

一个用户有多个角色

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

步骤

1、建立两张表

​ 用户表

​ 角色表

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OrudigYF-1611200879972)(https://i.loli.net/2021/01/21/rhDSmZBUOXfgMJe.png)]

2、建立两个实体类:

​ 用户实体类

​ 角色实体类

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a1mMI44n-1611200879976)(https://i.loli.net/2021/01/21/xZnuN53Ssp9rVHh.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pDEPPFYn-1611200879977)(https://i.loli.net/2021/01/21/oC3DIMbWyhscTPi.png)]

3、建立两个配置文件

​ 用户的配置文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QNaA6Wfk-1611200879979)(https://i.loli.net/2021/01/21/cK2tdowaBIPAum4.png)]

​ 角色的配置文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l3WNvuQh-1611200879981)(https://i.loli.net/2021/01/21/dIPngrS8HBKCWRT.png)]

配置文件中:

​ result 标签中

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

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

开发注意:

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

4、实现配置

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3qgFhHLz-1611200879983)(https://i.loli.net/2021/01/21/DAwIahnyK8Sk56C.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y8JOlwxe-1611200879987)(https://i.loli.net/2021/01/21/FvOZ4EzQyRlo9UY.png)]

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-np1EPKLt-1611200879988)(https://i.loli.net/2021/01/21/KLASxrW2GipzluQ.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ixd6Ogb6-1611200879990)(https://i.loli.net/2021/01/21/Sdim4l2zpJwPOLE.png)]

JNDI

JNDI

Java Naming And Directory Interface

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

。。。。。。。。。。。

Mybatis 的延迟加载

问题:

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

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

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

解决:

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

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

延迟加载和立即加载

延迟加载

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

立即加载

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

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

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

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

Mybatis 中的缓存

什么是缓存

存在于内存中的临时数据

为什么使用缓存

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

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

适用于缓存:

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

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

不适用于缓存

​ 经常改变的数据

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

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

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

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

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

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

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5P73vICl-1611200879992)(https://i.loli.net/2021/01/21/MAkbx3HrfuQZzGm.png)]

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

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QsimZ1rI-1611200879993)(https://i.loli.net/2021/01/21/Yo5XzOlhnW6NRgD.png)]

二级缓存(需设置)

它指的是 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>

主配置文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H9gIB5Vz-1611200879995)(https://i.loli.net/2021/01/21/TUwv7RfOaFmk1yE.png)]

实体类配置文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KbOMcvKT-1611200879996)(https://i.loli.net/2021/01/21/hRxHpN8BbyWwDiK.png)]

测试类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jIJfj6uz-1611200879998)(https://i.loli.net/2021/01/21/ofvypGMTsIDZbh3.png)]

注意:

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

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JE7twkA5-1611200880001)(https://i.loli.net/2021/01/21/ohNtpad4B6KcZYz.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kHP9aVxT-1611200880002)(https://i.loli.net/2021/01/21/rWTOGwQKHfBXxYq.png)]

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

实体类:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Gucjsty2-1611200880004)(https://i.loli.net/2021/01/21/6WTgo7BpmG53zNx.png)]

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s3BiE1vT-1611200880007)(https://i.loli.net/2021/01/21/pYwEBMIf2mQnGAR.png)]

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());
        }
    }

}

效果图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D8IZOh4q-1611200880010)(https://i.loli.net/2021/01/21/bTcdaGExoue9IHA.png)]

注解开发二级缓存

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XMkhlNmo-1611200880012)(https://i.loli.net/2021/01/21/2fO5bqFSUu8NIke.png)]

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

@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);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值