赞
踩
Mybatis: 优秀的持久层框架,用于简化JDBC的开发.支持自定义 SQL, 存储过程和高级映射。几乎消除了 所有 JDBC 代码和手动设置参数和检索的结果。MyBatis 可以使用简单的 XML 或 的注释配置和映射文件和映射接口和数据映射(普通 Java 对象)到数据库记录。
Mybatis是对JDBC代码的封装与简化
Mybatis官网:Mybatis官网
A. Mybatis依赖(Maven)
<!--mysql驱动连接 jar包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.31</version>
</dependency>
<!--Mybatis框架 jar包-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
B. 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"> <configuration> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <!--数据库连接名 : xxxxxx--> <property name="url" value="jdbc:mysql:///xxxxxx?useSSL=false&useServerPrepStmts=true"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <!--扫描mapper xxx.xxx--> <mappers> <package name="xxx.xxx"/> </mappers> </configuration>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--Mapper接口全限定名-->
<mapper namespace="com.dao.xxx">
<!--id 与接口方法名对应, 保持参数和返回类型一致-->
<select id="xxxxx" resultType="com.pojo.xxxx">
SQL语句
</select>
</mapper>
package com.dao;
import com.pojo.User;
public interface UserMapper {
User selectById(int id);
}
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
userMapper.xxxx()
sqlSession.close(); // 释放资源
A. 相关依赖配置(Maven)
<!--junit测试单元 jar包-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency>
<!--log4j配置 jar包-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
B. log4j.properties
log4j.logger.com.ibatis=DEBUG
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
c. mybatis-config.xml当中加入log4j的相关设置
<settings>
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
Mybatis 配置文件严格按照顺序配置元素
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "https://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!--配置相关属性文件--> <properties></properties> <!--setting项, 对Mybatis运行行为调整--> <settings></settings> <!--简化合格的类名--> <typeAliases></typeAliases> <!--解决自定义数据类型与JDBC数据库类型转换--> <typeHandlers></typeHandlers> <!--创建新的结果集对象--> <objectFactory></objectFactory> <!--配置plugins拦截器--> <plugins></plugins> <!--数据源环境配置--> <environments default=""> <environment id=""> <transactionManager type=""></transactionManager> <dataSource type=""></dataSource> </environment> </environments> <!--配置xml映射文件路径--> <mappers></mappers> </configuration>
A. properties文件 : 支持读取外部的属性文件,这样可以在属性文件中配置大量备用信息,而Mybatis可以根据键值选择使用部分内容.
B. db.properties文件
driver = com.mysql.cj.jdbc.Driver
url = jdbc:mysql://localhost:3306/test?useSSL=false&useServerPrepStmts=true
username = root
password = 123456
C. Mybatis配置文件当中进行声明
<properties resource="db.properties"></properties>
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
动态SQL语句是用来简化用户在有条件时拼接SQL语句的操作,当有条件的拼接SQL语句的时候我们就可以使用动态SQL来简化SQL语句的编写
以下示例用户表结构
a. 动态单条件查询:
代码及运行结果 : 会根据条件的不同, 自动组装出不同的SQL语句
<select id="selectUser" resultType="com.pojo.User"> select * from tb_user where <choose> <when test="id != null"> id = #{id} </when> <when test="username != null"> username = #{username} </when> <when test="password != null"> password = #{password} </when> <otherwise> 1 = 1 </otherwise> </choose> </select>
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> list = userMapper.selectUser(1, "1", null); // 默认匹配第一个成功匹配的条件
/* 若都不匹配则执行最后的otherwise语句
List<User> list = userMapper.selectUser(null, null, null); */
System.out.println(list);
sqlSession.close(); // 释放资源
}
## 匹配第一个成功匹配的语句
## 执行otherwise语句
b. 动态多条件查询:
使用where标签去完成动态多条件查询,此标签会动态判断当语句以 and/or 开头时,会动态将其删除,将其改为一个合法的SQL语句
<select id="selectUser" resultType="com.pojo.User">
select * from tb_user
<where>
<if test="id != null">
and id = #{id}
</if>
<if test="username != null">
and username = #{username}
</if>
<if test="password != null">
and password = #{password}
</if>
</where>
</select>
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> list = userMapper.selectUser(null, "1", "123");
System.out.println(list);
sqlSession.close(); // 释放资源
}
## 自动处理多余的 and / or 连接字符
注意Mybatis 事务默认是开启的,对数据表进行修改操作需要手动提交事务(或者在开始设置时就将其设置为自动添加)
Mybatis 可以设置主键自增,让数据库自己自动生成主键,并且通过keyProperty可以映射回生成的主键
<insert id="insetUser" useGeneratedKeys="true" keyProperty="id">
insert into tb_user(id, username, password) values(#{id}, #{username}, #{password});
</insert>
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User u = new User(0, "7", "7");
userMapper.insetUser(u);
System.out.println(u); // 注意关注User的id, 会被返回成自动生成的主键
sqlSession.commit(); // 事务提交
sqlSession.close(); // 释放资源
}
## 自动生成主键,并将主键返回到对象当中
通过使用 set标签 + if 语句 进行动态的修改部分数据。 set标签会动态判断合法的内容,然后动态的将多余的逗号删除
<update id="updateUser">
update tb_user
<set>
<if test="username != null and username != '' ">
username = #{username},
</if>
<if test="password != null and password != '' ">
password = #{password},
</if>
</set>
where id = #{id}
</update>
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User u = new User(1, "11", "12");
userMapper.updateUser(u);
sqlSession.commit(); // 事务提交
sqlSession.close(); // 释放资源
}
## 自动对合法修改内容进行拼接(删除末尾多余的逗号)
借助foreach语句可以实现批量删除
<delete id="deleteUser">
delete from tb_user where id in
<!-- 从collection当中取出元素集合, item: 每个元素的名字, seperator: 元素之间的分隔符, open/clos: 语句起始结尾符号 -->
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
int id[] = {1, 2};
userMapper.deleteUser(id);
sqlSession.commit(); // 事务提交
sqlSession.close(); // 释放资源
}
## 运行结果
#{}: 会使用 ? 代替原位置占位符, 之后再自动设置参数 (参数传递时使用)
${}: 会直接拼接SQL语句,可能会造成SQL注入问题. (可以用于对表名与列名进行动态设置)
#{}占位符使用
${}占位符使用
1. 使用转义字符处理
2. 使用 <![CDATA[内容]]> 处理
<select id="selectUserById" resultType="com.pojo.User">
select * from tb_user where id
<!--或者使用转义字符 < -->
<![CDATA[
<
]]>
#{id}
</select>
## 运行结果
public Object getNamedParams(Object[] args) { // 处理参数封装 int paramCount = this.names.size(); if (args != null && paramCount != 0) { if (!this.hasParamAnnotation && paramCount == 1) { // 单个参数 且 未使用注解 Object value = args[(Integer)this.names.firstKey()]; // 调用方法进行封装 return wrapToMapIfCollection(value, this.useActualParamName ? (String)this.names.get(0) : null); } else { // 多个参数或者使用了注解 Map<String, Object> param = new ParamMap(); int i = 0; for(Iterator var5 = this.names.entrySet().iterator(); var5.hasNext(); ++i) { Entry<Integer, String> entry = (Entry)var5.next(); param.put(entry.getValue(), args[(Integer)entry.getKey()]); // 产生 arg[] 或者 注解 键 String genericParamName = "param" + (i + 1); if (!this.names.containsValue(genericParamName)) { // 产生 param键(不与其他键发生冲突前提下) param.put(genericParamName, args[(Integer)entry.getKey()]); } } return param; } } else { return null; } }
public static Object wrapToMapIfCollection(Object object, String actualParamName) { // 用于封装单个参数 ParamMap map; if (object instanceof Collection) { map = new ParamMap(); map.put("collection", object); if (object instanceof List) { map.put("list", object); } Optional.ofNullable(actualParamName).ifPresent((name) -> { map.put(name, object); }); return map; } else if (object != null && object.getClass().isArray()) { map = new ParamMap(); map.put("array", object); Optional.ofNullable(actualParamName).ifPresent((name) -> { map.put(name, object); }); return map; } else { return object; } }
底层代码分析
单个参数封装:
底层代码分析
多个参数封装:
Pojo: 直接使用属性名字进行调用
Map集合: 键名与参数占位符一致
Collection / list : 使用foreach循环
collection: 集合名称, item: 遍历的每个集合元素名称, index: 该元素的下标
seperator: 元素之间的分隔符, open/clos: 语句起始结尾符号
数组下标: array[0] / array[1]
其他:直接使用就行,参数名字是无所谓的,可以任意取参数名
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。