1.MyBatis概述
1.1.MyBatis是什么
MyBatis是一个持久层(DAO)框架,本质上是JDBC的一次封装。
1.2.MyBatis的作用
MyBatis是一个持久层框架,那么作用当然就是操作数据库(增删改查CRUD)。
1.3.为什么需要学习MyBatis
MyBatis的理念:让开发者编写10%的代码(相对于原生JDBC)就可以实现数据库的操作。
解决方案:持久层(DAO)的零实现,所谓的零实现,就是不用写实现类代码,直接使用接口就可以操作数据库。
MyBatis的定义,提高开发的效率、程序的健壮性、可扩展性、优雅性!!!真的写很少代码就可以增删改查。
在同等实现效果下,显著减少技术代码的编写,从而可以让开发人员关注业务逻辑代码的编写。
借用jQuery的理念就是:写的更少,做的更多(write less do more)。
1.4.MyBatis的作用
MyBatis框架能够让我们以最少的代码实现操作数据库。从而提高开发的效率!!!
–如何将代码减少呢?
【1】持久层的零实现 (不需要写实现类,底层通过动态代理实现)。
【2】无需编写结果集ResultSet和javaBean属性之间的映射关系的java代码,通过xml配置文件配置即可。
配置文件的作用记载对象和对象之间的映射关系或者依赖关系,在程序运行过程中动态的读取配置文件中的信息完成特定的程序应用。
1.5.MyBatis配置流程图
Resources:资源类,用于读取总配置文件。
SqlSessionFactoryBuilder:会话工厂构造类,通过读取的总配置文件构建会话工厂。
SqlSessionFactory:会话工厂。
SqlSession:会话操作对象,用于生成对应模块接口的代理对象(0实现)。
1.6.MyBatis的个人理解
MyBatis是一个持久层的框架,所谓的框架,无非就是一群牛逼的人封装了某一个java原生功能,而MyBatis就是对原生JDBC的一次封装,相对于我们自己的封装,MyBatis会更加的强大、健壮、高效,MyBatis的底层实现就是JDBC,我们封装过功能都清楚,封装无非就是将重复一样的代码在一个方法中写死,而那些随着业务场景不同的代码,则通过形参进行控制,封装过后,我们只需将变化的形参传递给封装的方法,那么我们就可以得到既定的返回值,封装把我们从编写繁琐无味的重复性代码中解放出来,从而使得我们可以更加关注业务逻辑代码的编写,进而降低开发成本,提高开发效率。所以学习MyBatis框架,首先学习如何使用Mybatis封装好的方法(功能),清楚MyBatis在开发中的使用流程,在熟练使用MyBatis进行业务开发之后,我们可以尝试的去学习Mybatis的源码,使得我们能更加灵活使用MyBatis进行开发。
MyBatis在项目中的使用流程:
【1】导包(MyBatis和数据库驱动的jar包)。
【2】编写mybatis-config.xml和xxxMapper.xml配置文件。
注意:[1]通常一个项目对应一个数据库实例、而一个数据库实例对应一个mybatis-config.xml配置文件,而项目中的一个模块对应一个xxxMapper.xml配置文件)。
xxxMapper.xml配置文件中编写模块DAO层接口中的抽象方法的sql语句。每一个方法的实际sql类型对应一个标签(select、insert、update、delete),这样做只是为了将代码语义化,方便后期代码维护。
【3】借助MyBatis封装好的SqlSessionFactoryBuilder对象的build方法构建一个数据库实例的sql会话对象(sqlSession)。
注意:build方法需要一个字节输入流(InputStream),是mybatis-config.xml总配置文件的字节输入流。
【4】通过sql会话对象的getMapper方法构建某一模块DAO层的代理对象(底层实现是动态代理)。
【5】通过代理对象调用模块DAO层接口中定义的方法。
2.入门示例
2.1.配置流程说明
–获得数据库连接
第一步:导入包(任何框架需要的事情)。
第二步:创建总配置文件,文件名可以随便写,官方推荐mybatis-config.xml。
第三步:创建一个MyBatisUtils工具类,(获得SqlSession对象)。
–需求:插入数据到数据库
第四步:创建一个映射接口(如UserMapper)。
第五步:创建一个映射文件(如UserMapper.xml)。
第六步:在总配置文件中配置映射文件(在mybatis-config.xml配置文件中mappers标签中引入一个mapper标签,resources属性值为的映射文件的路径)。
第七步:编写测试插入数据代码(通过UserMapper接口调用UserDao中的方法)。
PS:数据库sql脚本
/*
Navicat Premium Data Transfer
Source Server : root
Source Server Type : MySQL
Source Server Version : 50562
Source Host : localhost:3306
Source Schema : users
Target Server Type : MySQL
Target Server Version : 50562
File Encoding : 65001
Date: 12/12/2019 16:25:24
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for tb_user
-- ----------------------------
DROP TABLE IF EXISTS `tb_user`;
CREATE TABLE `tb_user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '姓名',
`age` int(11) NULL DEFAULT NULL COMMENT '年龄',
`email` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '邮箱',
`password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '密码',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1188715086030696464 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
SET FOREIGN_KEY_CHECKS = 1;
2.2.配置步骤
2.2.1.下载MyBatis框架
https://github.com/MyBatis/MyBatis-3
2.2.2.创建一个普通java项目并导入相关jar包
2.2.3.创建主配置文件 mybatis-config.xml
在项目的 src (类路径 classpath) 下面创建配置文件 mybatis-config.xml。
2.2.3.1.1.具体配置参考MyBatis的官方文档即可
<?xml version="1.0" encoding="UTF-8" ?>
<!-- dtd约束 -->
<!DOCTYPE configuration
PUBLIC "-//MyBatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- 根元素: 用于配置MyBatis -->
<configuration>
<!-- 配置MyBatis的运行环境 ,可以配置多个环境,但是一次只能使用一个
default属性 : 当前使用的环境 ,使用下面环境的id 即可 -->
<environments default="dev_mysql">
<!-- 环境配置 id 属性,唯一标识当前环境 -->
<environment id="dev_mysql">
<!-- 配置MyBatis事务管理器
type属性 : 事物类型
JDBC 使用事务(正常提交commit,异常回滚事务 rollback) 默认
MANAGED : 不使用事务
-->
<transactionManager type="JDBC"/>
<!-- 配置MyBatis的数据源
type : 配置连接池
POOLED :MyBatis内置的一个连接池(默认)
后期都交给spring管理了,配置 dbcp连接池,阿里巴巴的 druid连接池
-->
<dataSource type="POOLED">
<!-- 连接数据库的操作 -->
<!-- 数据库驱动 -->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!-- 连接数据库的url -->
<property name="url" value="jdbc:mysql://localhost:3306/users"/>
<!-- 连接数据库账号 -->
<property name="username" value="root"/>
<!-- 连接数据库密码 -->
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- 配置映射文件 -->
<mappers>
<!-- <mapper resource="org/cjw/mapper/UserMapper.xml"/>--> <!--指定一个配置文件-->
<!--<package name="org.cjw.mapper"/>--> <!-- 指定一个包,包含多个配置文件或者配置类,推荐 -->
<mapper class="org.cjw.mapper.UserMapper" /> <!-- 指定一个配置类 -->
</mappers>
</configuration>
2.2.4.创建MyBatisUtil工具类
MyBatisUtil工具类的作用主要用于读取配置文件,创建工厂对象,提供创建SqlSession数据库操作对象的方法。
package org.cjw.utils;
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 MyBatisUtil {
private MyBatisUtil() {}
private static SqlSessionFactory sqlSessionFactory;
static {
try(InputStream in = Resources.getResourceAsStream("mybatis-config.xml")) {
sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession openSession() {
return sqlSessionFactory.openSession();
}
}
2.2.5.创建数据库表对应的实体类
package org.cjw.pojo;
public class User {
private Long id;
private String name;
private Integer age;
private String email;
private String password;
public User() {
}
public User(Long id, String name, Integer age, String email, String password) {
this.id = id;
this.name = name;
this.age = age;
this.email = email;
this.password = password;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
2.2.6.创建一个操作接口
package org.cjw.mapper;
import org.cjw.pojo.User;
public interface UserMapper {
/*
使用MyBatis的动态代理开发编写代码遵循四个原则
1.映射文件的namespace命名空间的值必须是对应接口的全限定名。
2.映射文件的对应功能 id值必须等于映射接口中方法的名称。
3.映射文件的参数类型必须和接口中方法的参数类型一致。
4.映射文件查询的返回结果类型必须和接口的方法的返回数据类型一致,
DML操作返回的受影响的行数,除外。
*/
void insert(User user);
}
2.2.7.创建表对应的映射文件 :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">
<!-- 配置映射
namespace : 命名空间(通俗说法: 给当前映射文件的唯一标识:起一个唯一的名字)
-->
<mapper namespace="org.cjw.mapper.UserMapper">
<!-- 新增操作
id: 当前功能的唯一标识,和接口方法同名
parameterType : 参数的类型
useGeneratedKeys:是否返回数据库生成的主键 true是/false否
keyProperty : 数据库主键对应java的pojo对象的属性
keyColumn : 数据表的主键列名
-->
<insert id="insert" parameterType="org.cjw.pojo.User" keyProperty="id" keyColumn="id">
insert into tb_user (name, age, email, password) values (#{name}, #{age}, #{email}, #{password});
</insert>
</mapper>
2.2.8.创建测试类准备测试
@Test
public void testInsert() {
SqlSession session = MyBatisUtil.openSession();
try {
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = new User();
user.setName("李四");
user.setAge(14);
user.setEmail("lisi@qq.com");
user.setPassword("lisi");
userMapper.insert(user);
session.commit();
} catch (Exception e) {
e.printStackTrace();
session.rollback();
} finally {
session.close();
}
}
3.log4j日志框架的配置
3.1.说明
log4j是一个日志输出框架,就是用于输出日志的。
MyBatis的日志输出是通过log4J输出的。主流框架大部分都是log4j输出的。Spring框架也可以通过log4j输出日志!!
问题:既然log4j功能类似System.out.println(),为什么使用log4j而不直接使用System.out.println()?
答:log4j提供了强大的日志输出的自定义功能。
1.通过级别输出日志 (调试、信息、警告、错误、致命异常)。
2.可以指定输出到控制台,以及输出到文件。
3.可以设置输出的日志格式。
所以学习LOG4J.需要学会自定义配置LOG4J的输出格式以及输出等级。
3.2.下载路径
Log4j的下载地址:http://logging.apache.org/log4j/1.2/
3.3.配置步骤
3.3.1.第一步:导入log4j-1.2.17.jar的包
3.3.2.第二步:在src下创建一个log4j.properties文件
注意:文件名必须为log4j.properties
# Global logging configuration
log4j.rootLogger=debug, stdout
log4j.logger.org.cjw.mapper=TRACE // 需要修改为自己的包名
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
3.4.运行效果
4.MyBatis完成CRUD操作
4.1.单行查询
4.1.1.映射文件
<select id="selectUserById" resultType="org.cjw.pojo.User">
select * from tb_user where id = #{id}
</select>
4.1.2.测试方法
@Test
public void testSelectUserById() {
SqlSession session = MyBatisUtil.openSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = userMapper.selectUserById(1);
System.out.println(user.getName());
}
4.2.多行查询
4.2.1.映射文件
<!-- 多行查询
resultType : 无论是多行查询还是单行查询,返回的结果类型都是对应的JavaBean的类型
-->
<select id="selectAll" resultType="org.cjw.pojo.User">
select * from tb_user
</select>
4.2.2.测试方法
@Test
public void testSelectAll() {
SqlSession session = MyBatisUtil.openSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
List<User> users = userMapper.selectAll();
for (User user : users) {
System.out.println(user.getName());
}
}
4.3.删除操作
4.3.1.映射文件
<delete id="deleteUserById">
delete from tb_user where id = #{id}
</delete>
4.3.2.测试方法
@Test
public void testDeleteUserById() {
SqlSession session = MyBatisUtil.openSession();
try {
UserMapper userMapper = session.getMapper(UserMapper.class);
userMapper.deleteUserById(1);
session.commit();
} catch (Exception e) {
e.printStackTrace();
session.rollback();
} finally {
session.close();
}
}
4.4.修改操作
4.4.1.映射文件
<update id="updateUserById" parameterType="org.cjw.pojo.User">
update tb_user set
name = #{name}, age = #{age}, email = #{email}, password = #{password}
where id = #{id}
</update>
4.4.2.测试方法
@Test
public void testUpdateUserById() {
SqlSession session = MyBatisUtil.openSession();
try {
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = new User();
user.setId(2L);
user.setName("zhangsan");
user.setEmail("zhangsan@126.com");
user.setPassword("zhangsan123123123");
userMapper.updateUserById(user);
session.commit();
} catch (Exception e) {
e.printStackTrace();
session.rollback();
} finally {
session.close();
}
}
5.ResultMap 手动映射
MyBatis的查询结果集都是自动映射封装的,单行查询将数据库一条数据封装成对应的Java对象。多行查询,先将每一行封装成对象,再将每个对象添加到集合中,最后返回一个List集合对象。
但是:必须保证查询结果集和pojo对象的属性名相同,否则无法自动封装。
问题: 如何解决查询结果集名称和pojo对象属性不同的映射封装?
解决方案:
1.使用手动映射封装 标签。
2.可以使用MyBatis的驼峰命名法,但是也必须遵循一定规则才行。
<select id="selectUserById" resultMap="user_map">
select id u_id, name u_name, age u_age, email u_email, password u_password from tb_user where id = #{id}
</select>
<resultMap id="user_map" type="User">
<id property="id" column="u_id" />
<result property="name" column="u_name"/>
<result property="age" column="u_age"/>
<result property="email" column="u_email"/>
<result property="password" column="u_password"/>
</resultMap>
6.主配置文件说明与细节配置
<environments>:环境集标签,就是用于配置数据库的连接信息的。
<environment>:用于配置具体环境参数。
<transactionManager>:配置使用的事务类型,JDBC。
<dataSource>:配置数据源的参数,POOLED。
具体参数参看PooledDataSource的set方法。
<property>:配置属性
<mappers>:配置映射文件信息的
<mapper class|resource>:配置具体指定的mapper文件
class:配置使用注解时指定有注解的映射接口
resource:指定映射文件
<package name>:配置配置文件、配置类所在的包,推荐
<properties>:MyBatis读取classpath路径下配置文件,一般用于读取db.properties。
<typeAliases>:用于配置别名。
<typeAliase type alias>
type:指定取别名的全限定名
alias:别名`在这里插入代码片`
<package name>
name:指定取别名的包
<typeHandlers>:用于配置自定义类型处理器。
<settings>:配置MyBatis的默认设置的(开启二级缓存、驼峰命名自动映射)。
总配置文件的标签顺序
<!ELEMENT configuration (properties?, settings?, typeAliases?, typeHandlers?, objectFactory?, objectWrapperFactory?, reflectorFactory?, plugins?, environments?, databaseIdProvider?, mappers?)>
这句话的意思就是configuration标签下的标签的顺序以及标签出现的个数的声明。
根据这个声明可以看到顺序为:
1.properties
2.settings
3.typeAliases
4.typeHandlers
5.objectFactory
6.objectWrapperFactory
7.reflectorFactory
8.plugins
9.environments
10.databaseIdProvider
11.mappers
DTD规则文件标签的出现的次数说明
如果声明的标签后?:表示出现0-1次
如果声明的标签后*:表示出现0-N次
如果声明的标签后+:表示出现1-N次
如果声明的标签后什么都没有:表示出现1次
6.1.别名typeAliases标签
在UserMapper.xml文件中User无论是作为参数还是作为查询返回数据类型,都需要写上全限定名,实际可以写上简单类名即可,但是需要配置别名。
MyBatis框架提供了两种别名机制,一种是自定义别名,一种是内置别名。
6.1.1.自定义别名
<?xml version="1.0" encoding="UTF-8" ?>
<!-- dtd约束 -->
<!DOCTYPE configuration
PUBLIC "-//MyBatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- 根元素: 用于配置MyBatis -->
<configuration>
<!-- 别名配置 -->
<typeAliases>
<!--
<typeAlias type="" alias=""/>
设置单个类型的别名
type: 要设置别名的数据类型(全限定名)
alias : 取的别名,一般都使用类的简单名称
<package name="" />
设置一个包的别名,推荐
-->
<typeAlias type="org.cjw.pojo.User" alias="User" />
<package name="org.cjw.pojo"/>
</typeAliases>
<!-- 配置MyBatis的运行环境 ,可以配置多个环境,但是一次只能使用一个
default属性 : 当前使用的环境 ,使用下面环境的id 即可 -->
<environments default="dev_mysql">
<!-- 环境配置 id 属性,唯一标识当前环境 -->
<environment id="dev_mysql">
<!-- 配置MyBatis事务管理器
type属性 : 事物类型
JDBC 使用事务(正常提交commit,异常回滚事务 rollback) 默认
MANAGED : 不使用事务
-->
<transactionManager type="JDBC"/>
<!-- 配置MyBatis的数据源
type : 配置连接池
POOLED :MyBatis内置的一个连接池(默认)
后期都交给spring管理了,配置 dbcp连接池,阿里巴巴的 druid连接池
-->
<dataSource type="POOLED">
<!-- 连接数据库的操作 -->
<!-- 数据库驱动 -->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!-- 连接数据库的url -->
<property name="url" value="jdbc:mysql://localhost:3306/users"/>
<!-- 连接数据库账号 -->
<property name="username" value="root"/>
<!-- 连接数据库密码 -->
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- 配置映射文件 -->
<mappers>
<!-- <mapper resource="org/cjw/mapper/UserMapper.xml"/>--> <!--指定一个配置文件-->
<!--<package name="org.cjw.mapper"/>--> <!-- 指定一个包,包含多个配置文件或者配置类,推荐 -->
<mapper class="org.cjw.mapper.UserMapper"/> <!-- 指定一个配置类 -->
</mappers>
</configuration>
如果配置成功,在映射文件里面可以直接使用别名
<?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">
<!-- 配置映射
namespace : 命名空间(通俗说法: 给当前映射文件的唯一标识:起一个唯一的名字)
-->
<mapper namespace="org.cjw.mapper.UserMapper">
<!-- 新增操作
id: 当前功能的唯一标识,和接口方法同名
parameterType : 参数的类型
useGeneratedKeys:是否返回数据库生成的主键 true是/false否
keyProperty : 数据库主键对应java的pojo对象的属性
keyColumn : 数据表的主键列名
-->
<insert id="insert" parameterType="User" keyProperty="id" keyColumn="id">
insert into tb_user (name, age, email, password) values (#{name}, #{age}, #{email}, #{password});
</insert>
<select id="selectUserById" resultType="User">
select * from tb_user where id = #{id}
</select>
<!-- 多行查询
resultType : 无论是多行查询还是单行查询,返回的结果类型都是对应的JavaBean的类型
-->
<select id="selectAll" resultType="User">
select * from tb_user
</select>
<delete id="deleteUserById">
delete from tb_user where id = #{id}
</delete>
<update id="updateUserById" parameterType="User">
update tb_user set
name = #{name}, age = #{age}, email = #{email}, password = #{password}
where id = #{id}
</update>
</mapper>
6.1.2.内置别名
所谓的内置别名,就是MyBatis框架自带别名。
MyBatis已经将常用的数据类型的别名声明了,所以这些内置的别名不需要配置就可以直接使用。
内置的别名就是,MyBatis框架默认已经设置的别名.
6.2.properties 读取配置文件
一般开发会单独将数据库连接信息配置到db.properties 配置文件中。
Mybaits框架中配置文件的标签可以读取配置文件中的内容。并可以使用${key}的语法取出properties配置文件中的value设置给框架的数据库连接参数。
6.2.1.在classpath下面创建一个db.properties数据库连接配置文件
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/users?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root
6.2.2.在MyBatis-config.xml主配置文件中配置标签读取配置文件
<!--
读取classpath下面的 数据库配置文件、
读取以后在下面连接数据库的配置中就可以使用
${配置文件key}获取对应的数据库连接相关信息
-->
<properties resource="db.properties" />
6.2.3.连接数据库的配置修改为 ${key}的方式
<dataSource type="POOLED">
<!-- 连接数据库的操作 -->
<!-- 数据库驱动 -->
<property name="driver" value="${jdbc.driverClassName}"/>
<!-- 连接数据库的url -->
<property name="url" value="${jdbc.url}"/>
<!-- 连接数据库账号 -->
<property name="username" value="${jdbc.username}"/>
<!-- 连接数据库密码 -->
<property name="password" value="${jdbc.password}"/>
</dataSource>
6.3.settings标签
MyBatis默认设置了很多默认配置。有时候,我们需求与默认的配置的参数不一样,我们就需要修改这些默认配置的参数。
如:MyBatis对骆驼命名法的支持默认是不开启的。可以通过
mapUnderscoreToCamelCase参数设置为true支持。
表示MyBatis启动可以配置的设置。
如支持骆驼命名法
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
7.MyBatis的注解开发
MyBatis的映射配置除了使用xml配置以外,还支持注解配置sql语句。
问题: 为什么有了xml配置还有注解配置。
答 :MyBatis的注解开发更简洁,只需要将对应的SQL语句的注解标注对应的功能方法上即可,直接连 XxxMapper.xml映射文件都可以省略了。
本身注解开发就是Java配置的一种趋势,后期学习SpringBoot时候,发现全部用纯注解配置。
MyBatis提供了下面注解进行映射文件配置
@Select 查询数据注解
@Insert 插入数据注解
@Delete 删除数据注解
@Update 修改数据注解
@Options 选项配置
@Results 手动映射配置
@Result: @results中的具体的某一列的映射信息配置
7.1.案例代码
package org.cjw.mapper;
import org.apache.ibatis.annotations.*;
import org.cjw.pojo.User;
import java.util.List;
public interface UserMapper {
/*
使用MyBatis的动态代理开发编写代码遵循四个原则
1.映射文件的namespace命名空间的值必须是对应接口的全限定名。
2.映射文件的对应功能 id值必须等于映射接口中方法的名称。
3.映射文件的参数类型必须和接口中方法的参数类型一致。
4.映射文件查询的返回结果类型必须和接口的方法的返回数据类型一致,
DML操作返回的受影响的行数,除外。
*/
@Insert("insert into tb_user (name, age, email, password) values (#{name}, #{age}, #{email}, #{password})")
void insert(User user);
@Select("select id u_id, name u_name, age u_age, email u_email, password u_password from tb_user where id = #{id}")
@Results({
@Result(id = true, property = "id", column = "u_id"),
@Result(property = "age", column = "u_age"),
@Result(property = "name", column = "u_name"),
@Result(property = "email", column = "u_email"),
@Result(property = "password", column = "u_password")
})
User selectUserById(Integer id);
@Select("select * from tb_user")
List<User> selectAll();
@Delete("delete from tb_user where id = #{id}")
void deleteUserById(Integer id);
@Update("update tb_user set age = #{age}, name = #{name}, email = #{email}, password = #{password} where id = #{id}")
void updateUserById(User user);
}
7.2.注解映射的配置
<mappers>
<!-- <mapper resource="org/cjw/mapper/UserMapper.xml"/>--> <!--指定一个配置文件-->
<!--<package name="org.cjw.mapper"/>--> <!-- 指定一个包,包含多个配置文件或者配置类,推荐 -->
<mapper class="org.cjw.mapper.UserMapper"/> <!-- 指定一个配置类 -->
</mappers>
该映射类的xml配置文件不能放置到该映射类同包环境下,否则会报映射语句已经包含的异常。
8.方法多参数传递使用-@Param注解
MyBatis默认情况下是不支持传入多个参数的,只能传入一个参数。
所谓的传入参数指的是MyBatis操作()的传入参数。
方案1:将这些参数封装到一个对象里面(JavaBean/Map),再传入。
方案2:给参数设置一个@Param注解支持,而且多参数的类型要统一。
问题:为什么不支持多个参数?
因为Java语法1.7以前,是不能通过反射技术获得方法的参数名的。
解决方案使用@Param 参数注解。
8.1.案例代码
@Select("select * from tb_user where name = #{name} and password = #{password}")
User login(User user);
@Select("select * from tb_user where name = #{name} and password = #{password}")
User login2(Map<String, Object> map);
@Select("select * from tb_user where name = #{name} and password = #{password}")
User login3(@Param("name") String name, @Param("password") String password);
8.2.测试代码
@Test
public void testLogin() {
SqlSession session = MyBatisUtil.openSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = new User();
user.setName("zhangsan");
user.setPassword("zhangsan123123");
User loginUser = userMapper.login(user);
System.out.println(loginUser.getName());
}
@Test
public void testLogin2() {
SqlSession session = MyBatisUtil.openSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
Map<String, Object> map = new HashMap<String, Object>();
map.put("name", "zhangsan");
map.put("password", "zhangsan123123");
User loginUser = userMapper.login2(map);
System.out.println(loginUser.getName());
}
@Test
public void testLogin3() {
SqlSession session = MyBatisUtil.openSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
User loginUser = userMapper.login3("zhangsan", "zhangsan123123");
System.out.println(loginUser.getName());
}
9.#{}与${}的区别
在MyBatis框架中支持两种 OGNL语法
#{}
${}
#{}基于JDBC的PreparedStatement类,SQL语句参数使用?占位符,在运行阶段动态设置参数,但是?不能作为表名。
预编译语句对象的SQL语句只能操作DML和DQL 语句,不能操作DDL语句。
1.#{}表示设置预编译的参数,就是?的参数,所以如果要不固定的表名不能使用#{},只能使用${}
2.${}直接把值输出来,直接把参数拼接到SQL语句中.而#{}是使用?来代替. 所以${}是不安全的。
3.${}只能获得参数池的值,而#{}可以获得方法的参数值,也可以获得参数池的值,如果使用${}获得参数的值,这个参数必须要加上@Param。
如果非必要情况,不要使用${}。
问题:那么${}有什么用呢?
答:注意基于JDBC的接口的原来的表名是不可以使用?的,?只能用于传入的参数。
如果操作的涉及表名这些非参数的数据时,需要使用${}。
9.1.删除案例代码
import org.apache.ibatis.annotations.Param;
public interface UserMapper {
/**
* 动态删除数据库中指定表名
* @param tableName 表名
* @return
*/
int dropTable(@Param("tableName")String tableName);
}
<?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">
<!-- 映射配置
namespace : 命名空间,通俗讲,每个映射文件唯一的标识名称
-->
<mapper namespace="org.cjws.mybatis.mapper.UserMapper">
<!--
使用 #{} 不能使用在表名操作
-->
<delete id="dropTable" parameterType="String">
<!-- drop table #{tableName} -->
drop table ${tableName}
</delete>
</mapper>
9.2.打印效果
9.2.1使用 #{}
使用此种方法无法删除数据库表