目录
一、框架的概述
JavaEE开发是分层开发的,分别有:表现层、业务层、持久层
1.1 常见的JavaEE开发框架
1)解决数据的持久化问题的框架
MyBatis本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)
作为持久层的框架,还有一个封装程度更高的框架就是 Hibernate,但这个框架因为各种原因目前在国内的流行程度下降太多,现在公司开发也越来越少使用。 目前使用 Spring Data 来实现数据持久化也是一种趋势
2)解决 WEB层问题的 MVC 框架
Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。
Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。
使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的SpringMVC框架或集成其他MVC开发框架,如Struts1(现在一般不用),Struts2等。
3)解决技术整合问题的框架
Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。
Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson创建。简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架。
目的:解决企业应用开发的复杂性
功能:使用基本的JavaBean代替EJB
范围:任何Java应用
Spring是一个轻量级控制反转(IOC)和面向切面(AOP)的容器框架
1.2 总结
框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种定义认为,框架是可被应用开发者定制的应用骨架。前者是从应用方面而后者是从目的方面给出的定义。
简而言之,框架其实就是某种应用的半成品,就是一组组件,供你选用完成你自己的系统。简单说就是使用别人搭好的舞台,你来做表演。而且,框架一般是成熟的,不断升级的软件
二、Mybatis的概述
Mybatis是一个持久层的框架,对JDBC做了轻量级封装。
2.1 对JDBC的回顾
package com.cpz.jdbc;
import java.sql.*;
public class MainJdbc {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
//加载数据库驱动
Class.forName("com.mysql.jdbc.Driver");
//通过驱动管理类获取数据库链接
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?characterEncoding=utf-8","root", "root");
//定义sql语句 ?表示占位符
String sql = "select * from user where username = ?";
//获取预处理statement
preparedStatement = connection.prepareStatement(sql);
//设置参数,第一个参数为sql语句中参数的序号(从1开始),第二个参数为设置的参数值
preparedStatement.setString(1, "老王");
//向数据库发出sql执行查询,查询出结果集
resultSet = preparedStatement.executeQuery();
//遍历查询结果集
while(resultSet.next()){
System.out.println(resultSet.getString("id")+" "+resultSet.getString("username"));
}
} catch (Exception e) {
e.printStackTrace();
}finally{
//释放资源
if(resultSet!=null){
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(preparedStatement!=null){
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection!=null){
try {
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
JDBC缺陷总结:
1:数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库连接池可解决此问题。
2:Sql 语句在代码中硬编码,造成代码不易维护,实际应用 sql 变化的可能较大, sql 变动需要改变java 代码。
3:使用 preparedStatement 向占有位符号传参数存在硬编码,因为 sql 语句的 where 条件不一定,可能多也可能少,修改 sql 还要修改代码,系统不易维护。
4:对结果集解析存在硬编码(查询列名), sql 变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成 pojo 对象解析比较方便(通过映射,让查询的结果集直接封装到实体类的属性中)。
2.2 Mybatis的概述
它是基于Java编写的持久层框架,使开发者不必关心传统jdbc的api,只关心sql语句本身。
mybatis 通过 xml或注解的方式将要执行的各种 statement 配置起来,并通过 java 对象和 statement 中 sql的动态参数进行映射生成最终执行的 sql 语句,最后由 mybatis 框架执行 sql 并将结果映射为 java 对象并返回。采用 ORM 思想解决了实体和数据库映射的问题,对 jdbc 进行了封装,屏蔽了 jdbc api 底层访问细节,使我们不用与 jdbc api 打交道,就可以完成对数据库的持久化操作。
为了我们能够更好掌握框架运行的内部过程,并且有更好的体验,下面我们将从自定义 Mybatis 框架开始来学习框架。此时我们将会体验框架从无到有的过程体验,也能够很好的综合前面阶段所学的基础
2.3 ORM思想简介
ORM :Object Relational Mapping 对象关系映射(目的:操作对象,就可以操作数据库)
通过建立数据库表和Java实体类的对应关系,从而实现操作实体类就相当于操作数据库表。
ORM思想对应的框架有:mybatis(半自动),hibernate(全自动),spring data jpa(全自动,底层封装的就是hibernate)
作为持久层的框架,还有一个封装程度更高的框架就是Hibernate,但这个框架因为各种原因目前在国内的流行程度下降太多,现在公司开发也越来越少使用。目前使用Spring Data JPA来实现数据持久化也是一种趋势。
三、Mybatis框架入门案例
3.1 导入Maven依赖
<?xml version="1.0" encoding="UTF-8"?>
<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.itheima</groupId>
<artifactId>mybatis_day01_quick</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.18</version>
</dependency>
<!-- 日志坐标 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<!--测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
</dependencies>
</project>
3.2 创建数据库
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','女','南京');
3.3 创建实体类
public class User implements Serializable {
private int id;// 主键ID
private String username;// 用户姓名
private String sex;// 性别
private Date birthday;// 生日
private String address;// 地址
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", sex='" + sex + '\'' +
", birthday=" + birthday +
", address='" + address + '\'' +
'}';
}
}
3.4 创建接口UserDao.java
public interface UserDao {
//查询所有
List<User> findAll();
}
3.5 sqlMaoConfig.xml
在resources包下,新建sqlMapConfig.xml,表示mybatis的配置文件
<?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">
<!--mybatis的核心配置文件-->
<configuration>
<!--1:配置连接数据库的环境
environments default="mysql":名称随便填写
environment id="mysql":id表示当前环境的唯一标识
transactionManager type="JDBC":事务管理器,JDBC是固定要求
dataSource type="POOLED":数据源的连接池,POOLED固定写法,表示使用连接池
-->
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql:///test"></property>
<property name="username" value="root"></property>
<property name="password" value="1234"></property>
</dataSource>
</environment>
</environments>
<!--2:加载映射文件-->
<mappers>
<mapper resource="com/cpz/dao/UserDao.xml"></mapper>
</mappers>
</configuration>
3.6 创建UserDao.xml
因为是maven项目,所有xml的文件应该放在resources下,创建包com.cpz.dao,创建UserDao.xml,表示mybatis的映射文件(Dao有几个,映射文件就有几个)
<?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.cpz.dao.UserDao">
<!--查询所有-->
<select id="findAll" resultType="com.cpz.domain.User">
select * from user
</select>
</mapper>
3.7 创建测试类
package com.itheima.test;
import com.itheima.dao.UserDao;
import com.itheima.domain.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 org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class TestMybatis {
@Test
public void findAll() throws IOException {
// mybatis的api
// 1:加载sqlMapConfig.xml(配置文件),同时加载UserDao.xml(映射文件)
InputStream in = Resources.getResourceAsStream("sqlMapConfig.xml");
// 2:创建SqlSessionFactory(1个),相当于DataSource
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
// 3:创建SqlSession(多个,每个线程都会使用独立的SqlSession),相当于Connection
SqlSession sqlSession = sqlSessionFactory.openSession();
// 4:使用SqlSession获取Dao(底层反射和代理技术完成)
UserDao userDao = sqlSession.getMapper(UserDao.class);
// 5:操作Dao中的方法(重点)
List<User> list = userDao.findAll();
for (User user : list) {
System.out.println(user);
}
// 6:关闭资源
sqlSession.close();
in.close();
}
}
3.8 log4j.properties 日志配置文件
# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d://axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n