一、传统jdbc编程模式及缺点
1.传统jdbc编程模式步骤
(1)注册数据库驱动类,明确指定数据库URL地址,数据库用户名,密码等连接信息
(2)通过Drivermanager打开数据库连接
(3)通过数据库连接创建statement对象
(4)通过statemnet对象执行sql语句,得到resultSet对象
(5)通过ResultSet读取相关数据,并将数据转为JavaBean对象
(6)关闭相关的对象和连接,释放相关的资源
2.传统jdbc编程模式的痛点
(1)工作量大,重复性动作多,需要自己封装比较通过呢的JDBCUtils工具类
(2)上面得到ResultSet结果后转为JavaBean要封装成通用的比较困难
(3)项目大了以后难以维护
(4)数据库连接池使用不方便
二、ORM框架介绍
- ORM模型简单的说就是表和简单对象之间(POJO)的映射关系,主要是解决了数据库数据和POJO对象的相互映射,ORM模型提供了统一的规则使得数据库的数据通过配置便可以轻易的映射到POJO上。
- ORM对象关系映射框架的主要功能是根据映射配置文件,完成数据在对象模型与关系模型之间的映射,同时屏蔽重复性的代码,只是暴露简单的API给开发人员使用。
- 同时ORM框架基本会集成第三方的缓存、数据源等组件,来提高开发效率和系统的可维护性。
1.Hibernate
特点
1.hibernate通过hbm.xml映射文件维护java类与数据库表之间的映射关系,提供的是一种全表映射的模型。
2.提供Criteria和HQL查询语句,屏蔽掉底层的数据库差异
3.hibernate的API无侵入性,提供缓存、持久化、延迟加载等等优势
缺点
1.基于全表映射,无法利用sql原生语句的一些好的特性,比如索引、存储过程等。
2.在大量数据、高并发、低延迟场景下,不够灵活,sql语句不能满足私人定制和调优
3.学习成本高
2.SpringJdbc
特点
1.严格不算一个ORM框架,仅仅是使用模板方法对原生的JDBC进行了一层非常薄的封装
2.SpringJDBC可以帮助开发人员屏蔽创建数据库连接对statement对象和异常处理及事物的重复性代码,提高开发效率
3.足够简单和灵活,直接执行原生sql,提供多种template类,将对象中的属性映射为sql语句绑定的参数,还提供了很多的ORM化的callback,通过callback可以将ResultSet转为相应的对象列表。
4.属于spring家族的一员,与spring无缝集成,借助spring,SpringJdbc可以集成多种开源数据源和事物等功能。
缺点
1.不够自动,开发时候需要写很多sql语句
2.产生的结果需要自己去封装实现
3.mybatis
特点
1.拥有几乎hibernate的重要功能,包括(持久化、屏蔽底层底层重复的原生jdbc代码,配置映射,缓存等),当时相对hibernate更加轻量、灵活,是一种半自动化框架
2.能在配置文件中编写原生的sql语句,能充分的利用sql语句的优势,比如索引等,同时封装了对结果映射的处理使得能很方便的使用
3.提供动态的sql功能,提高开发效率
缺点
1.SQL语句的编写工作量较大,尤其是字段多、关联表多时,更是如此,对开发人员编写SQL语句的功底有一定要求。(但是mybatis-plus的产生,能解决绝大部分的sql编写)
2.SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库(目前基本公司使用数据库在生产上改动很小)
三、ORM框架选择
可以根据项目的大小和并发量等因素综合选择ORM框架,对性能的要求很高,或者需求变化较多的项目,如互联网项目,选择mybatis和SpringJdbc都是不错的选择。但是mybatis的开发效率会比SpringJdbc高,如果使用mybatis-plus能省去很多的sql语句编写。但是SpringJdbc天然集成Spring,足够简单,目前所在公司(日活几百万)就是使用SpringJdbc作为Dao层开发框架。所以说ORM框架的选择并没有固定,ORM框架选型要建立在项目实际需求基础之上。
但是不管如何,ORM框架的理念都是想通的,就是"简化开发提高开发效率"。mybatis框架适应互联网开发,目前绝大数公司使用mybatis作为首选dao层框架,同时mybatis源码简洁精悍,是提高我们编程水平较好的模板,做为一个java后端开发者,没有理由不去学习下mybatis。
四、mybatis之Hello World
1.maven项目搭建及pom文件
<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.0</modelVersion>
<groupId>com.qiu</groupId>
<artifactId>mybatis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.36</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
</project>
2.mysql中创建数据表
CREATE TABLE `country` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`countryname` varchar(255) DEFAULT NULL,
`countrycode` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
3.配置mybatis核心文件Mybatis-Config.xml
如果是使用eclipse开发建议先安装插件:(eclipse-->Eclipse MarketPlace--->mybtipse),安装完就有提示了。
<?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>
<settings>
<setting name="logImpl" value="LOG4J" />
</settings>
<typeAliases>
<!--配置别名-->
<package name="com.huya.qiu.model" />
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">
<property name="" value="" />
</transactionManager>
<dataSource type="UNPOOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost:3306/mybatis" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
<mappers>
<!--加载mapper文件-->
<mapper resource="com/huya/qiu/mapper/CountryMapper.xml" />
</mappers>
</configuration>
4.创建country实体类
public class Country {
private Long id;
private String countryname;
private String countrycode;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCountryname() {
return countryname;
}
public void setCountryname(String countryname) {
this.countryname = countryname;
}
public String getCountrycode() {
return countrycode;
}
public void setCountrycode(String countrycode) {
this.countrycode = countrycode;
}
@Override
public String toString() {
return "Country [id=" + id + ", countryname=" + countryname + ", countrycode=" + countrycode + "]";
}
}
5、创建mapper映射文件CountryMapper.xml
在com.huya.qiu.mapper包名下创建mapper映射文件,与config配置文件中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">
<!--包名位置+类型,用于唯一区分-->
<mapper namespace="com.qiu.mapper.CountryMapper">
<!-- resultType定义返回类型和前面config配置的别名对应 -->
<select id="selectAll" resultType="Country">
select * from country
</select>
</mapper>
6.配置log4j打印详细信息
在src/mian/resource目录下面创建log4j.properties文件,用于打印详细的日志信息。
#全局配置
log4j.rootLogger=ERROR,stdout
#mybatis日志配置,打印出详细sql过程
log4j.logger.com.qiu.mapper=TRACE
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] -%m%n
7.测试及结果
public class Demo1Test {
//SqlSessionFactory工厂类用于创建SqlSession
private static SqlSessionFactory sqlSessionFactory ;
@BeforeClass
public static void init() {
try {
//加载配置config配置文件
Reader reader=Resources.getResourceAsReader("Mybatis-Config.xml");
sqlSessionFactory=new SqlSessionFactoryBuilder().build(reader);
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void testSelectAll() {
//SqlSession是mybatis提高给开发者的一个门面,利用它提供的方法执行sql语句操作
SqlSession session=sqlSessionFactory.openSession();
try {
List<Country> countryList=session.selectList("selectAll");
countryList.forEach(System.out::println);
} catch (Exception e) {
e.printStackTrace();
}finally {
//关闭session
session.close();
}
}
}
测试结果:
DEBUG [main] -ooo Using Connection [com.mysql.jdbc.JDBC4Connection@34cd072c]
DEBUG [main] -==> Preparing: select * from country
DEBUG [main] -==> Parameters:
TRACE [main] -<== Columns: id, countryname, countrycode
TRACE [main] -<== Row: 1, 中国, cn
TRACE [main] -<== Row: 2, 美国, us
Country [id=1, countryname=中国, countrycode=cn]
Country [id=2, countryname=美国, countrycode=us]
五、从Hello World认识Mybatis的执行流程
1.通过Resources资源加载器将Mybatis-Config.xml配置文件读取入Reader中
2.然后通过SqlSessionFactoryBuilder建造类加载reader创建SqlSessionFactory工厂对象
(在创建时候会先解析核心配置文件,并读取核心配置文件中mappers属性中全部xxxMapper.xml映射文件
进行具体的方法解析,解析完成后SqlSessionFactory就包含了所有的配置属性和执行sql的信息)
3.创建SqlSession会话
4.通过SqlSession的selectList方法映射到CountryMapper.xml中id=“selectAll”的方法,
然后执行sql查询
5.在mybatis底层使用JDBC查询并根据xxxMapper中配置的返回类型对结果集进行了封装,返回查询结果
6.关闭会话连接,回收资源