MyBatis原理总结(前期准备)
1.不同框架解决不用问题,框架封装了很多细节,开发者可以使用简单的方式实现功能。
2.三层架构: 1.表现层 2.业务层 3.持久层 都有相应的处理框架。
3.持久层的技术解决方案:
JDBC技术: Connection PrepareStatement ResultSet
Spring的 JDBCTemplate Spring中对jdbc的简单封装
Apache的DBUtils: 它和Spring的JDBCTemplate很像,也是对JDBC的简单封装
注: 以上都不是框架。JDBC是规范,DPring的JDBCTemplate和Apache的DBUtils都只是工具类
参考JDBC:
JDBC步骤很繁琐的,重复的。可以简化!开发关注项目的功能实现。
Mybatis封装JDBC,开发者只需要关注SQL语句,省去了加载驱动,创建连接,创建statement等
通过XML或者注解方式将要执行的各种statement配置起来,通过Java对象和statement中sql的动态参数进行映射成最终执行的sql语句。然后封装结果映射成Java对象并返回。
MyBatis 是ORM思想,数据库字段和实体类映射。
废话不多说,先搭建个环境再说吧
环境搭建:
MyBatis配置文件的约束:
config:
<?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">
Mapper:
<?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">
sql:
DROP TABLE IF EXISTS `user`; 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; insert into `user`(`id`,`username`,`birthday`,`sex`,`address`) values (41,'老王','2018-02-27 17:47:08','男','北京'),
(42,'小二王','2018-03-02 15:09:37','女','北京金燕龙'),(43,'小二王','2018-03-04 11:34:34','女','北京金燕龙'),
(45,'张三','2018-03-04 12:04:06','男','北京金燕龙'),(46,'老王','2018-03-07 17:37:26','男','北京'),
(48,'小马宝莉','2018-03-08 11:44:00','女','北京修正'); DROP TABLE IF EXISTS `account`; 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; insert into `account`(`ID`,`UID`,`MONEY`) values (1,41,1000),(2,45,1000),(3,41,2000); DROP TABLE IF EXISTS `role`; 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; insert into `role`(`ID`,`ROLE_NAME`,`ROLE_DESC`) values (1,'院长','管理整个学院'),(2,'总裁','管理整个公司'),(3,'校长','管理整个学校'); DROP TABLE IF EXISTS `user_role`; CREATE TABLE `user_role` ( `UID` int(11) NOT NULL COMMENT '用户编号', `RID` int(11) NOT NULL COMMENT '角色编号', PRIMARY KEY (`UID`,`RID`), KEY `FK_Reference_10` (`RID`), CONSTRAINT `FK_Reference_10` FOREIGN KEY (`RID`) REFERENCES `role` (`ID`), CONSTRAINT `FK_Reference_9` FOREIGN KEY (`UID`) REFERENCES `user` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; insert into `user_role`(`UID`,`RID`) values (41,1),(45,1),(41,2);
创建步骤:
1.创建maven工程并且导入坐标
2. SqlMapperConfig.xml主配置文件
3. 实体类
4. Dao接口
5. IUserDao.xml 映射配置文件
环境搭建的注意事项:
1. 创建IUserDao.xml和IUserDao.java 时名称是为了和我们之前的知识保持一致。在Mybatis中它把持久层的操作接口名称和映射文件叫做: Mapper
所以IUserDao 和 IUserMapper是一样的
2. 在IDEA创建目录时候,它和包是不一样的。包在创建时候,source下的com.toov5.dao是它的三级目录(需要连续创建,逐层创建)
3. MyBatis的映射配置文件必须是和Dao接口的包结构相同
4. 映射配置文件的mapper标签namespace属性的取值必须是dao接口的全限定类名。
5. 映射配置文件的操作配置,id属性和dao接口的方法名相同。
如果遵从上述3到5,就不用写接口实现类了!
思路:
连接数据库的信息
有了工厂就可以生产操作对象,这个对象就可以操作数据库
此时只有dao接口,框架会生成代理对象。有了代理对象之后,表名方法已经被增强过了,可以实现功能了。
最后关闭连接。
环境搭建:
实体类:
public class User implements Serializable { private Integer id; private String username; private Date birthday; private String sex; private String address; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", birthday=" + birthday + ", sex='" + sex + '\'' + ", address='" + address + '\'' + '}'; } }
接口:
/** * 用户的持久层接口 */ public interface IUserDao { List<User> findAll(); }
映射:
<?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.toov5.dao.IUserDao"> <!--查询所有--> <select id="findAll" resultType="com.toov5.entity.User"> select * from user; </select> </mapper>
主配置:
<?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/test"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <!-- 指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件 --> <mappers> <!--resource目录下 对应要创建相应的包 --> <mapper resource="com/toov5/dao/IUserDao.xml"/> </mappers> </configuration>
测试类:
/** * MyBatis测试类 */ public class MyBatisTest { public static void main(String[] args) throws IOException { //1.读取配置文件 InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml"); //2. 创建SqlSessonFactory工厂 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); //如何解析,如何封装已经底层帮助实现了。细节封装了。 SqlSessionFactory factory = builder.build(in); // SqlSessionFactory 是个接口,需要找实现。这个工厂是用来创建对象的,创建过程省略了 //3. 使用工厂生产SqlSession对象 SqlSession sqlSession = factory.openSession(); //4. 使用SqlSession创建Dao接口的代理对象(这样就有了Dao的代理对象,不改变源码基础上对方法进行增强: List<User> findAll();) // 通过字节码去生产代理对象(通过代理方式实现接口) IUserDao userDao = sqlSession.getMapper(IUserDao.class); //5.使用代理对象执行方法 List<User> userList = userDao.findAll(); userList.stream().forEach( user ->{ System.out.println(user); } ); //6.释放资源 sqlSession.close(); in.close(); } }
测试结果:
小结:
1. 读取配置文件
2. 创建SqlSessionFactory工厂
3. 创建SqlSession
4. 创建Dao接口的代理对象
5. 执行dao中的方法
6. 释放资源