本文主要内容:java
public class DataBaseUtil {
public static final String URL = "jdbc:mysql://localhost:3306/mblog";
public static final String USER = "root";
public static final String PASSWORD = "123456";
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.jdbc.Driver");
//2.
Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
//3.
Statement stmt = conn.createStatement();
//4.
ResultSet rs = stmt.executeQuery("SELECT id, name, age FROM m_user where id =1");
//若是有数据,rs.next()返回true
while(rs.next()){
System.out.println("name: "+rs.getString("name")+" 年龄:"+rs.getInt("age"));
}
}
}
上面代码中知识为了展现JDBC整个过程(异常和资源是简单粗暴的处理了,咱们关注的点不在这两个)。mysql
大体能够分为六个步骤:程序员
从使用层面来讲,采用原生态的JDBC在项目中使用起来成本仍是很高的。若是咱们的项目中的业务相对比较复杂,数据库表也相对较多,各类操做数据库的增删改查的方法也会随之多起来,那么这样的代码重复次数会很是之多。面试
为了解决以上问题,就诞生了各类各样替换JDBC
的产品。即就是ORM框架。算法
全称为Object Relational Mapping。对象-映射-关系型数据库。对象关系映射(,简称ORM,或O/RM,或O/R mapping),用于实现面向对象编程语言里不一样类型系统的数据之间的转换。简单的说,ORM是经过使用描述对象和数据库之间映射的元数据,将程序中的对象与关系数据库相互映射。sql
ORM提供了实现持久化层的另外一种模式,它采用映射元数据来描述对象关系的映射,使得ORM中间件能在任何一个应用的业务逻辑层和数据库层之间充当桥梁。数据库
咱们的项目中是这样的:apache
好比说:Apache DbUtils、Spring JDBC、 Hibernate、Ibatis
(Mybatis
的前生)、Spring Data Jpa
等等。编程
目前最为流行的Mybatis
和Spring Data Jpa
。本系列咱们先讲解Mybatis
,Jpa
后面再讲。安全
优势1.提升了开发效率。因为ORM能够自动对Entity对象与数据库中的Table进行字段与属性的映射,因此咱们实际可能已经不须要一个专用的、庞大的数据访问层。2.ORM提供了对数据库的映射,不用sql直接编码,可以像操做对象同样从数据库获取数据。
缺点牺牲程序的执行效率和会固定思惟模式,下降了开发的灵活性。
从系统结构上来看,采用ORM的系统通常都是多层系统,系统的层次多了,效率就会下降。ORM是一种彻底的面向对象的作法,而面向对象的作法也会对性能产生必定的影响。在咱们开发系统时,通常都有性能问题。性能问题主要产生在算法不正确和与数据库不正确的使用上。ORM所生成的代码通常不太可能写出很高效的算法,在数据库应用上更有可能会被误用,主要体如今对持久对象的提取和和数据的加工处理上,若是用上了ORM,程序员颇有可能将所有的数据提取到内存对象中,而后再进行过滤和加工处理,这样就容易产生性能问题。在对对象作持久化时,ORM通常会持久化全部的属性,有时,这是不但愿的。但ORM是一种工具,工具确实能解决一些重复,简单的劳动。这是不能否认的。但咱们不能期望工具能一劳永逸的解决全部问题,有些问题仍是须要特殊处理的,但须要特殊处理的部分对绝大多数的系统,应该是不多的。
若是在面试的时候被问到,只要你说出下面三种便可。
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。
MyBatis 免除了几乎全部的 JDBC 代码以及设置参数和获取结果集的工做。
MyBatis 能够经过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
来自官网。
优势:
(1)基于SQL语句编程,至关灵活,不会对应用程序或者数据库的现有设计形成任何影响,SQL写在XML里,解除sql与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,并可重用。
(2)与JDBC相比,减小了50%以上的代码量,消除了JDBC大量冗余的代码,不须要手动开关链接;
(3)很好的与各类数据库兼容(由于MyBatis使用JDBC来链接数据库,因此只要JDBC支持的数据库MyBatis都支持)。
(4)可以与Spring很好的集成;
(5)提供映射标签,支持对象与数据库的ORM字段关系映射;提供对象关系映射标签,支持对象关系组件维护。
缺点
(1)SQL语句的编写工做量较大,尤为当字段多、关联表多时,对开发人员编写SQL语句的功底有必定要求。
(2)SQL语句依赖于数据库,致使数据库移植性差,不能随意更换数据库。
Mybatis
环境搭建及简单实例建立一张m_user表使用MySQL
数据库。
CREATE TABLE `m_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
<scope>runtime</scope>
</dependency>
</dependencies>
项目结构以下:
建立一个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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mblog?useUnicode=true"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
</configuration>
实体类User
ublic class User {
private Integer id;
private String name;
private Integer age;
//set get
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
建立UserMapper.java
import com.tian.mybatis.entity.User;
public interface UserMapper {
User selectUserById(Integer id);
}
建立UserMapper.xml
<?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.tian.mybatis.mapper.UserMapper">
<select id="selectUserById" resultType="com.tian.mybatis.entity.User">
select * from m_user where id = #{id}
</select>
</mapper>
建立一个测试类
import com.tian.mybatis.entity.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.IOException;
import java.io.InputStream;
public class MybatisApplication {
public static void main(String[] args) {
String resource = "mybatis-config.xml";
InputStream inputStream = null;
SqlSession sqlSession =null;
try {
inputStream = Resources.getResourceAsStream(resource);
//工厂模式
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//sql操做会话
sqlSession = sqlSessionFactory.openSession();
//获取数据并解析成User对象
User user = sqlSession.selectOne("com.tian.mybatis.mapper.UserMapper.selectUserById", 1);
System.out.println(user);
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
sqlSession.close();
}
}
}
输出结果:
User{id=1, name='tian', age=22}
总体步骤:
另一种启动方式
import com.tian.mybatis.entity.User;
import org.apache.ibatis.builder.xml.XMLConfigBuilder;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.session.defaults.DefaultSqlSessionFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class MybatisApplication {
public static void main(String[] args) {
String resource = "mybatis-config.xml";
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);
} catch (IOException e) {
e.printStackTrace();
}
//解析xml文件
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, null, null);
//构建一个SqlSessionFactory工厂类
SqlSessionFactory sqlSessionFactory = build(parser.parse());
//建立一个SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取数据并解析成User对象
User user = sqlSession.selectOne("com.tian.mybatis.mapper.UserMapper.selectUserById", 1);
System.out.println(user);
}
public static SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
}
输出和上面同样。还能够直接使用Java代码而不用mybatis-config.xml
。
//建立数据源
DataSource dataSource = getDataSource();
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment("development", transactionFactory, dataSource);
Configuration configuration = new Configuration(environment);
configuration.addMapper(BlogMapper.class);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
小总结
从上面这个案例中咱们大体能猜到,Mybatis中最主要几个组件:
SqlSessionFactoryBuilder
SqlSessionFactory
SqlSession
Mapper
SqlSessionFactoryBuilder
这个类能够被初始、使用和丢弃,若是你已经建立好了一个 SqlSessionFactory
后就不用再保留它。所以 ,SqlSessionFactoryBuilder
的最好做用域是方法体内,好比说定义一个方法变量。
你能够重复使用SqlSessionFactoryBuilder
生成多个 SqlSessionFactory
实例,可是最好不要强行保留,由于 XML 的解析资源要用来作其它更重要的事。
SqlSessionFactory
一旦建立,SqlSessionFactory
就会在整个应用过程当中始终存在。因此没有理由去销毁和再建立它,一个 应用运行中也不建议屡次建立 SqlSessionFactory。若是真的那样作,会显得很拙劣。
所以 SqlSessionFactory最好的做用域是 Application。能够有多种方法实现。最简单的方法是单例模式或者是静态单例模式。然而这既不是普遍同意和好用的。反而,使用 Google Guice 或 Spring 来进行依赖反射会更好。这些框架允 许你生成管理器来管理 SqlSessionFactory
的单例生命周期
SqlSession
每一个线程都有本身的 SqlSession 实例,SqlSession 实例是不能被共享,也是否是线程安全的。所以最好 使用 Request 做用域或者方法体做用域。
不要使用类的静态变量来引用一个 SqlSession 实例,甚至不要使用类的一个实例变动来引用。永远不要在一个被管理域中引用 SqlSession,好比说在 Servlet 中的HttpSession 中。若是你正在使用 WEB 框架,应该让 SqlSession 跟随 HTTP 请求的类似做用域。
也就是说,在收到一个 HTTP 请求事后,打开 SqlSession,等返回一个回应之后,立马关掉这个 SqlSession。关闭 SqlSession 是很是重要的。你必需要确保 SqlSession 在 finally 方法体中正常关闭。
SqlSession session = sqlSessionFactory.openSession();
try {
// do work
} finally {
session.close();
}
使用这种模式来贯穿你的全部代码,以确保全部数据库资源都被彻底关闭。
Mapper
Mapper 是一种你建立的用于绑定映射语句的接口。Mapper 接口的实例是用 SqlSession 来得到的。一样 , 从技术上来讲,最普遍的 Mapper 实例做用域像 SqlSession 同样,使用请求做用域。确切地说,在方法 被调用的时候调用 Mapper 实例,而后使用后,就自动销毁掉。不须要使用明确的注销。当一个请求执 行正确无误的时候,像 SqlSession 同样,你能够垂手可得地操控这一切。保持简单性,保持 Mapper 在 方法体做用域内。
//获取数据并解析成User对象
User user = sqlSession.selectOne("com.tian.mybatis.mapper.UserMapper.selectUserById", 1);
System.out.println(user);
这里映射涉及到四个主体:
UaerMapper
。xml
配置文件UserMapper
。Mybatis的五部曲:
回顾JDBC
的demo,JDBC
中的问题,建立一个Mybatis示例,总结出重要的四个组件,以及每一个组件的做用。