框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种定义认为,框架是可被应用开发者定制的应用骨架。前者是从应用方面而后者是从目的方面给出的定义。
简而言之,框架其实就是某种应用的半成品,就是一组组件,供你选用完成你自己的系统,或者说是使用别人搭好的舞台,你来做表演。框架一般是成熟的,不断升级的软件。
框架要解决的最重要的一个问题是技术整合的问题,在JavaEE的 框架中,有着各种各样的技术,不同的软件企业需要从JavaEE中选择不同的技术,这就使得软件企业最终的应用依赖于这些技术,技术自身的复杂性和技术的风险性将会直接对应用造成冲击。而应用是软件企业的核心,是竞争力的关键所在,因此应该将应用自身的设计和具体的实现技术解耦。这样,软件企业的研发将集中在应用的设计上,而不是具体的技术实现,技术实现是应用的底层支撑,它不应该直接对应用产生影响。
框架的重要性在于它实现了部分功能,并且能够很好的将低层应用平台和高层业务逻辑进行了缓和。为了实现软件工程中的“高内聚、低耦合”。把问题划分开来各个解决,易于控制,易于延展,易于分配资源。我们常见的MVC软件设计思想就是很好的分层思想。
通过分层更好的实现了各个部分的职责,在每一层将再细化出不同的框架,分别解决各层关注的问题。
Mybatis
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
作为持久层的框架,还有一个封装程度更高的框架就是Hibernate,但这个框架因为各种原因目前在国内的流行程度下降太多,现在公司开发也越来越少使用。目前Mybatis框架是主流,未来使用Spring Data来实现数据持久化也是一种趋势。
SpringMVC
Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的SpringMVC框架或集成其他MVC开发框架,如Struts1(现在一般不用),Struts2(一般老项目使用)等。
Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益。
Mybatis是一个优秀的基于Java的持久层框架,它内部封装了Jdbc,使开发者只需要关注sql语句本身,而不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。
Mybatis通过xml或注解的方式将要执行的各种statement配置起来,并通过java对象和statement中sql的动态参数进行映射生成最终执行的sql语句,最后由Mybatis框架执行sql并将结果映射为java对象并返回。
采用ORM思想解决了实体和数据库映射的问题,对Jdbc进行了封装,屏蔽了Jdbc Api底层访问细节,使我们不用与Jdbc Api打交道,就可以完成对数据库的持久化操作。
ORM :操作对象既是操作数据库
为了我们能够更好掌握框架运行的内部过程,并且有更好的体验,下面我们将从自定义Mybatis框架开始来学习框架。此时我们将会体验框架从无到有的过程体验,也能够很好的综合前面阶段所学的基础。
案例场景: 根据 user 表,查询出所有“上海”的用户对象,返回一个pojo的 List集合。
1、创建数据库,数据库名:mybatisDemo
2、将如下Sql语句在数据库中执行,初始化测试数据
-- ----------------------------
-- Table structure for `user`
-- ----------------------------
CREATE DATABASE mybatisdemo;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(32) NOT NULL COMMENT '用户名称',
`birthday` date DEFAULT NULL COMMENT '生日',
`sex` char(1) DEFAULT NULL COMMENT '性别',
`address` varchar(256) DEFAULT NULL COMMENT '地址',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', '张三', '2018-07-10', '1', '北京');
INSERT INTO `user` VALUES ('2', '李四', '2018-07-10', '1', '上海');
INSERT INTO `user` VALUES ('3', '王五', '2018-07-10', '1', '广州');
INSERT INTO `user` VALUES ('4', '王六', '2018-07-10', '1', '深圳');
INSERT INTO `user` VALUES ('5', '王八', '2018-07-10', '1', '上海');
代码:
import java.util.Date;
public class User {
private Integer id;
private String username;
private String sex;
private Date birthday;
private String address;
// 省略getter ,setter,toString 方法
// ......
// ......
}
JDBC问题分析:
上边使用JDBC的原始方法(未经封装)实现了查询数据库表记录的操作。
下面我们将通过Mybatis 解决部分问题。
步骤1-a: 创建Maven 工程,引入 Mybatis jar 包。(普通工程)
在pom 文件中加入一下代码
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.3</version>
</dependency>
配置jdk编译环境
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
步骤1-b 创建Spring boot 工程, 引入以下依赖.(Spring Boot)
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
步骤2: 定义Dao接口和实现类
Dao接口
public interface UserDao {
User selectUserById(int id);
public List<User> selectUserByAddr(String address);
}
public class UserDaoImpl implements UserDao{
public User selectUserById(int id){
return null;
}
public List<User>selectUserByAddr(String address){
return null;
}
}
步骤3: 新建 mybatis-config.xml 文件(Spring Boot 请略过)
在resources 文件夹中新建一个 mybatis-config.xml 文件, 主要包含数据库连接信息
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>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
<environments default="env1">
<environment id="env1">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatisdemo"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!--
<mappers>
<mapper resource="mapper/UserDao.xml"/>
</mappers>
-->
</configuration>
步骤4: 创建映射文件
在resources 文件夹中新建一个 UserDao.xml 文件,主要是包含 SQL 语句
映射文件
<?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="net.suncaper.mybatisdemo.dao.UserDao">
<select id="selectUser1" parameterType="java.lang.String" resultType="net.suncaper.mybatisdemo.entity.User">
select id, username ,birthday,sex , address from user where address = #{address}
</select>
<select id="selectUser2" parameterType="_int" resultType="net.suncaper.mybatisdemo.entity.User">
select id, username ,birthday,sex , address from user where id = #{id}
</select>
</mapper>
注意: 需要把映射文件添加到配置文件中 <mapper resource=“mapper/UserDao.xml”/>
步骤5: 实现查询User对象
UserDaoImpl.java
public class UserDaoImpl implements UserDao {
private SqlSession sqlSession;
//构造注入
public UserDaoImpl(SqlSession sqlSession) {
this.sqlSession = sqlSession;
}
@Override
public User selectUserById(int id) {
return sqlSession.selectOne("s1",id);
}
@Override
public List<User> selectUserByAddr(String address) {
return sqlSession.selectList("s2",address);
}
}
Test运行测试代码
package demo2test;
import net.suncaper.dao.UserDao;
import net.suncaper.dao.UserDaoImpl;
import net.suncaper.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 org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class MybatisTest {
SqlSession sqlSession = null;
@Before
public void before() {
try {
//1. 读取配置文件,(已经包含映射文件)
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
// 2. 创建SqlSessionFactory
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 3. 打开 sqlSession
sqlSession = sessionFactory.openSession();
} catch (IOException e) {
e.printStackTrace();
}
}
//想办法运行 映射文件的sql 语句
@Test
public void test0() {
User user = sqlSession.selectOne("s1", 1);
System.out.println(user);
System.out.println("==============================================================");
List<User> users = sqlSession.selectList("s2", "上海");
for (User u :
users) {
System.out.println(u);
}
}
@Test
public void test1() {
UserDao userDao = new UserDaoImpl(sqlSession);
System.out.println( userDao.selectUserById(1) );
}
@Test
public void test2() {
UserDao userDao = new UserDaoImpl(sqlSession);
List<User> users = userDao.selectUserByAddr("上海");
for (User u :
users) {
System.out.println(u);
}
}
}
步骤6: 映射文件中添加 resultMap
<?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="net.suncaper.dao.UserDao">
<resultMap id="baseResultMap" type="net.suncaper.entity.User">
<id column="id" property="id"></id>
<result column="username" property="name"/>
<result column="birthday" property="birthday"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
</resultMap>
<select id="s1" parameterType="_int" resultMap="baseResultMap">
select id, username ,birthday,sex , address from user where id = #{value}
</select>
<select id="s2" parameterType="string" resultMap="baseResultMap">
select id, username ,birthday,sex , address from user where address = #{address}
</select>
</mapper>
步骤7: 改成用Mapper的方式来实现
public interface UserMapper {
User selectUserById(int id);
List<User> selectUserByAddr(String address);
}
<select id="selectUserById" parameterType="_int" resultMap="baseResultMap">
select id, username ,birthday,sex , address from user where id = #{value}
</select>
<select id="s2" parameterType="string" resultMap="baseResultMap">
select id, username ,birthday,sex , address from user where address = #{address}
</select>
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> users = userMapper.selectUserByAddr("上海");
select:
public Employee getEmployeeById(Integer id );
<select id="getEmployeeById" resultType="net.suncaper.mybatis.beans.Employee">
select * from tbl_employee where id =${_parameter}
</select>
insert:
Mapper 接口方法
public Integer insertEmployee(Employee employee);
Mapper 映射文件
<insert id="insertEmployee" parameterType="com.mybatis.beans.Employee">
insert into tbl_employee(last_name,email,gender) values(#{lastName},#{email},#{gender})
</insert>
update:
Mapper 接口方法
public Boolean updateEmployee(Employee employee);
Mapper 映射文件
<update id="updateEmployee" >
update tbl_employee set last_name = #{lastName},email = #{email},gender = #{gender} where id = #{id}
</update>
delete:
Mapper 接口方法
public void deleteEmployeeById(Integer id );
Mapper 映射文件
<delete id="deleteEmployeeById" >
delete from tbl_employee where id= #{id}
</delete>