关于MyBatis框架这一篇就够了
Posted Java架构师-大仙
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于MyBatis框架这一篇就够了相关的知识,希望对你有一定的参考价值。
一、MyBatis框架简介
1. 什么是框架?
框架(Framework)是整个或者部分系统的可重用设计,从应用角度看框架可以被当为一组抽象构件及构件实例间交互的方法;在应用目的的角度来看框架是一种可以被应用开发者定制的应用骨架。总结来讲,框架是一种半成品应用,是一种组件,可以辅助你开发自己的系统。
框架解决的问题
框架要解决的最重要的一个问题是技术整合的问题,在J2EE的框架中,有着各种各样的技术,不同的软件企业需要从J2EE中选择不同的技术,这就使得软件企业最终的应用依赖于这些技术,技术自身的复杂性和技术的风险性将会直接对应用造成冲击。而应用是软件企业的核心,是竞争力的关键所在,因此应该将应用自身的设计和具体的实现技术解耦。这样,软件企业的研发将集中在应用的设计上,而不是具体的技术实现,技术实现是应用的底层支撑,它不应该直接对应用产生影响。
框架一般处在低层应用平台(如J2EE)和高层业务逻辑之间的中间层,框架实现了部分功能,并能很好的进行业务逻辑和功能的整合。
软件开发中的分层思想
为了方便对软件进行开发和管理,实现软件工程中的“高内聚,低耦合”,将开发中的问题划分开各个解决,使得应用易于控制,易于扩展,易于资源管理,常见分层思想-MVC设计思想。通过分层更好的实现了各个部分的职责,再细分化出不同的框架,分别解决各层关注的问题。
分层开发中的常见框架
① 解决数据的持久层问题的框架–MyBatis
② 解决web层问题的框架–springMVC
③ 解决技术整合问题得框架–spring
2. MyBatis框架简介
MyBatis是一个优秀的基于Java的持久层框架,内部封装了jdbc,开发者仅需关注sql语句本身,不需要花更多的精力去处理加载驱动、创建连接、创建statement等繁杂的过程。
MyBatis通过注解或xml配置的方式将需要执行的statement配置起来,并通过Java对象和statement中sql的动态参数进行映射生成最终需要执行的sql语句,最后由Mybatis框架执行sql语句并将结果映射为Java对象并返回。
Mybatis采用 ORM思想决了实体类和数据库映射的问题,对jdbc进行了封装,屏蔽了jdbc底层API的访问细节,让我们不用和jdbc API打交道,也能完成数据库的访问操作。
强烈推荐阅读:MyBatis官方中文文档
二、MyBatis实现基本CRUD操作
1. 基本配置流程:
① 创建Maven工程,并添加坐标导入jar包
② 书写与数据库表映射的实体类
③ 书写持久层接口
④ 书写持久层接口的映射文件或在持久层接口书写注解
⑤ 书写配置文件
2. 持久层映射配置文件的使用
2.1 映射配置文件中的标签
2.1.1 常见的标签
<resultMap>
:用于配置返回的数据集,建立查询结果列名和实体类属性名之间的对应的关系。
id属性:指定名称
type属性:指定实体类名
- 内部标签
<id>
:用于配置与数据库表中的关键字对应的字段。 - 内部标签
<result>
:用于配置与数据库中的非关键字段对应的字段。- property属性:用于指定实体类的属性
- colum属性:用于指定数据库列的属性
<sql>
:用于书写通用的SQL语句,可以搭配 <include>
标签对通用SQL语句进行抽取。
2.1.2 与查询相关的标签
<insert>
:用于书写数据库插入相关的操作
<delete>
:用于书写数据库删除相关的操作
<update>
:用于书写数据库更新相关的操作
<select>
:用于书写数据库查询相关的操作
标签的属性
- id属性:要和持久层接口的方法名相同,否则找不到映射的方法。
- resultType属性:指定结果集的类型
- resultMap属性:指定结果集
- parameterType属性:指定传入参数的类型。如果传入的是自定义的类需要写类的全限定类名
- parameterMap属性:指定传入参数
此处列出的标签并不全,更多关于映射标签的介绍建议参考MyBatis官方的文档:MyBatis XML映射器
2.2 在标签内书写SQL语句
在对应的标签内部书写SQL语句,支持SQL语句中的联合查询、聚合查询等复杂查询。
sql语句中的 #{}
字符:表示占位符,相当于jdbc中的 ?
,用于执行SQL语句时替换实际数据,具体的数据
由大括号里的内容决定。
#{}
中内容的写法:如果为基本数据类型可以随意书写,如果是对象类型的则需要使用ognl表达。
ognl表达式:是Apache提供的一种表达式语言,全称是:object Graphic Navigation Language(对象导航语言),它按照一定的语法格式来获取数据,语法格式为:
#{对象.对象}
的方式
#{}
与 ${}
的区别:
#{}
表示一个占位符号:通过 #{}
可以实现向prepareStatement向占位符中设置值,自动进行Java类型和jdbc类型转换,#{}
可以防止SQL注入。#{}
可以接收简单类型值或pojo属性值。如果parameterType传输单个简单类型值,#{}
括号中可以是value或者其他名称。
${}
表示拼接字符串:通过 ${}
可以将parameterType传入的内容拼接在SQL中且不进行jdbc类型的转换,${}
可以接收简单类型值或pojo属性值,如果parameterType传输简单类型值,${}
括号中只能是value。
映射文件使用注意事项:
- 持久层接口和持久层接口的映射必须在相同的包结构下
- 持久层映射配置中mapper标签的namespace属性取值必须是持久层接口的全限定类名
3. MyBatis配置文件的使用
配置信息内容和顺序
-properties(属性):配置数据库连接文件
--property:单个配置数据库连接
-settings(全局配置参数):配置mybatis相关
--setting(子配置参数)
-typeAliases(类型别名):配置实体类别名
--typeAliase
--package(实体类包名)
-typeHandlers(类型处理器)
-objectFactory(对象工厂)
-plugging(插件)
-environments(环境集合属性对象)
--environment(环境子属性对象)
--transactionManager(事务管理)
--dataSource(数据源):引用properties配置中的内容
-mappers(映射器):指定映射文件位置
--mapper(指定映射类)
--resource(相对路径资源)
--class(多用于配置注解SQL):需要mapper接口名称和mapper映射文件名称相同,且在一个路径中。
--package(指定映射所在的包):需要mapper接口名称和mapper映射文件名称相同,且在一个路径中。
更多关于MyBatis配置文件的的内容建议查看MyBatis官方文档:MyBatis XML配置
4. 示例代码:
前期准备:执行SQL语句生成user表
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户名称',
`birthday` datetime(0) NULL DEFAULT NULL COMMENT '生日',
`sex` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '性别',
`address` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '地址',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 72 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (41, '老王', '2018-02-27 17:47:08', '男', '北京');
INSERT INTO `user` VALUES (42, '小二王', '2018-03-02 15:09:37', '女', '北京朝阳区');
INSERT INTO `user` VALUES (43, '小二王', '2018-03-04 11:34:34', '女', '北京朝阳区');
INSERT INTO `user` VALUES (45, 'Tom', '2018-03-04 12:04:06', '男', '北京朝阳区');
INSERT INTO `user` VALUES (46, '老王', '2018-03-07 17:37:26', '男', '北京');
INSERT INTO `user` VALUES (48, 'Bruce', '2020-09-14 14:54:47', '男', '山东威海');
INSERT INTO `user` VALUES (56, 'Tom', '2020-09-14 14:18:08', '男', '山东烟台');
INSERT INTO `user` VALUES (57, 'Jerry', '2020-09-14 14:15:51', '女', '山东烟台');
INSERT INTO `user` VALUES (60, 'Big M', '2020-09-17 11:28:08', '男', '啥不懂');
INSERT INTO `user` VALUES (67, '王五', '2020-09-15 08:41:57', '男', '浙江温州');
INSERT INTO `user` VALUES (68, 'update', '2020-09-17 16:13:24', '男', '北京市海淀区');
INSERT INTO `user` VALUES (69, 'test', '2020-09-17 15:59:56', '女', '北京市海淀区');
INSERT INTO `user` VALUES (70, 'test', '2020-09-17 16:07:22', '女', '北京市海淀区');
INSERT INTO `user` VALUES (71, 'test', '2020-09-17 16:07:35', '女', '北京市海淀区');
SET FOREIGN_KEY_CHECKS = 1;
① 创建Maven工程,并添加坐标
<!-- 配置编译插件 -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<!-- 设置打成jar包 -->
<packaging>jar</packaging>
<!-- 配置三方依赖库 -->
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
</dependencies>
② 书写与数据对应的实体类User
public class User {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
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 Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\\'' +
", birthday=" + birthday +
", sex='" + sex + '\\'' +
", address='" + address + '\\'' +
'}';
}
}
③ 书写持久层接口IUserDao
public interface IUserDao {
/**
* 获取所有的账户
* @return
*/
List<User> getUsers();
/**
* 保存账户
* @param user
*/
void saveUser(User user);
/**
* 更新账户
* @param user
*/
void updateUserById(User user);
/**
* 通过id查询用户
* @param userId
* @return
*/
User getUserById(Integer userId);
/**
* 通过id删除用户
* @param userId
*/
void deleteUserById(Integer userId);
/**
* 通过名称查询用户
* @param name
* @return
*/
List<User> getUserByName(String name);
/**
* 查询用户总数
* @return
*/
int getUserTotal();
}
④ 书写持久层接口的映射文件IUserDao.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="cn.bruce.dao.IUserDao">
<!-- 建立查询结果列名和实体类属性名之间的对应关系 -->
<resultMap id="userMap" type="user">
<!-- 关键字对应 -->
<id property="userId" column="id"/>
<!-- 非关键字对应 -->
<result property="userName" column="username"/>
<result property="userSex" column="sex"/>
<result property="userBirthday" column="birthday"/>
<result property="userAddress" column="address"/>
</resultMap>
<!-- 配置查询相关的语句 -->
<!-- 查询所有用户 -->
<select id="getUsers" resultMap="userMap">
select * from user;
</select>
<!-- 保存用户 -->
<insert id="saveUser" parameterType="user">
<selectKey keyProperty="userId" keyColumn="id" resultType="int" order="AFTER">
select last_insert_id();
</selectKey>
insert into user(username, sex, birthday, address) value (#{userName}, #{userSex}, #{userBirthday},
#{userAddress})
</insert>
<!-- 更新操作 -->
<update id="updateUserById" parameterType="user">
update user set username = #{userName}, sex = #{userSex}, birthday = #{userBirthday}, address =
#{userAddress} where id = #{userId}
</update>
<!-- 根据id查询用户 -->
<select id="getUserById" parameterType="int" resultMap="userMap">
select * from user where id = #{userId}
</select>
<!-- 根据id删除用户 -->
<delete id="deleteUserById" parameterType="java.lang.Integer">
delete from user where id = #{userId}
</delete>
<!-- 根据名称查询 -->
<select id="getUserByName" parameterType="string" resultMap="userMap">
select * from user where username like #{userName}
</select>
<!-- 获取用户记录总条目数 -->
<select id="getUserTotal" resultType="int">
select count(id) from user
</select>
</mapper>
⑤ 书写jdbc连接配置文件jdbcConfig.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/base_crud?characterEncoding=utf-8&useSSL=false
jdbc.username=root
jdbc.password=*****
⑥ 书写MyBatis配置文件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>
<!-- 三种配置方式效果相同,resource属性通过查找相对路径得到jdbc连接,url属性通过绝对路径获取jdbc连接,也可以通过配置property标签的方式指定jdbc连接 -->
<!-- 第一种方式,通过resource属性配置相对路径获取jdbc连接 -->
<properties resource="jdbcConfig.properties">
<!-- 第二种方式,通过url属性配置绝对路径获取jdbc连接 -->
<!--url="file:///E:/workspace/workspace_idea03/demo-mybatis/day02_mybatis01_CRUD/src/main/resources/jdbcConfig.properties">-->
<!-- 第三种方式,配置property标签的方式配置jdbc连接 -->
<!--<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/base_crud"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>-->
</properties>
<!-- typeAliases用于配置别名,只能配置domain中类的别名 -->
<typeAliases>
<!-- typeAlias用于配置别名。type属性配置实体类全限定类名。alias属性指定别名,指定别名后则区分大小写 -->
<!--<typeAlias type="cn.bruce.domain.User" alias="user"></typeAlias>-->
<!-- 用于指定配置别名的包,当指定后,该包下的实体类都会注册别名,并且类名就是别名,并且不区分大小写 -->
<package name="cn.bruce.domain"/>
</typeAliases>
<!-- 配置环境,配置jdbc连接和事务的控制 -->
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- 配置映射文件 -->
<mappers>
<mapper resource="dao/IUserDao.xml"></mapper>
<mybatis入门看这一篇就够了