一.什么是ORM及作用
ORM(Object Relational Mapping,简称ORM)即面向对象和关系数据库之间的映射。面向对象是应用程序执行存放在内存当中的对象,数据库的数据是存放在表中即字节码文件。而ORM所做的操作就是讲两者转换。如何我要找的数据库的字节码转换为我需要的对象,这种操作就是ORM思想。比如实现这一思想的就是学了很久的jdbc,以及刚学习的mybatis等等技术。
二.MyBatis
下载地址:https://github.com/mybatis/mybatis-3/releases(也可以通过maven依赖拿取)
MyBatis框架特点:
1.提供xml文件,支持写动态sql。
2.减少代码耦合性。写在配置文件当中,利于从外部去修改,维护性高。
3.提供对象关系映射标签,支持对象关系组件维护。
4.灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql基本上可以实现我们不使用数据访问框架可以实现的所有功能,或许更多。
工作原理图:
几个对象的生命周期:
SqlSessionFactoryBuilder:这个类可以被实例化,使用和丢弃,创建SqlSessionFactory就可以不需要他了,因此他的作用域建议是在方法作用域
SqlSessionFactory:此对象用于封装全局配置文件信息,整个应用都需要用到他,因此生命周期是应用的运行阶段。一般采用单例模式来构建他。
SqlSession(相当于JDBC中的statement对像):每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。
三.入门创建
采用的是pom工程创建:
依赖:
配置mybatis-config.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>
<!--default:默认是哪个环境的id
id:环境的唯一标识
-->
<environments default="mysql">
<environment id="mysql">
<!-- transactionManager:事务管理方式
type:JDBC | MANAGED
JDBC:使用原生的JDBC事务管理方式
MANAGED:mybatis什么都不做,交由第三方容器事务管理区做
-->
<transactionManager type="JDBC"></transactionManager>
<!-- 数据源 取值有三个
POOLED:使用的是mybatis自带的连接池
UNPOOLED:使用原生的JDBC连接
JNDI:引入其他容器产生的数据源
-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/manager?serverTimezone=Asia/Shanghai"/>
<property name="username" value="root"/>
<property name="password" value="123456789"/>
</dataSource>
</environment>
</environments>
<!--引入相应的mapper映射文件-->
<mappers>
<!--resource:引入的map路径-->
<mapper resource="mapper/UserMapper.xml"></mapper>
</mappers>
</configuration>
作用:包括url,驱动,数据库用户名,密码等全局信息
UserMapper.xml:
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.UserMapper">
<!--配置相关的CRUD对应的SQL语句
1.其中有子标签:insert,delete,update,select 用于写相应的sql语法
其共同必须属性:id,是对标签中sql语句的唯一标识,即当前mapper文件中id不能重复
2.映射关系的说明(对像和关系型数据的映射关系)
表和类的映射关系:resultType表示的模型类的完全限定名
字段和属性的映射关系:模型类的属性和表的结果集字段具有一一对应性(字符串相等)
实质上字段和set及get方法具有对应关系
3.相同namespace下的sql的id不能重复,不同的可以重复.
即通过namespace+id来唯一区分相应的sql
Mybatis映射关系:最终解决的是接口方法与Sql语句的映射
-->
<select id="selectAll" resultType="com.study.model.User">
select * from user
</select>
<select id="selectById" resultType="com.study.model.User">
select * from user where id=#{id}
</select>
<select id="selectLogin" resultType="com.study.model.User">
select * from user where username=#{username} and password=#{password}
</select>
</mapper>
model层
package com.study.model;
public class User {
private Integer id;
private String username;
private String password;
private String loginname;
private Integer status;
private String createDate;
public User() {
}
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 String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getLoginname() {
return loginname;
}
public void setLoginname(String loginname) {
this.loginname = loginname;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public String getCreateDate() {
return createDate;
}
public void setCreateDate(String createDate) {
this.createDate = createDate;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", loginname='" + loginname + '\'' +
", status=" + status +
", createDate='" + createDate + '\'' +
'}';
}
}
入门测试:
package com.study;
import com.study.model.User;
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 java.io.InputStream;
import java.util.List;
public class Test1 {
public static void main(String[] args) throws Exception{
//1.用输入流将全文配置信息输入至内存,解析并创建SessionFactoryBuilder对象
InputStream rs = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sessionBuilder = new SqlSessionFactoryBuilder().build(rs);
//2.创建SessionFactory对象
SqlSession sqlSession = sessionBuilder.openSession();
//3.SessionFactory对象创建sqlSession对象来访问数据库并返回数据
List<User> list = sqlSession.selectList("mapper.UserMapper.selectAll");
System.out.println(list);
User user = sqlSession.selectOne("mapper.UserMapper.selectById",1);
System.out.println(user);
User user1 = new User();
user1.setUsername("jack");
user1.setPassword("753951");
User loginUser = sqlSession.selectOne("mapper.UserMapper.selectLogin",user1);
System.out.println(loginUser);
//4.关闭sqlSession对象
sqlSession.close();
}
}
mybatis运行的底层原理:mybatis初始化时会读取全局配置文件(包括mappers标签指定的map文件)中的配置信息至mybatis底层的MappedStatement对象中。该类对象专门保存一个配置信息(即一个sql语句)。然后将MappedStatement封装到map中去,map的key是该类的属性ID,值就是它本身。在SqlSession调用时,会根据形参与map中的key进行比对。在执行相应的JDBC操作。因此mybatis与JDBC的区别在于多了配置文件,原先JDBC是在代码中去写sql,很麻烦,现在sql脱离了代码,更易于维护。
以下是MappedStatement的属性
private String resource;
private Configuration configuration;
private String id;
private Integer fetchSize;
private Integer timeout;
private StatementType statementType;
private ResultSetType resultSetType;
private SqlSource sqlSource;
private Cache cache;
private ParameterMap parameterMap;
private List<ResultMap> resultMaps;
private boolean flushCacheRequired;
private boolean useCache;
private boolean resultOrdered;
private SqlCommandType sqlCommandType;
private KeyGenerator keyGenerator;
private String[] keyProperties;
private String[] keyColumns;
private boolean hasNestedResultMaps;
private String databaseId;
private Log statementLog;
private LanguageDriver lang;
private String[] resultSets;