1、MyBatis是一个优秀的基于Java的持久层框架,内部对JDBC做了封装,使开发者只需要关注SQL语句,而不用关注JDBC的代码,使开发变得更加的简单。
2、MyBatis通过XML或者注解的方式将要执行的各种Statement对象配置起来,通过Java对象和statement中SQL的动态参数进行映射,并最终执行SQL语句。执行SQL后,最终将结果已Java对象返回。
3、采用了ORM的思想。(对象关系映射)
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.4.5version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.6version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.10version>
<scope>testscope>
dependency>
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>1.2.17version>
dependency>
数据库记得先建立表
CREATE TABLE `user` (
`id` int(11) NOT NULL auto_increment,
`username` varchar(32) NOT NULL COMMENT '用户名称',
`birthday` datetime default NULL COMMENT '生日',
`sex` char(1) default NULL COMMENT '性别',
`address` varchar(256) default NULL COMMENT '地址',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
编写实体类
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<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:///mybatis_day04"/>
<property name="username" value="root"/>
<property name="password" value="18056112120"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="mappers/UserMapper.xml"/>
mappers>
configuration>
补充:另外一种比较好的方式 是在接口方法的参数列表中加入@Params(“参数名”) 然后在SQL语句中直接写#{参数名}即可
因为很多情况下我们使用的数据库的自增ID,插入数据 的时候我们是没有手动设置ID的,那么我们该如何插入数据后在实体类中拿到这个ID呢?
测试:
那么插入数据后该实体类中就能被封装进ID了
为了方便测试,所以我们可以使用junit提供的@Before和@After注解将拿到SqlSession或测试接口的过程都提取出来。
这样我们直接测试UserMapper中的业务即可
可以使用下面两种方式
说明:
MyBatis在处理#{ }的时候会将sql中的#{}替换成?号,调用PreparedStatement来赋值,也就是将sql进行预编译处理,可以 有效防止sql注入问题
MyBatis在处理${ }的时候采用的是sql语句的拼接,调用Statement来赋值,无法进行防止sql注入
当然还有一种更好的写法:concat(‘%’,#{xxx},‘%’)
作用:声明传递过来的属性
记得带包名,一会儿我们可以通过配置别名可以让它不用携带包名
当表中的实体类属性名和数据库字段不一样的时候我们可以使用resultMap来映射属性名和字段名
我们可以使用单独的一个properties文件来存储连接池的信息,然后这样也方便管理
<properties resource="jdbc.properties"/>
<typeAliases>
<package name="com.yangzihao.domain"/>
typeAliases>
之前我们可以看到,传递引用数据类型的参数是需要 带上包名的,我们可以在主配置文件中配置别名,这样之后就不用加入包名了
<typeAliases>
<package name="com.yangzihao.domain"/>
typeAliases>
用来动态的拼接我们的sql语句,他必须满足test中声明的条件才会拼接上if标签内的sql语句
因为if中的内容都携带了and 符号,为了使得sql语句拼接正确,那么我们就可以使用where 1==1 或
标签来解决
如果参数传递的是集合 我们可以通过
标签对List进行遍历,动态生成我们想要的sql语句
collection 表示传递的集合、open 表示遍开始前要拼接的语句
close表示遍历后结尾拼接的语句、item表示集合中遍历出来的每一个元素、separator表示两item中间所拼接的语句
先创建好所需要的 数据库表 和 实体类
CREATE TABLE `account` (
`ID` int(11) NOT NULL COMMENT '编号',
`UID` int(11) default NULL COMMENT '用户编号',
`MONEY` double default NULL COMMENT '金额',
PRIMARY KEY (`ID`),
KEY `FK_Reference_8` (`UID`),
CONSTRAINT `FK_Reference_8` FOREIGN KEY (`UID`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
属性为类类型的话需要在resultMap中使用association 来进行封装
一对一:
属性为集合类型的话需要使用collection进行封装
一对多:
注意,因为两张表中都有相同的字段id 所以我们得设置别名去区分
多对多表的设计,需要有一个中间表,中间表中的数据同时也为联合主键、中间表我们可以不创建实体类
CREATE TABLE `role` (
`ID` int(11) NOT NULL COMMENT '编号',
`ROLE_NAME` varchar(30) default NULL COMMENT '角色名称',
`ROLE_DESC` varchar(60) default NULL COMMENT '角色描述',
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
记得还得创建一张 关联表哦 如下图
其实多对多我们可以拆成两个一对多来看,在角色中,我们相当于是一个角色包含了多个用户
延迟加载就是当真正需要是用该数据的时候才会被加载
开启延迟加载
在主配置文件中添加
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
settings>
一对一延迟加载 案例,首先需要在UserMapper编写通过id查询用户的方法,然后在AccountMapper的XML文件
中通过select参数
去调用UserMapper中的的方法,通过column
参数传递字段值给UserMapper中的方法,注意:fetchType参数值必须为lazy该 属性才是延迟加载的
一对多延迟加载 案例,原理同上 只不过association换成了 collection 并且javaType换成了 ofType
增删改查分别对应注解
@Insert() 、@Delete()、@Update()、@Select()
都很简单 没什么好说的,需要注意点的是一对一查询或者一对多 以及延迟加载 或者属性与数据库字段不同的 都可以用@Results
,@Results和XML中的resultMap标签效果一样,id即为这个resultMap的id
,写一次即可,如果要在其他方法上调用可以直接使用@ResultMap(value="@Results中的id")
另外@Results中的one相当于
中的association
,many相当于
中的collection
生活明朗、万物可爱、人间值得、未来可期。