一.MyBatis简介
1原理:
Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。
2.MyBatis的框架核心
1、 mybatis配置文件,包括Mybatis全局配置文件和Mybatis映射文件,其中全局配置文件配置了数据源、事务等信息;映射文件配置了SQL执行相关的信息。
2、 mybatis通过读取配置文件信息(全局配置文件和映射文件),构造出SqlSessionFactory,即会话工厂。
3、 通过SqlSessionFactory,可以创建SqlSession即会话。Mybatis是通过SqlSession来操作数据库的。
4、 SqlSession本身不能直接操作数据库,它是通过底层的Executor执行器接口来操作数据库的。Executor接口有两个实现类,一个是普通执行器,一个是缓存执行器(默认)。
5、 Executor执行器要处理的SQL信息是封装到一个底层对象MappedStatement中。该对象包括:SQL语句、输入参数映射信息、输出结果集映射信息。其中输入参数和输出结果的映射类型包括HashMap集合对象、POJO对象类型。
二.Mybatis入门
1.导包
mybatis-3.5.0/lib下所有包
mybatis-3.5.0.jar
mysql-connector-java-5.1.37-bin.jar
2.在classpath下创建log4j.properties
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=/home/miracle/Desktop/mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### set log levels - for more verbose logging change 'info' to 'debug' ###
log4j.rootLogger=debug, stdout
3.编写javaBean
User
package com.miracle.model;
import java.util.Date;
public class User {
private int id;
private String username;
private String sex;
private Date birthday;
private String address;
public User() {
}
public User(String username, String sex, Date birthday, String address) {
this.username = username;
this.sex = sex;
this.birthday = birthday;
this.address = 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 + '\'' +
'}';
}
}
4.创建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">
<configuration>
<!-- 加载classpath下的配置文件
不建议使用 配置数据源时候 用${key} 取值时,会和sql映射文件中的${key}冲突的bug
-->
<!--<properties resource="db.properties"></properties>-->
<settings>
<!-- 打印查询语句 -->
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
<!-- 配置mybatis的环境信息
environments标签里面可以包含多个environment标签,
每一个代表一套配置,通过environments中的default属性来指定
-->
<environments default="development">
<environment id="development">
<!-- 配置JDBC事务控制,由mybatis进行管理 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置数据源,采用dbcp连接池 -->
<dataSource type="POOLED">
<!-- 从properties文件中拿值,不建议使用 -->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis?useUnicode=true&characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- 告诉mybatis加载映射文件 -->
<mappers>
<mapper resource="com/miracle/orm/User.xml"></mapper>
<!--这里也可以设置包名,mybatis会自动加载指定包下的所有mapper文件-->
<!--<package name="com.miracle.mapper"></package>-->
</mappers>
</configuration>
5.编写映射文件User.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace一般以映射文件的全路径名来命名 -->
<mapper namespace="com.miracle.orm.User">
<!-- 根据id查询
[#{}]: 表示一个占位符?
-->
<select id="findUserById" parameterType="int" resultType="com.miracle.orm.User">
select * from user where id = #{id}
</select>
<!--
${} 表示拼接SQL字符串
${value} 表示要拼接的是简单类型参数
简单类型:int,byte,String...
1.如果参数为简单类型时,${}里面的参数名称必须是value
$符取值使用场景:比如分表,排序
select * from ${year}_salary where xxx;
select * from tbl_employee order by ${f_name} ${order}
-->
<select id="findUserByName" parameterType="String" resultType="com.miracle.orm.User">
select * from user where username like '%${value}%'
</select>
<!-- 插入数据
这里的站位是写javaBean的属性
-->
<insert id="insertUser" parameterType="com.miracle.orm.User">
<!--
selectKey标签:通过这个标签来返回插入数据的主键,
实际原理是执行插入语句后,又调用了一次查询,将查询的主键赋值到返回值中
keyProperty:指定javaBean中用来接收主键的字段
resultType:生成主键所对应的java类型
last_insert_id:mysql的函数,用于当插入一条数据后 执行此函数可以返回刚才插入记录的主键值
order:指定该查询主键SQL语句的执行顺序,相对于insert语句,由上面可知 这里写AFTER
-->
<selectKey keyProperty="id" resultType="int" order="AFTER">
select last_insert_id()
</selectKey>
insert into user (username, sex, birthday, address)
value
(#{username}, #{sex}, #{birthday}, #{address})
</insert>
<!-- 删除
-->
<delete id="deleteUser" parameterType="int">
delete from user where id = #{id}
</delete>
<!-- 更新
-->
<update id="updateUser" parameterType="com.miracle.orm.User">
update user set address = #{address}, sex = #{sex}
where id = #{id}
</update>
</mapper>
6.编写测试类
package com.miracle.test;
import com.miracle.orm.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.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
/**
* 普通方式
*/
public class Demo {
private SqlSession sqlSession;
/**
* 获取session
* @throws IOException
*/
@Before
public void init() throws IOException {
// 1.读取配置文件
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
// 2.通过SqlSessionFactoryBuilder创建SqlSessionFactory会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
sqlSession = sqlSessionFactory.openSession();
}
/**
* 提交事务
*/
@After
public void destory(){
sqlSession.commit();
sqlSession.close();
}
/**
* 查询
*/
@Test
public void test1(){
// 这里写xml映射文件的 namespace + id
User user = (User) sqlSession.selectOne("com.miracle.orm.User.findUserById", 10);
System.out.println(user);
List<User> userList = sqlSession.selectList("com.miracle.orm.User.findUserByName", "张");
System.out.println(userList);
}
/**
* 插入
*/
@Test
public void test2(){
User user = new User("gyf2", "1", new Date(), "广州");
// 返回受影响的行数
int affectRow = sqlSession.insert("com.miracle.orm.User.insertUser", user);
System.out.println(affectRow);
}
/**
* 删除
*/
@Test
public void test3(){
// 返回受影响的行数
int affectRow = sqlSession.delete("com.miracle.orm.User.deleteUser", 33);
System.out.println(affectRow);
}
/**
* 更新
*/
@Test
public void test4(){
User user = new User();
user.setId(27);
user.setSex("男");
user.setAddress("深圳");
// 返回受影响的行数
int affectRow = sqlSession.update("com.miracle.orm.User.updateUser", user);
System.out.println(affectRow);
}
/**
* 插入后获取插入数据的id,设置到JavaBean中
*/
@Test
public void test5(){
User user = new User("gyf3", "2", new Date(), "广州");
// 返回受影响的行数
int affectRow = sqlSession.insert("com.miracle.orm.User.insertUser", user);
System.out.println(affectRow);
// 返回插入数据的id
int id = user.getId();
System.out.println(id);
}
}
三.MyBatis编写Dao层【mapper代理方式实现】
1.概述
Mapper代理的开发方式,程序员只需要编写mapper接口(相当于dao接口)即可。Mybatis会自动的为mapper接口生成动态代理实现类。
不过要实现mapper代理的开发方式,需要遵循一些开发规范。
1. mapper接口的全限定名要和mapper映射文件的namespace的值相同。
2. mapper接口的方法名称要和mapper映射文件中的statement的id相同;
3. mapper接口的方法参数只能有一个,且类型要和mapper映射文件中statement的parameterType的值保持一致。
4. mapper接口的返回值类型要和mapper映射文件中statement的resultType值或resultMap中的type值保持一致;
2.demo
编写mapper接口:UserMapper
package com.miracle.mapper;
import com.miracle.model.User;
import com.miracle.vo.UserQueryVo;
import java.util.List;
import java.util.Map;
public interface UserMapper {
/*
有时候去数据库查询一条记录多个列,
这是没有对应业务的JavaBean对象,
可以把单条查询结果封装到map中,
以列名为key,列值为value
*/
public Map<String, Object> getEmpByIdReturnMap(Integer id);
/**
* @param user
* @return 受影响的行数
*/
// 使用mapper方式开发,那么接口方法的参数只能接收一个参数
public int save(User user);
public User findUserById(int id);
public List<User> findUserByUserQueryVo(UserQueryVo userQueryVo);
public List<User> findUserListByMap(Map<String, Object> map);
public int findUserCount(UserQueryVo userQueryVo);
public User findUserByIdResultMap(int id);
public List<User> findUserList(UserQueryVo userQueryVo);
public List<User> findUserByIds(UserQueryVo userQueryVo);
public List<User> findUserByIds2(List<Integer> ids);
/*
mybatis 增删改 在接口放回方法处
允许将返回值 void 改为:
Integer:表示影响行数
Long:表示影响行数
Boolean:影响行数超过一,返回true,否则false
*/
public Long addEmp(Employee employee);
public Long updateEmp(Employee employee);
public Boolean deleteEmpById(Integer id);
}
编写xml映射文件:UserMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace内容为mapper接口的全路径名 -->
<mapper namespace="com.miracle.mapper.UserMapper">
<select id="getEmpByIdReturnMap" resultType="map">
select * from tbl_employee where id != #{id}
</select>
<!-- id要和接口方法名一样 -->
<insert id="save" parameterType="com.miracle.model.User">
insert into user (username, sex, birthday, address)
value (#{username}, #{sex}, #{birthday}, #{address})
</insert>
<select id="findUserById" parameterType="int" resultType="com.miracle.model.User">
select * from user where id = #{id}
</select>
<!-- 通过包装类查数据 -->
<select id="findUserByUserQueryVo" parameterType="com.miracle.vo.UserQueryVo" resultType="com.miracle.model.User">
select u.*
from user u
where u.id <![CDATA[<>]]> #{user.id}
</select>
<!-- 通过Map查询数据 -->
<select id="findUserListByMap" parameterType="hashmap" resultType="com.miracle.model.User">
select u.* from user u where u.username like '%${user}%' and u.sex = #{sex}
</select>
<!-- 聚合函数查询用户个数 -->
<select id="findUserCount" parameterType="com.miracle.vo.UserQueryVo" resultType="int">
select count(*) from user where sex=#{user.sex}
</select>
<!-- 设置返回数据为resultMap类型的示例 -->
<resultMap id="userResultMap" type="com.miracle.model.User">
<id property="id" column="id_"></id>
<result property="username" column="username_"></result>
<result property="sex" column="sex_"></result>
<result property="birthday" column="birthday_"></result>
<result property="address" column="addresss_"></result>
</resultMap>
<select id="findUserByIdResultMap" parameterType="int" resultMap="userResultMap">
select id id_, username username_, sex sex_, birthday birthday_, address addresss_
from user
where id = #{id};
</select>
<!-- 声明一个SQL片段 -->
<sql id="select_user_where">
<if test="user != null">
<if test="user.sex != null and user.sex != ''">
sex = #{user.sex}
</if>
<if test="user.username != null and user.username != ''">
and username like '%${user.username}%'
</if>
</if>
</sql>
<!-- if和where标签 -->
<select id="findUserList" parameterType="com.miracle.vo.UserQueryVo" resultType="com.miracle.model.User">
select * from user
<!-- 条件判断 -->
<!-- Where标签:会去掉条件中的第一个and符号。 -->
<where>
<!-- 引用SQL片段 -->
<include refid="select_user_where"></include>
</where>
</select>
<!-- foreach标签使用 遍历JavaBean中的集合 -->
<select id="findUserByIds" parameterType="com.miracle.vo.UserQueryVo" resultType="com.miracle.model.User">
select * from user
<where>
<!-- 判断列表ids不为空 -->
<if test="ids != null and ids.size > 0">
<!--
collection:要遍历的属性
item:遍历出来属性的名字
open:拼接sql开始部分
separator:拼接sql中间部分
close:拼接sql结束部分
-->
<foreach collection="ids" item="id" open="id in (" close=")" separator=",">
#{id}
</foreach>
</if>
</where>
</select>
<!-- foreach标签使用 直接遍历 集合 -->
<select id="findUserByIds2" parameterType="list" resultType="com.miracle.model.User">
select * from user
<where>
<!-- 判断列表ids不为空,注意这里不能写ids 要写list -->
<if test="list != null and list.size > 0">
<!--
collection:要遍历的属性
item:遍历出来属性的名字
open:拼接sql开始部分
separator:拼接sql中间部分
close:拼接sql结束部分
-->
<foreach collection="list" item="id" open="id in (" close=")" separator=",">
#{id}
</foreach>
</if>
</where>
</select>
<insert id="addEmp" parameterType="com.mybatis.beans.Employee">
insert into tbl_employee(last_name, email, gender) values (
#{lastName},#{email},#{gender}
)
</insert>
<update id="updateEmp">
update tbl_employee
set last_name = #{lastName},
email = #{email},
gender = #{gender}
where id = #{id}
</update>
<delete id="deleteEmpById">
delete from tbl_employee where id = #{id}
</delete>
</mapper>
编写测试
package com.miracle.test;
import com.miracle.mapper.UserMapper;
import com.miracle.model.User;
import com.miracle.vo.UserQueryVo;
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.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
/**
* mapper代理方式,mapper就相当于dao,用mapper开发就不需要dao了,service层直接调用mapper
*/
@SuppressWarnings("all")
public class Demo {
private SqlSession sqlSession;
private UserMapper userMapper;
/**
* 获取session
* @throws IOException
*/
@Before
public void init() throws IOException {
// 1.读取配置文件
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
// 2.通过SqlSessionFactoryBuilder创建SqlSessionFactory会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
sqlSession = sqlSessionFactory.openSession();
// 获取mapper
userMapper = sqlSession.getMapper(UserMapper.class);
}
/**
* 提交事务
*/
@After
public void destory(){
sqlSession.commit();
sqlSession.close();
}
/**
* 查询
*/
@Test
public void test1(){
// 查询
User user = userMapper.findUserById(1);
System.out.println(user);
}
/**
* 保存
*/
@Test
public void test2(){
// 保存
User user = new User("王五", "x", new Date(), "xx");
userMapper.save(user);
}
/**
* 复杂类型查询
*/
@Test
public void test3(){
User user = new User();
user.setId(1);
UserQueryVo userQueryVo = new UserQueryVo();
userQueryVo.setUser(user);
List<User> userList = userMapper.findUserByUserQueryVo(userQueryVo);
System.out.println(userList);
}
/**
* map类型查询
*/
@Test
public void test4(){
Map<String, Object> map = new HashMap<>();
map.put("user", "张");
map.put("sex", 1);
List<User> userList = userMapper.findUserListByMap(map);
System.out.println(userList);
}
@Test
public void test5(){
UserQueryVo userQueryVo = new UserQueryVo();
User user = new User();
user.setSex("2");
userQueryVo.setUser(user);
int count = userMapper.findUserCount(userQueryVo);
System.out.println(count);
}
@Test
public void test6(){
User user = userMapper.findUserByIdResultMap(1);
System.out.println(user);
}
@Test
public void test7(){
User user = new User();
user.setUsername("张");
user.setSex("1");
UserQueryVo userQueryVo = new UserQueryVo();
userQueryVo.setUser(user);
List<User> userList = userMapper.findUserList(userQueryVo);
System.out.println(userList);
}
/**
* foreach 遍历JavaBean中的list
*/
@Test
public void test8(){
List<Integer> ids = new ArrayList<>();
ids.add(10);
ids.add(16);
ids.add(22);
ids.add(24);
UserQueryVo userQueryVo = new UserQueryVo();
userQueryVo.setIds(ids);
List<User> userList = userMapper.findUserByIds(userQueryVo);
System.out.println(userList);
}
/**
* foreach 遍历list
*/
@Test
public void test9(){
List<Integer> ids = new ArrayList<>();
ids.add(10);
ids.add(16);
ids.add(22);
ids.add(24);
List<User> userList = userMapper.findUserByIds2(ids);
System.out.println(userList);
}
}
四.mybatis全局配置文件介绍
- 注意mybatis全局配置文件标签书写是有顺序的
properties
settings
typeAliases
typeHandlers
objectFactory
objectWrapperFactory
plugins
environments?
databaseIdProvider
mappers
1.<environments>标签介绍
<configuration>
<!-- 配置mybatis的环境信息
environments标签里面可以包含多个environment标签,
每一个代表一套配置,通过environments中的default属性来指定,使用那一套环境
-->
<environments default="development">
<environment id="development">
<!-- 配置JDBC事务控制,由mybatis进行管理 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置数据源,采用dbcp连接池 -->
<dataSource type="POOLED">
<!-- 从properties文件中拿值,不建议使用 -->
<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>
</configuration>
2.<properties>标签介绍
mybatis可以使用properties来引入外部properties配置文件的内容
<configuration>
<!--
properties标签有两个属性:
1.resource:引入类路径下的资源
2.url:引入网络路径或者磁盘路径下的资源
-->
<properties resource="dbconfig.properties"></properties>
<!-- 配置mybatis的环境信息
environments标签里面可以包含多个environment标签,
每一个代表一套配置,通过environments中的default属性来指定
-->
<environments default="development">
<environment id="development">
<!-- 配置JDBC事务控制,由mybatis进行管理 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置数据源,采用dbcp连接池 -->
<dataSource type="POOLED">
<!-- 从properties文件中拿值,不建议使用 -->
<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>
</configuration>
3.<settings>标签介绍
<configuration>
<!--
settings包含很多重要的设置项
setting:用来设置每一个设置项
name:设置项名
value:设置项取值
-->
<settings>
<!-- 打印查询语句 -->
<setting name="logImpl" value="STDOUT_LOGGING" />
<!--
如果把javaBean对象的Null字段 插入到oracle中
oracle无法识别,这里可以配置如下内容(影响全局)
也可以在mapper映射文件中的sql里面,指定某个可能
为空字段的jdbcType=NULL
#{email,jdbcType=NULL}
-->
<setting name="jdbcTypeForNull" value="NULL"/>
<!--懒加载-->
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
</configuration>
4.<mappers>标签介绍
<configuration>
<!-- 告诉mybatis加载映射文件,将sql映射文件出册到全局配置中 -->
<mappers>
<!--注册classpath下的sql映射文件-->
<mapper resource="com/miracle/orm/User.xml"></mapper>
<!--这里也可以设置包名,mybatis会自动加载指定包下的所有mapper文件-->
<!--<package name="com.miracle.mapper"></package>-->
</mappers>
</configuration>
五.mybatisSQL映射文件编写
1.select标签 属性
2.mapper 映射文件中 #{} 和 ${} 区别
1.#{} 和 ${} 区别
#{}:相当于预处理中的占位符?。(底层是JDBC的preparedstatement)
#{}里面的参数表示接收java输入参数的名称。
#{}可以接受HashMap、POJO类型的参数。
当接受简单类型的参数时,#{}里面可以是value,也可以是其他。
#{}可以防止SQL注入。
使用场景:
尽量用#{}取值
${}:相当于拼接SQL串,对传入的值不做任何解释的原样输出。(底层是JDBC的statement)
${}会引起SQL注入,所以要谨慎使用。
${}可以接受HashMap、POJO类型的参数。
当接受简单类型的参数时,${}里面只能是value。
使用场景:
比如分表,排序... 按照年份分表拆分:
select * from ${year}_salary whrere xxx
select * from tbl_employee order by ${f_name} ${asc}
六.动态SQL
1.If标签
If标签:作为判断入参来使用的,如果符合条件,则把if标签体内的SQL拼接上。
注意:用if进行判断是否为空时,不仅要判断null,也要判断空字符串‘’;
eg:见下图
2.where标签
会去掉条件中的第一个and符号。
eg:见下图
3.choose 分支
<select id="getEmpsByConditionChoose" resultType="com.mybatis.beans.Employee">
select * from tbl_employee
<where>
<!-- 如果查询对象id有值就按照id查,
如果lastName有值就按照lastName查,
否则查询所有
类似java中的switch case
-->
<choose>
<when test="id != null and id != ''">
id = #{id}
</when>
<when test="lastName != null and lastName != ''">
last_name = #{lastName}
</when>
<otherwise>
1 = 1
</otherwise>
</choose>
</where>
</select>
4.set 封装修改条件
需求:
想根据JavaBean更新数据库记录,当JavaBean字段非空则更新响应字段,空则不更新
<update id="updateEmp">
update tbl_employee
set
<if test="lastName != null and lastName != ''">
last_name = #{lastName},
</if>
<if test="email != null and email != ''">
email = #{email},
</if>
<if test="gender != null and gender != ''">
gender = #{gender}
</if>
where id = #{id}
</update>
但是这个sql执行会有问题,if标签里面的sql后面有个逗号,无法处理,这是要用到set标签
<update id="updateEmp">
update tbl_employee
<set>
<if test="lastName != null and lastName != ''">
last_name = #{lastName},
</if>
<if test="email != null and email != ''">
email = #{email},
</if>
<if test="gender != null and gender != ''">
gender = #{gender}
</if>
</set>
where id = #{id}
</update>
5.foreach 遍历
<select id="getEmpsByConditionForeach" resultType="com.mybatis.beans.Employee">
select * from tbl_employee where id in
<!--
collection: 指定要遍历的集合(必须为list或者collection )
item:将遍历出的元素赋值给指定的变量
separator:表示每个元素之间的分隔符
open:遍历出所有结果拼接出一个开始的字符
close:遍历出所有结果拼接出一个结束的字符
index:索引,
如果遍历list的时候,index就是索引
如果遍历map的时候,index就是map的key
-->
<foreach collection="list" item="item_id" separator="," open="(" close=")">
#{item_id}
</foreach>
</select>
5.trim
<insert id="insertDepartment" parameterType="com.miracle.beans.Department">
insert into tbl_dept
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="deptId != null and deptId != ''">
dept_id,
</if>
<if test="deptName != null and deptName != ''">
dept_name,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="deptId != null and deptId != ''">
#{deptId,jdbcType=INTEGER},
</if>
<if test="deptName != null and deptName != ''">
#{deptName,jdbcType=VARCHAR},
</if>
</trim>
</insert>
五.SQL片断
Mybatis提供了SQL片段的功能,可以提高SQL的可重用性。
六.总结
2.selectOne和selectList
selectOne:只能查询0或1条记录,大于1条记录的话,会报错:
selectList:可以查询0或N条记录
3.mybatis特殊字符处理
使用<![CDATA[ ]]>符号进行说明,在最里层的[ ]里面内容不进行解析
4.输出映射 resultType/resultMap
(1)resultType
使用resultType进行结果映射时,查询的列名和映射的pojo属性名完全一致,该列才能映射成功。
如果查询的列名和映射的pojo属性名全部不一致,则不会创建pojo对象;
如果查询的列名和映射的pojo属性名有一个一致,就会创建pojo对象。
输出单个pojo对象和pojo列表时,mapper映射文件中的resultType的类型是一样的,mapper接口的方法返回值不同。同样的mapper映射文件,返回单个对象和对象列表时,mapper接口在生成动态代理的时候,会根据返回值的类型,决定调用selectOne方法还是selectList方法。
(2)resultMap(当mybatis返回JavaBean嵌套JavaBean时,向内层JavaBean里面设置值可以用resultMap)
如果查询出来的列名和属性名不一致,通过定义一个resultMap将列名和pojo属性名之间作一个映射关系。
1、 定义resultMap
2、使用resultMap作为statement的输出映射类型
(3)总结
resultType:将查询结果按照sql列名pojo属性名一致性映射到pojo中。
resultMap:使用association和collection完成一对一和一对多高级映射(对结果有特殊的映射要求)。
association:将关联查询信息映射到一个pojo对象中。
collection:将关联查询信息映射到一个list集合中。
5.mybatis标签大全
https://blog.csdn.net/weixin_40950778/article/details/78655288