如有需看图片请转到原创:https://www.cnblogs.com/liangls/p/14307384.html
即:是软件开发中的一套解决方案,不同的框架解决的是不同的问题;
即:实体类和数据库表中的属性一一对应;让我们操作实体类就可以操作数据库表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k6cZOfYe-1611200879900)([外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nbZyVm1A-1611200880787)(https://raw.githubusercontent.com/L-LGL/ImagesCSDNBlog//CSDNBlog/20201205142434.png)]])
在 Windows 系统下,Mybatis 不区分大小写。Mac 系统下,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 的实现类
==第一步:==读取配置文件
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)]
# 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 下即可
<configuration>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC">transactionManager>
<dataSource type="POOLED">
<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>
<mappers>
<mapper resource="com/dream/dao/UserDao.xml"/>
mappers>
configuration>
<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
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r3ZicD2P-1611200879920)(https://i.loli.net/2021/01/19/lQW9D27LNFTethk.png)]
优点:
==构建者模式:==把对象的创建细节隐藏,使用者直接调用方法即可拿到对象
==工厂模式:==解耦(降低类之间的依赖关系)
==代理模式:==不修改源码的基础上,对已有方法增强
XML文件的解析有多种方法
1、DOM解析(java官方提供)
2、SAX解析(java官方提供)
3、JDOM解析(第三方提供)
4、DOM4J提供(第三方提供)
mybatis 使用的是 DOM4J 方式来解析 XML 配置文件
读取文件的路径方法有:
1、相对路径
2、绝对路径
3、类加载器
4、Select
在 mybatis 中,XML 文件的读取使用 SelectContext 对象的 getReadPath();
Mybatis 在使用代理 dao 的方式实现增删改查时做什么事呢?
只有两件事:
第一:创建代理对象
第二:在代理对象中调用 selectList
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U06ZdeA6-1611200879922)(https://i.loli.net/2021/01/19/5BjxUIqAuWt7Cs4.png)]
对象 图 导航 语言
它是通过对象的取值方法来获取数据,在写法上把 get 省略了
eg:
我们获取用户的名称
类中的写法: user.getUsername();
OGNL表达式的写法:user.username;
mybatis 中为什么能直接写 username,而不用 user. 呢?
因为在 parameterType 中已经提供了属性所属的类,所以此时不需要写对象名
可以在标签内部配置连接数据库的信息,也可以通过属性应用外部配置文件信息
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 配置别名,他只能配置 domain 中类的别名
typeAlias 用于配置别名,type属性指定的是实体类全限定类名;alias 属性指定别名,当指定别名就不在区分大小写
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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)]
package 标签用于指定 dao 接口所在的包,当指定之后就不需要在写 mapper以及 resource 或者 class 这里没有运行出来
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BdOTKHb1-1611200879937)(https://i.loli.net/2021/01/19/Q7blZPGrKJIgwNm.png)]
在实际开发中都会使用连接池
因为他可以减少我们获取连接所消耗的时间
主配置文件 SqlMapConfig.xml 中 dataSource 标签,type 属性就是表示采用何种连接池方式
##### POOLED
采用传统的 javax.sql.DataSource 规范中的连接池,mybatis中有针对规范的实现
##### UNPOOLED
采用传统的获取连接的方式,虽然也实现了 javax.sql.DataSource 接口,但是并没有使用池的思想
##### JNDI
采用服务为其提供的JNDI 技术实现,来获取 DataSource 对象,不同的服务器所能拿到的 DataSource 是不一样的
注意:如果不是web或者maven工程,是不能使用的
解决办法:
四种隔离级别
它是通过 sqlsession 对象的 commit 方法和 rollback 方法实现事务的提交和回滚
根据实体类的不同取值,使用不同的 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)]
根据实体类的不同取值,使用不同的 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)]
根据实际开发要求,应对需要查询多 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 标签中
property 表示 实体类中 get 和 set 方法后面的属性
colum 表示 SQL 语句查询结果中的结果列
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XaibkgtB-1611200879956)(https://i.loli.net/2021/01/21/ys7XZUvJdY2nqBh.png)]
抽取重复的 SQL 语句为其添加别名
注意:若在 if 标签或 where 标签中引用,不能在 SQL 标签中的 SQL 语句中添加分号[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a7QweoQL-1611200879957)(https://i.loli.net/2021/01/21/n3tK2yRLiWIv7la.png)]
一个用户有多个账户
一个账户只能属于一个用户(多个账户也可以属于同一个用户)
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)]
Java Naming And Directory Interface
是 SUN 公司推出的一套规范,属于 JavaEE 技术之一 。目的是模仿 Windows 系统中的注册表。
。。。。。。。。。。。
在一对多中,当我们有一个用户,他有100个账户。
在查询用户的时候,要不要把关联的账户查出来?
在查询账户的时候,要不要把关联的用户查出来?
在查询用户是,用户下的账户信息,什么时候用,什么时候查询
在查询账户时,账户所属用户信息,随着账户查询时一起查询出来
在真正使用数据是才发起查询,不用的时候不查询,按需加载(懒加载)
不管用不用,只要一调用方法,马上发起查询
在对应四中表关系中:一对一;一对多;多对一;多对多
一对**多;多对多:通常情况下都是采用延迟加载**;
多对**一;一对一**:通常情况下都是采用==立即加载==;
存在于内存中的临时数据
减少和数据库的交互次数,提高执行效率
经常查询并且不经常改变的
数据的正确与否对最后结果影响不大的
经常改变的数据
数据的正确与否对最终结果影响很大的
例如:商品的库存,银行的汇率,股市的牌价
它指的是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 框架中,只能存在一种解析方式,即要么使用配置文件方式,要么使用注解方式,不能两者同时存在
pom.xml
<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.0modelVersion>
<groupId>com.itheima.mybatisgroupId>
<artifactId>day05_mybatis_annotation02artifactId>
<version>1.0-SNAPSHOTversion>
<packaging>warpackaging>
<dependencies>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.4.5version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.10version>
<scope>testscope>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.18.12version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.38version>
dependency>
<dependency>
<groupId>org.junit.jupitergroupId>
<artifactId>junit-jupiterartifactId>
<version>5.4.2version>
<scope>testscope>
dependency>
dependencies>
project>
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
<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>
<mappers>
<package name="com.lgl.mybatis.dao"/>
mappers>
configuration>
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 +
'}';
}
}
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 byName = dao.findByName("%王%");
List<User> byName = dao.findByName("王");
for(User u:byName){
System.out.println(u);
}
}
}
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 +
'}';
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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("王"));
}
}
实体类:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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 +
'}';
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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 +
'}';
}
}
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);
}