MyBatis框架的简单使用

一、MyBatis框架的简介

在这里插入图片描述
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

中文官网:https://mybatis.org/mybatis-3/zh/index.html

MyBatis的特点:

  • 属于持久层的ORM框架
    • 持久层:将内存中的对象数据储存到数据库持久保存
    • ORM:Object Relational Mapping 通过使用描述对象和数据库之间映射的元数据,将面向对象语言程序中的对象自动持久化到关系数据库中。本质上就是将数据从一种形式转换到另外一种形式。
  • 半自动化
    • 需要手动设计表
    • 提供sql语句
    • 依赖于数据库平台

MyBatis的优缺点:

  • 优点:
    • 简单易学
    • 灵活
    • 解除sql语句与程序代码的耦合
    • 提供映射标签,支持对象与数据库的ORM关系映射
    • 提供对象关系映射标签,支持对象关系组件维护
    • 系统XML标签,支持编写动态SQL
  • 缺点:
    • 编写SQL语句时工作量大。
    • SQL语句依赖于数据库,导致数据库移植性差,不能更换数据库

二、环境搭建

使用MyBatis,需要使用到MyBatis的jar包,将jar包添加到项目中即可。

Jar包地址:https://github.com/mybatis/mybatis-3/releases

1、创建文件

创建一个新的Java项目,在项目的src文件夹下创建一个名叫mybatis的xml文件,用来配置MyBatis的全局配置文件。

创建一个mappers包,在包内创建一个mapper.xml文件,用来配置要使用的SQL命令和对应结果集的实体类。

创建一个pojo包,在包内创建SQL结果集的对应的实体类(实体类的属性类型和名字要和数据库中的字段名字和类型一致)。

2、配置MyBatis的核心配置文件




  
  
  
<configuration>
		
	<environments default="dev">
		
		<environment id="dev">
			
			<transactionManager type="JDBC">transactionManager>
			
			<dataSource type="pooled">
				
				<property name="driver" value="oracle.jdbc.driver.OracleDriver"/>
				
				<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
				
				<property name="username" value="SCOTT"/>
				
				<property name="password" value="TIGER"/>
			dataSource>
		environment>
	environments>
	
	
	<mappers>
		
		<mapper resource="cn/yanghuisen/mappers/UserMapper.xml"/>
	mappers>
configuration>
  • configuration:核心配置文件的根元素,所有其它的元素都要在这个元素里面
  • environments:用于管理所有环境,可以default指定默认使用哪个环境
  • environment:配置环境,id用来唯一标识环境
  • transactionManager:用户配置事务管理器,type用来指定事务管理方式
    • JDBC:表示采用和原生JDBC一致的事务管理方式
  • dataSource:用于配置数据库连接信息,type用来指定是否使用连接池技术,pooled表示使用连接池技术
    • driver:数据库驱动
    • url:数据库链接地址
    • username:用户实列|用户账号
    • password:用户密码
  • mappers:配置SQL扫描映射文件(可以配置多个SQL扫描映射文件)
    • mapper:SQL映射文件的路径,resource指定路径

3、配置SQL映射文件



 
 
<mapper namespace="cn.yanghuisen.mappers.UserMapper">
	
	<select id="queryAll" resultType="cn.yanghuisen.pojo.User">
		
		select * from u_user
	select>
mapper>
  • mapper:SQL映射配置文件的根元素,namespace指定该文件的命名空间,全局唯一
    • select:查询标签
    • resultType:要返回的数据类型

select也可改变为:insert、update、delete…

4、创建实体类

实体类的属性名和类型要和数据库中的字段名和类型一致

package cn.yanghuisen.pojo;

import java.util.Date;

public class User {
	private Integer u_id;
	private String u_name;
	private String u_pwd;
	private Date u_date;
	public User() {
		super();
	}
	
	
	
	public User(String u_name, String u_pwd) {
		super();
		this.u_name = u_name;
		this.u_pwd = u_pwd;
	}



	public User(Integer u_id, String u_name, String u_pwd) {
		super();
		this.u_id = u_id;
		this.u_name = u_name;
		this.u_pwd = u_pwd;
	}



	public User(String u_name, String u_pwd, Date u_date) {
		super();
		this.u_name = u_name;
		this.u_pwd = u_pwd;
		this.u_date = u_date;
	}



	public User(Integer u_id, String u_name, String u_pwd, Date u_date) {
		super();
		this.u_id = u_id;
		this.u_name = u_name;
		this.u_pwd = u_pwd;
		this.u_date = u_date;
	}
	@Override
	public String toString() {
		return "User [u_id=" + u_id + ", u_name=" + u_name + ", u_pwd=" + u_pwd + ", u_date=" + u_date + "]";
	}
}

环境到此配置完成,后续只需要编写Java代码就行。

三、配置文件优化

上面的配置文件中有的地方是可以优化配置的。

1、properties标签

可以使用properties标签加载外部properties文件,解决硬编码问题

db.properties

driver=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:xe
name=SCOTT
pwd=TIGER


  
<configuration>
	
	<properties resource="db.properties"/>
	<environments default="dev">
		<environment id="dev">
			<transactionManager type="JDBC"/>
			<dataSource type="POOLED">
											
				<property name="driver" value="${driver}"/>
				<property name="url" value="${url}"/>
				<property name="username" value="${name}"/>
				<property name="password" value="${pwd}"/>
			dataSource>
		environment>
	environments>
	
	<mappers>
		<mapper resource="cn/yanghuisen/mappers/UserMapper.xml"/>
	mappers>

configuration>

2、typeAliases标签

可以使用typeAliases标签对SQL映射文件的返回数据类型设置别名,typeAliases有三种使用方式

1、指定别名

核心配置文件



  
<configuration>
	
	<properties resource="db.properties"/>
	
	
	<typeAliases>
			
		<typeAlias type="cn.yanghuisen.pojo.User" alias="u"/>
	typeAliases>
	<environments default="dev">
		<environment id="dev">
			<transactionManager type="JDBC"/>
			<dataSource type="POOLED">
											
				<property name="driver" value="${driver}"/>
				<property name="url" value="${url}"/>
				<property name="username" value="${name}"/>
				<property name="password" value="${pwd}"/>
			dataSource>
		environment>
	environments>
	
	<mappers>
		<mapper resource="cn/yanghuisen/mappers/UserMapper.xml"/>
	mappers>

configuration>

SQL映射文件

<select id="queryAll" resultType="u">
    select * from u_user
select>

2、省略alias属性

可以省略alias属性,系统默认设置类名为别名,并且不区分大小写

核心配置文件


<typeAliases>
    
    <typeAlias type="cn.yanghuisen.pojo.User"/>
typeAliases>

SQL映射文件

<select id="queryAll" resultType="user">
    select * from u_user
select>

3、对整个包下面的类设置别名

就算是第二种省略alias属性,一旦类多了想要配置也很麻烦,所以可以对一个包下面的所有类设置别名

<typeAliases>
    
    <package name="cn.yanghuisen.pojo"/>
typeAliases>

cn.yanghuisen.pojo这个包下面的所有属性设置别名

还有一些是内建别名,在MyBatis中文官网有详细介绍:https://mybatis.org/mybatis-3/zh/configuration.html#typeAliases

下面是一些为常见的 Java 类型内建的类型别名。它们都是不区分大小写的,注意,为了应对原始类型的命名重复,采取了特殊的命名风格。

别名 映射的类型
_byte byte
_long long
_short short
_int int
_integer int
_double double
_float float
_boolean boolean
string String
byte Byte
long Long
short Short
int Integer
integer Integer
double Double
float Float
boolean Boolean
date Date
decimal BigDecimal
bigdecimal BigDecimal
object Object
map Map
hashmap HashMap
list List
arraylist ArrayList
collection Collection
iterator Iterator

3、sql标签

sql标签可以对sql语句进行优化封装,比如某几个字段使用频率非常高,就可以使用sql标签进行封装,后续使用只需要调用就行。

<mapper namespace="cn.yanghuisen.mappers.UserMapper">
	<sql id="user_all_field">
		u_id,u_name,u_pwd,u_date
	</sql>

	<!-- 查找全部数据 -->
	<select id="queryAll" resultType="user">
		select <include refid="user_all_field"/> from u_user
	</select>
</mapper>

可以封装指定字段,也可以封装一条完整语句,需要时使用include调用就行

三、查询

查询,增删改查中最长用的一个

1、查询全部数据

package cn.yanghuisen.test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

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.jupiter.api.Test;

import cn.yanghuisen.pojo.User;
import cn.yanghuisen.utils.MyBatisUtil;

public class Test1 {
	
	// 查找数据-查找全部数据
	@Test
	public void test1() {
		InputStream is = null;
		SqlSession session = null;
		try {
			// 载入mybatis配置文件,返回一个InputStream流
			is = Resources.getResourceAsStream("mybatis-config.xml");
			// 构建SqlSessionFactory工厂
			SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
			// 构建SqlSession对象
			session = MyBatisUtil.getSqlSession();
			// 执行SQL语句
			List<User> list = session.selectList("cn.yanghuisen.mappers.UserMapper.queryAll");
			list.forEach(System.out::println);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			session.close();
		}
	}
}

运行结果
User [u_id=1, u_name=zhangsan, u_pwd=123456, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=2, u_name=lisi, u_pwd=123123, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=3, u_name=wanger, u_pwd=112233, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=4, u_name=mazi, u_pwd=1314520, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=5, u_name=wangwu, u_pwd=666666, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=6, u_name=zhaoliu, u_pwd=88888888, u_date=Sun Mar 15 18:41:45 CST 2020]
  • selectList:查询了表中的全部数据,返回的是一个List集合。

  • cn.yanghuisen.mappers.UserMapper.queryAll:是sql映射文件的namespace属性值+sql语句的ID

载入配置文件,构建工厂,构建对象每次都要使用,所以也可以再次封装,制作一个工具类。

MyBatisUtil工具

package cn.yanghuisen.utils;

import java.io.IOException;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class MyBatisUtil {
	private static SqlSessionFactory factory;
	
	static {
		try {
			factory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("mybatis-config.xml"));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static SqlSession getSqlSession() {
		SqlSession session = null;
		if(factory!=null) {
			session = factory.openSession();
		}
		return session;
	}
}

封装工具后的掉用

@Test
public void test0() {
    SqlSession session = MyBatisUtil.getSqlSession();
    Map<String, User> map = session.selectMap("cn.yanghuisen.mappers.UserMapper.queryAll","u_name");
    Set<Entry<String, User>> set = map.entrySet();
    set.forEach(System.out::println);
    session.close();
}
  • selectMap:返回一个Map集合
    • 第一个参数为Sql映射文件
    • 第二个参数为返回的map的key。用数据库中的u_name字段的值设置为key
运行结果
mazi=User [u_id=4, u_name=mazi, u_pwd=1314520, u_date=Sun Mar 15 18:41:45 CST 2020]
lisi=User [u_id=2, u_name=lisi, u_pwd=123123, u_date=Sun Mar 15 18:41:45 CST 2020]
zhaoliu=User [u_id=6, u_name=zhaoliu, u_pwd=88888888, u_date=Sun Mar 15 18:41:45 CST 2020]
zhangsan=User [u_id=1, u_name=zhangsan, u_pwd=123456, u_date=Sun Mar 15 18:41:45 CST 2020]
wangwu=User [u_id=5, u_name=wangwu, u_pwd=666666, u_date=Sun Mar 15 18:41:45 CST 2020]
wanger=User [u_id=3, u_name=wanger, u_pwd=112233, u_date=Sun Mar 15 18:41:45 CST 2020]

2、查询指定条件数据

查询指定条件数据就需要指定筛选条件,所以还涉及一个传参的问题。

2.1、传参-基本数据类型-一个参数

查询之前要先创建相应的SQL语句


<select id="queryByID" resultType="user" parameterType="int">
    select <include refid="user_all_field"/> from u_user where u_id = #{id}
select>
  • parameterType:传入参数类型,这里使用的是int类型
  • #{id}:获取传入的参数,如果只有一个参数的话,id可以随便写

java程序

// 查找数据-一个参数的查询
// 根据指定ID查找数据
// 传入一个基本数据类型参数
@Test
public void test2() {
    SqlSession session = MyBatisUtil.getSqlSession();
    // 2:要传入的参数
    User user = session.selectOne("cn.yanghuisen.mappers.UserMapper.queryByID",2);
    System.out.println(user);
    session.close();
}
运行结果
User [u_id=2, u_name=lisi, u_pwd=123123, u_date=Sun Mar 15 18:41:45 CST 2020]
  • selectOne:查询一条数据

2.2、传参-String类型-一个参数

参数不一样,sql语句也要相应的改变


<select id="queryByName" resultType="user" parameterType="string">
    select <include refid="user_all_field"/> from u_user where u_name = #{str}
select>

java程序

// 查找数据-一个参数的查询
// 根据指定name查找数据
// 传入一个String型参数
@Test
public void test3() {
    SqlSession session = MyBatisUtil.getSqlSession();
    // wanger:要传入的参数
    User user = session.selectOne("cn.yanghuisen.mappers.UserMapper.queryByName","wanger");
    System.out.println(user);
    session.close();
}
运行结果
User [u_id=3, u_name=wanger, u_pwd=112233, u_date=Sun Mar 15 18:41:45 CST 2020]

2.3、传参-数组|List集合-多个参数

MyBatis的查询方法中,不能填写多个参数,所以如果要传入多个参数就要使用别的办法。例如数组或者List集合

同样,参数不一样,SQL语配置要改变


<select id="queryByArray" resultType="user">
    select <include refid="user_all_field"/> from u_user where u_id in(
    <foreach collection="array"  item="arr" separator=",">#{arr}foreach>
    )
select>
  • foreach:遍历数组或者List集合
  • collection:传入的数据类型,数组就是array,list集合就是list
  • item:临时储存数组或List集合中的一个数据,就和java中的foreach一样
  • separator:指定分隔符
  • 如果是传入的是数组或者List集合,不用定义parameterType属性
// 查找数据-多个参数的查询
// 根据多个id查找数据数据
// 传入一个数组或者List集合
@Test
public void test4() {
    SqlSession session = MyBatisUtil.getSqlSession();
    int[] arr = {2,3};
    List<User> list = session.selectList("cn.yanghuisen.mappers.UserMapper.queryByArray",arr);
    list.forEach(System.out::println);
    session.close();
}
运行结果
User [u_id=2, u_name=lisi, u_pwd=123123, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=3, u_name=wanger, u_pwd=112233, u_date=Sun Mar 15 18:41:45 CST 2020]

2.4、传参-javaBean对象-多个参数

也可以使用JavaBean传参,但是并不是在所有的情况下都可以使用,例如如果要根据ID查找多条记录,就需要传入多个ID值,但是JavaBean中只能有一个ID。


<select id="queryByNamePwd" resultType="user" parameterType="user">
    select <include refid="user_all_field"/> from u_user where u_name = #{u_name} and u_pwd = #{u_pwd}
select>
  • parameterType:设置传入数据的类型,可以和resultType一样使用别名
  • #{u_name}:传入的user类型数据的属性名
  • #{u_pwd}:传入的user类型数据的属性名

java程序

// 查找数据-多个参数的查询
// 根据多个name和pwd查找数据数据
// 传入一个JavaBean对象
@Test
public void test5() {
    SqlSession session = MyBatisUtil.getSqlSession();
    User user = new User("zhangsan","123456");
    user = session.selectOne("cn.yanghuisen.mappers.UserMapper.queryByNamePwd",user);
    System.out.println(user);
    session.close();
}

2.5、传参-Map集合-多个参数

也可以使用Map集合传递参数,key为参数名字,value为参数值


<select id="queryByMapNamePwd" resultType="user" parameterType="map">
    select <include refid="user_all_field"/> from u_user where u_name = #{name} and u_pwd = #{pwd}
select>
  • parameterType:设置传入参数类型为map
  • #{name}:对应的key的键
  • #{pwd}:对应的key的键

java程序

// 查找数据-多个参数的查询
// 根据多个name和pwd查找数据数据
// 传入一个Map集合
@Test
public void test6() {
    SqlSession session = MyBatisUtil.getSqlSession();
    Map<String, Object> map = new HashMap<String, Object> ();
    map.put("name", "wanger");
    map.put("pwd", "112233");
    User user = session.selectOne("cn.yanghuisen.mappers.UserMapper.queryByMapNamePwd",map);
    System.out.println(user);
    session.close();
}
运行结果
User [u_id=3, u_name=wanger, u_pwd=112233, u_date=Sun Mar 15 18:41:45 CST 2020]

3、查询数据的结果类型

传入参数有多种方式,结果的类型也有多种

3.1、Date类型

返回Date类型时间


<select id="queryAllByDate" resultType="date">
    select u_date from u_user
select>
  • resultType:返回date类型数据

java程序:

// 查找数据
// 获取多条数据的时间,返回Date类型时间
@Test
public void test7() {
    SqlSession session = MyBatisUtil.getSqlSession();
    List<Date> list = session.selectList("cn.yanghuisen.mappers.UserMapper.queryAllByDate");
    list.forEach(System.out::println);
    session.close();
}
运行结果
Sun Mar 15 18:41:45 CST 2020
Sun Mar 15 18:41:45 CST 2020
Sun Mar 15 18:41:45 CST 2020
Sun Mar 15 18:41:45 CST 2020
Sun Mar 15 18:41:45 CST 2020
Sun Mar 15 18:41:45 CST 2020

3.2、List集合

返回List集合


<select id="queryAll" resultType="user">
    select <include refid="user_all_field"/> from u_user
select>
  • resultType:因为List集合需要指定泛型,所有List集合中装的是User类型的,所以为User

java程序

// 查找数据
// 获取多条数据,返回List类型
@Test
public void test8() {
    SqlSession session = MyBatisUtil.getSqlSession();
    List<User> list = session.selectList("cn.yanghuisen.mappers.UserMapper.queryAll");
    list.forEach(System.out::println);
    session.close();
}
运行结果
User [u_id=1, u_name=zhangsan, u_pwd=123456, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=2, u_name=lisi, u_pwd=123123, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=3, u_name=wanger, u_pwd=112233, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=4, u_name=mazi, u_pwd=1314520, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=5, u_name=wangwu, u_pwd=666666, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=6, u_name=zhaoliu, u_pwd=88888888, u_date=Sun Mar 15 18:41:45 CST 2020]

3.3、Map集合

返回Map集合,字段为Key,值为Value


<select id="queryMapById" resultType="map" parameterType="int">
    select <include refid="user_all_field"/> from u_user where u_id = #{id}
select>

java程序

// 查找数据
// 获取ID为4的数据
// 返回Map集合
@Test
public void test9() {
    SqlSession session = MyBatisUtil.getSqlSession();
    Map<String, Object> map = session.selectOne("cn.yanghuisen.mappers.UserMapper.queryMapById",4);
    System.out.println(map);
    session.close();
}
运行结果
{U_PWD=1314520, U_ID=4, U_NAME=mazi, U_DATE=2020-03-15 18:41:45.0}

返回Map有一个弊端,那就是只能返回一条数据。如果想要返回多个Map可以使用List-Map。

3.4、List-Map

Map只能返回一条数据,所以可以使用List-Map达到返回多条Map的xiaog。就是List集合中装Map。


<select id="queryALLToListMap" resultType="map">
    select <include refid="user_all_field"/> from u_user
select>
  • resultType:因为是list中装map所以最底下还是map

java程序

// 查找数据
// 获所有数据
// 返回List-Map集合
@Test
public void test10() {
    SqlSession session = MyBatisUtil.getSqlSession();
    List<Map<String, Object>> list = session.selectList("cn.yanghuisen.mappers.UserMapper.queryALLToListMap");
    list.forEach(System.out::println);
    session.close();
}
运行结果
{U_PWD=123456, U_ID=1, U_NAME=zhangsan, U_DATE=2020-03-15 18:41:45.0}
{U_PWD=123123, U_ID=2, U_NAME=lisi, U_DATE=2020-03-15 18:41:45.0}
{U_PWD=112233, U_ID=3, U_NAME=wanger, U_DATE=2020-03-15 18:41:45.0}
{U_PWD=1314520, U_ID=4, U_NAME=mazi, U_DATE=2020-03-15 18:41:45.0}
{U_PWD=666666, U_ID=5, U_NAME=wangwu, U_DATE=2020-03-15 18:41:45.0}
{U_PWD=88888888, U_ID=6, U_NAME=zhaoliu, U_DATE=2020-03-15 18:41:45.0}

四、插入、修改、删除

1、插入

插入数据传递参数的方法和查询数据时传递参数的方法一致


<insert id="addUser" parameterType="user">
    insert into u_user values(sq_u_user.nextval,#{u_name},#{u_pwd},#{u_date})
insert>

java程序

// 插入数据
@Test
public void test11() {
    SqlSession session = MyBatisUtil.getSqlSession();
    User user = new User("ahh","123123",new Date());
    int len = session.insert("cn.yanghuisen.mappers.UserMapper.addUser",user);
    if(len>0) {
        System.out.println("数据添加成功");
        // 手动事务提交
        session.commit();
    }else {
        System.out.println("数据添加失败");
        // 事务回滚
        session.rollback();
    }
    session.close();
}
运行结果
数据添加成功

在MyBatis中默认是手动事务提交,如果要设置为自动需要在工具类中修改一个数据。

public static SqlSession getSqlSession() {
    SqlSession session = null;
    if(factory!=null) {
        // true:自动提交事务,默认手动
        session = factory.openSession(true);
    }
    return session;
}

自动提交事务

// 插入数据
@Test
public void test11() {
    SqlSession session = MyBatisUtil.getSqlSession();
    User user = new User("abcd","123123",new Date());
    int len = session.insert("cn.yanghuisen.mappers.UserMapper.addUser",user);
    System.out.println(len>0?"添加成功":"添加失败");
    session.close();
}

2、修改

修改数据的参数传递和查询数据的参数传递一样


<update id="updateUserPwd" parameterType="map">
    update u_user set u_pwd = #{pwd} where u_id = #{id}
update>

java程序

// 修改数据
@Test
public void test12() {
    SqlSession session = MyBatisUtil.getSqlSession();
    Map<String, Object> map = new HashMap<String, Object>();
    map.put("pwd", "778899");
    map.put("id", 8);
    int len = session.update("cn.yanghuisen.mappers.UserMapper.updateUserPwd",map);
    System.out.println(len>0?"修改成功":"修改失败");
    session.close();
}
运行结果
修改成功

3、删除

同样删除数据的参数传递和查询一样


<delete id="deleteUser" parameterType="int">
    delete from u_user where u_id = #{id}
delete>

java程序

// 删除数据
@Test
public void test13() {
    SqlSession session = MyBatisUtil.getSqlSession();
    int len = session.update("cn.yanghuisen.mappers.UserMapper.deleteUser",8);
    System.out.println(len>0?"删除成功":"删除失败");
    session.close();
}
运行结果
删除成功

五、接口绑定方案

上面的方式还是不够简单,所以MyBatis又提供了一条接口绑定方案,程序员可以提供一个接口,然后提供一个接口所对应的Mapper.xml文件。MyBatis会自动将接口与XML文件进行绑定。实际上就是MyBatis根据接口和对应的XML文件创建一个接口的实现类,得到一个接口的子类对象,后续只需要调用方法就行。

1、定义接口

package cn.yanghuisen.mappers;

import java.util.List;

import cn.yanghuisen.pojo.User;

public interface UserMapper {
	// 查询所有数据
	public List<User> queryAll();
}

2、修改全局配置文件

全局配置文件的SQL映射也需要修改

<mappers>
    
    <mapper class="cn.yanghuisen.mappers.UserMapper"/>
mappers>

接口如果很少还好,如果有很多接口,一个个配置也太麻烦了,所有还可以进行简化配置

<mappers>
    
    <package name="cn.yanghuisen.mappers"/>

mappers>

3、配置SQL映射文件

要求:

  • 接口和XML文件要在一个包内
  • XML文件要和接口文件名一致
  • namespace属性值必须是接口的包名+类名
  • XML文件的ID必须接口中的抽象方法的名字一致
  • XML文件的返回值和参数类型必须和抽象方法的返回值和参数类型一致

XML配置和原先没有多大区别




<mapper namespace="cn.yanghuisen.mappers.UserMapper">
	<sql id="user_all_field">
		u_id,u_name,u_pwd,u_date
	sql>

	
	<select id="queryAll" resultType="user">
		select <include refid="user_all_field"/> from u_user
	select>	
mapper>

4、使用-查询全部数据-无参数

查找全部数据

// 查找全部数据
@Test
public void test1() {
    SqlSession session = MyBatisUtil.getSqlSession();
    // 获取接口的实现类
    UserMapper um = session.getMapper(UserMapper.class);
    // 多态调用方法
    List<User> list = um.queryAll();
    list.forEach(System.out::println);
}
运行结果
User [u_id=1, u_name=zhangsan, u_pwd=123456, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=2, u_name=lisi, u_pwd=123123, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=3, u_name=wanger, u_pwd=112233, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=4, u_name=mazi, u_pwd=1314520, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=5, u_name=wangwu, u_pwd=666666, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=6, u_name=zhaoliu, u_pwd=88888888, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=7, u_name=ahh, u_pwd=123123, u_date=Sun Mar 15 22:09:03 CST 2020]

5、使用-查找指定数据-多个参数

查找根据name和密码查找数据

配置XML文件


<select id="queryByNamePwd" resultType="user">
    select <include refid="user_all_field"/> from u_user where u_name = #{param1} and u_pwd =#{param2} 
select>
  • 传入参数不需要声明类型,只需要定义返回类型

接口中抽象方法

// 根据name和pwd查找数据
public User queryByNamePwd(String name,String pwd);
  • param1+:默认为死格式,第一个参数就是param1,第二个参数就是param2…
  • 如果要修改需要在抽象方法中定义
public User queryByNamePwd(@Param("name")String name,@Param("pwd")String pwd);

<select id="queryByNamePwd" resultType="user">
    select <include refid="user_all_field"/> from u_user where u_name = #{name} and u_pwd =#{pwd} 
select>

java程序

// 根据Name和Pwd查找数据
@Test
public void test2() {
    SqlSession session = MyBatisUtil.getSqlSession();
    UserMapper um = session.getMapper(UserMapper.class);
    User user = um.queryByNamePwd("zhangsan", "123456");
    System.out.println(user);
}
运行结果
User [u_id=1, u_name=zhangsan, u_pwd=123456, u_date=Sun Mar 15 18:41:45 CST 2020]

6、使用-插入数据-多个参数


<insert id="addUser">
    insert into u_user values(sq_u_user.nextval,#{param1},#{param2},#{param3})
insrt>
// 插入数据
public int addUser(String name,String pwd,Date date);
// 插入数据
@Test
public void test3() {
    SqlSession session = MyBatisUtil.getSqlSession();
    UserMapper um = session.getMapper(UserMapper.class);
    int len = um.addUser("wanggoudan", "123123", new Date());
    System.out.println(len>0?"插入成功":"插入失败");
}
运行结果
插入成功

7、使用-修改数据-多个参数

根据ID修改pwd


<update id="updatePwdById">
    update u_user set u_pwd = #{param1} where u_id = #{param2}
update>
// 根据id修改pwd
public int updatePwdById(String pwd,int id);
// 根据id修改pwd
@Test
public void test4() {
    SqlSession session = MyBatisUtil.getSqlSession();
    UserMapper um = session.getMapper(UserMapper.class);
    int len = um.updatePwdById("123456", 4);
    System.out.println(len>0?"修改成功":"修改失败");
}
运行结果
修改成功

8、使用-删除数据-一个参数

根据ID删除数据


<delete id="deleteById">
    delete from u_user where u_id = #{param1}
delete>
// 根据id删除数据
public int deleteById(int id);
// 根据id删除数据
@Test
public void test5() {
    SqlSession session = MyBatisUtil.getSqlSession();
    UserMapper um = session.getMapper(UserMapper.class);
    int len = um.deleteById(9);
    System.out.println(len>0?"删除成功":"删除失败");
}
运行结果
删除成功

六、动态SQL

动态SQL就是根据不同的条件,SQL语句可以随之变化。可以实现一条SQL查询多种结果。

1、if标签

可以对传入的参数进行判断


<select id="queryUserByIDNamePwd" resultType="user">
    select * from u_user where 1=1
    <if test="id!=null">
        and u_id = #{id}
    if>
    <if test="name!=null and name!=''">
        and u_name = #{name}
    if>
    <if test="pwd!=null and pwd!=''">
        and u_pwd = #{pwd}
    if>
select>
  • test:判断条件
  • 1=1:为了所有的if都不成立,出现select * from u_user where

java程序:根据ID查找数据

List<User> list = mapper.queryUserByIDNamePwd(2, null, null);
运行结果
User [u_id=2, u_name=lisi, u_pwd=123123, u_date=Sun Mar 15 18:41:45 CST 2020]

java程序:根据Name查找数据

List<User> list = mapper.queryUserByIDNamePwd(null, "kl", null);
运行结果
User [u_id=55, u_name=kl, u_pwd=221133, u_date=Mon Mar 16 19:09:11 CST 2020]

java程序:根据Pwd查找数据

List<User> list = mapper.queryUserByIDNamePwd(null, null, "123456");
运行结果
User [u_id=1, u_name=zhangsan, u_pwd=123456, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=30, u_name=wahaah, u_pwd=123456, u_date=Mon Mar 16 11:41:07 CST 2020]
User [u_id=60, u_name=shaungwaiwai, u_pwd=123456, u_date=Mon Mar 16 11:41:07 CST 2020]
User [u_id=80, u_name=baisushan, u_pwd=123456, u_date=Mon Mar 16 11:41:07 CST 2020]
User [u_id=56, u_name=sanjianke, u_pwd=123456, u_date=Mon Mar 16 22:03:03 CST 2020]

java程序:查找全部数据

List<User> list = mapper.queryUserByIDNamePwd(null, null, null);
运行结果
User [u_id=1, u_name=zhangsan, u_pwd=123456, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=2, u_name=lisi, u_pwd=123123, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=3, u_name=wanger, u_pwd=112233, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=4, u_name=mazi, u_pwd=123456789, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=5, u_name=wangwu, u_pwd=666666, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=6, u_name=zhaoliu, u_pwd=88888888, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=20, u_name=#{item.u_name), u_pwd=#{item.u_pwd}, u_date=Mon Mar 16 10:49:46 CST 2020]
User [u_id=7, u_name=ahh, u_pwd=123123, u_date=Sun Mar 15 22:09:03 CST 2020]
User [u_id=30, u_name=wahaah, u_pwd=123456, u_date=Mon Mar 16 11:41:07 CST 2020]
User [u_id=60, u_name=shaungwaiwai, u_pwd=123456, u_date=Mon Mar 16 11:41:07 CST 2020]
User [u_id=80, u_name=baisushan, u_pwd=123456, u_date=Mon Mar 16 11:41:07 CST 2020]
User [u_id=54, u_name=whh, u_pwd=11223344, u_date=Mon Mar 16 19:09:11 CST 2020]
User [u_id=55, u_name=kl, u_pwd=221133, u_date=Mon Mar 16 19:09:11 CST 2020]
User [u_id=56, u_name=sanjianke, u_pwd=123456, u_date=Mon Mar 16 22:03:03 CST 2020]

2、where标签

where就是为了解决上面的1=1问题




<select id="queryUserByIDNamePwd1" resultType="User">
    select * from u_user
    <where>
        <if test="id!=null">
            and u_id = #{id}
        if>
        <if test="name!=null and name!=''">
            and u_name = #{name}
        if>
        <if test="pwd!=null and pwd!=''">
            and u_pwd = #{pwd}
        if>
    where>
select>
  • 如果没有满足条件则不会添加where关键字,否则相反
  • 如果第一个满足条件的语句中有and,则自动去除

java程序:

List<User> list = mapper.queryUserByIDNamePwd1(null, null, "123456");
运行结果
User [u_id=1, u_name=zhangsan, u_pwd=123456, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=30, u_name=wahaah, u_pwd=123456, u_date=Mon Mar 16 11:41:07 CST 2020]
User [u_id=60, u_name=shaungwaiwai, u_pwd=123456, u_date=Mon Mar 16 11:41:07 CST 2020]
User [u_id=80, u_name=baisushan, u_pwd=123456, u_date=Mon Mar 16 11:41:07 CST 2020]
User [u_id=56, u_name=sanjianke, u_pwd=123456, u_date=Mon Mar 16 22:03:03 CST 2020]

3、choose when otherwise、标签

类似于java中的switch




<select id="queryUserByIDNamePwd2" resultType="User">
    select * from u_user
    <where>
        <choose>
            <when test="name!=null and name!=''">
                and u_name = #{name}
            when>
            <when test="pwd!=null and pwd!=''">
                and u_pwd = #{pwd}
            when>
            <otherwise>
                1=1
            otherwise>
        choose>
    where>
select>
  • when:相当于java中的case
  • otherwise:相当于java中的default

java程序:查找全部数据

List<User> list = mapper.queryUserByIDNamePwd2(null, null);
运行结果
User [u_id=1, u_name=zhangsan, u_pwd=123456, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=2, u_name=lisi, u_pwd=123123, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=3, u_name=wanger, u_pwd=112233, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=4, u_name=mazi, u_pwd=123456789, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=5, u_name=wangwu, u_pwd=666666, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=6, u_name=zhaoliu, u_pwd=88888888, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=20, u_name=#{item.u_name), u_pwd=#{item.u_pwd}, u_date=Mon Mar 16 10:49:46 CST 2020]
User [u_id=7, u_name=ahh, u_pwd=123123, u_date=Sun Mar 15 22:09:03 CST 2020]
User [u_id=30, u_name=wahaah, u_pwd=123456, u_date=Mon Mar 16 11:41:07 CST 2020]
User [u_id=60, u_name=shaungwaiwai, u_pwd=123456, u_date=Mon Mar 16 11:41:07 CST 2020]
User [u_id=80, u_name=baisushan, u_pwd=123456, u_date=Mon Mar 16 11:41:07 CST 2020]
User [u_id=54, u_name=whh, u_pwd=11223344, u_date=Mon Mar 16 19:09:11 CST 2020]
User [u_id=55, u_name=kl, u_pwd=221133, u_date=Mon Mar 16 19:09:11 CST 2020]
User [u_id=56, u_name=sanjianke, u_pwd=123456, u_date=Mon Mar 16 22:03:03 CST 2020]

java程序:根据Name查找

List<User> list = mapper.queryUserByIDNamePwd2("kl", null);
运行结果
User [u_id=55, u_name=kl, u_pwd=221133, u_date=Mon Mar 16 19:09:11 CST 2020]

java程序:根据Pwd查找

List<User> list = mapper.queryUserByIDNamePwd2(null, "123456");
运行结果
User [u_id=1, u_name=zhangsan, u_pwd=123456, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=30, u_name=wahaah, u_pwd=123456, u_date=Mon Mar 16 11:41:07 CST 2020]
User [u_id=60, u_name=shaungwaiwai, u_pwd=123456, u_date=Mon Mar 16 11:41:07 CST 2020]
User [u_id=80, u_name=baisushan, u_pwd=123456, u_date=Mon Mar 16 11:41:07 CST 2020]
User [u_id=56, u_name=sanjianke, u_pwd=123456, u_date=Mon Mar 16 22:03:03 CST 2020]

4、set标签

维护Update语句中的set子句




<update id="updateUserNamePwdDateByID">
    update u_user
    <set>
        
        u_id = #{u_id},
        <if test="u_name!=null and u_name!=''">
            u_name = #{u_name},
        if>
        <if test="u_pwd!=null and u_pwd!=''">
            u_pwd = #{u_pwd},
        if>
        <if test="u_date!=null">
            u_date = #{u_date},
        if>
    set>
    where u_id = #{u_id}
update>
  • 如果不满足条件则不会生成set关键字,反之
  • 自动去除最后一个,

java程序:根据ID修改name

int len = mapper.updateUserNamePwdDateByID(new User(56,"sanjianke",null,null));
运行结果
1

java程序:根据ID修改Name和Pwd

int len = mapper.updateUserNamePwdDateByID(new User(56,"sanjianke","123456"));
运行结果
1

java程序:根据ID修改Name和Pwd和Date

int len = mapper.updateUserNamePwdDateByID(new User(56,"sanjianke","123456",new Date()));
运行结果
1

5、trim标签

如果对where和set的删除某些内容不不满意,可以自己定义





<select id="queryByNamePwd1" resultType="User">
    select * from u_user
    <trim prefix="where" prefixOverrides="and | or">
        <if test="name!=null and name!=''">
            and u_name = #{name}
        if>
        <if test="pwd!=null and pwd!=''">
            and u_pwd = #{pwd}
        if>
    trim>
select>
  • prefix:在前面添加的内容
    • suffix:在最后添加内容
  • prefixOverrides:删除第一个结果的内容
    • suffixOverrides:删除最后的内容

java程序:根据Name或者Pwd查找数据

// 根据Name或者Pwd查找数据-trim标签
@Test
public void test7() {
    SqlSession session = MyBatisUtil.getSqlSession();
    UserMapper mapper = session.getMapper(UserMapper.class);
    List<User> list = mapper.queryByNamePwd1("","123456");
    list.forEach(System.out::println);
    session.close();
}
运行结果
User [u_id=1, u_name=zhangsan, u_pwd=123456, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=30, u_name=wahaah, u_pwd=123456, u_date=Mon Mar 16 11:41:07 CST 2020]
User [u_id=60, u_name=shaungwaiwai, u_pwd=123456, u_date=Mon Mar 16 11:41:07 CST 2020]
User [u_id=80, u_name=baisushan, u_pwd=123456, u_date=Mon Mar 16 11:41:07 CST 2020]
User [u_id=56, u_name=sanjianke, u_pwd=123456, u_date=Mon Mar 16 22:41:51 CST 2020]

6、bind标签

对传入的数据在加工


<select id="queryByNameLike" resultType="User">
    select * from u_user
    <where>
        <if test="name!=null and name!=''">
            <bind name="name" value="'%'+name+'%'"/>
            u_name like #{name}
        if>
    where>
select>
  • name:加工后的值的名字
  • value:加工(字符串拼接)

java程序:传入一个空字符串,查找全部内容

List<User> list = mapper.queryByNameLike("");
运行结果
User [u_id=1, u_name=zhangsan, u_pwd=123456, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=2, u_name=lisi, u_pwd=123123, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=3, u_name=wanger, u_pwd=112233, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=4, u_name=mazi, u_pwd=123456789, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=5, u_name=wangwu, u_pwd=666666, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=6, u_name=zhaoliu, u_pwd=88888888, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=20, u_name=#{item.u_name), u_pwd=#{item.u_pwd}, u_date=Mon Mar 16 10:49:46 CST 2020]
User [u_id=7, u_name=ahh, u_pwd=123123, u_date=Sun Mar 15 22:09:03 CST 2020]
User [u_id=30, u_name=wahaah, u_pwd=123456, u_date=Mon Mar 16 11:41:07 CST 2020]
User [u_id=60, u_name=shaungwaiwai, u_pwd=123456, u_date=Mon Mar 16 11:41:07 CST 2020]
User [u_id=80, u_name=baisushan, u_pwd=123456, u_date=Mon Mar 16 11:41:07 CST 2020]
User [u_id=54, u_name=whh, u_pwd=11223344, u_date=Mon Mar 16 19:09:11 CST 2020]
User [u_id=55, u_name=kl, u_pwd=221133, u_date=Mon Mar 16 19:09:11 CST 2020]
User [u_id=56, u_name=sanjianke, u_pwd=123456, u_date=Mon Mar 16 22:41:51 CST 2020]

java程序:查找Name中带h的

List<User> list = mapper.queryByNameLike("h");
运行结果
User [u_id=7, u_name=ahh, u_pwd=123123, u_date=Sun Mar 15 22:09:03 CST 2020]
User [u_id=80, u_name=baisushan, u_pwd=123456, u_date=Mon Mar 16 11:41:07 CST 2020]
User [u_id=60, u_name=shaungwaiwai, u_pwd=123456, u_date=Mon Mar 16 11:41:07 CST 2020]
User [u_id=30, u_name=wahaah, u_pwd=123456, u_date=Mon Mar 16 11:41:07 CST 2020]
User [u_id=54, u_name=whh, u_pwd=11223344, u_date=Mon Mar 16 19:09:11 CST 2020]
User [u_id=1, u_name=zhangsan, u_pwd=123456, u_date=Sun Mar 15 18:41:45 CST 2020]
User [u_id=6, u_name=zhaoliu, u_pwd=88888888, u_date=Sun Mar 15 18:41:45 CST 2020]

7、foreach标签

遍历传入的list集合或者数组


<update id="updateSomeUser">
    <foreach collection="list" item="item" open="begin" close=";end;" separator=";">
        update u_user set u_name = #{item.u_name},u_pwd = #{item.u_pwd} where u_id = #{item.u_id}	
    foreach>
update>
  • collection:传入的数据类型,list集合就是list,数组就是array
  • item:遍历过程中每条数据的临时储存
  • open:头部添加内容
  • close:结尾添加内容
  • separator:每次遍历完毕添加内容
@Test
public void test2() {
    SqlSession session = MyBatisUtil.getSqlSession();
    UserMapper mapper = session.getMapper(UserMapper.class);
    int len = mapper.updateSomeUser(Arrays.asList(new User(54,"whh","11223344",new Date()),
                                                  new User(56,"sww","789456",new Date()),new User(55,"kl","221133",new Date())));
    System.out.println(len);
    session.close();
}
运行结果
-1

Tips:-1是对结果,原因不清楚。

8、Sql Include标签

引用SQL语句

SQL

<sql id="user_all_field">
    u_id,u_name,u_pwd,u_date
sql>

Include

<select id="queryAll" resultType="user">
    select <include refid="user_all_field"/> from u_user
select>

七、自动映射

自动映射:MyBatis自动把数据库中查出来的数据按照字段名字和JavaBean对象的属性进行匹配。

1、自动映射

如果数据库字段名和类的属性名一致,将会自动映射

2、设置别名的方式

如果数据库中的字段名和类的属性的属性名不一致,可以在Sql中设置别名。然后继续使用自动映射

<select id="queryAll1" resultType="Student">
    select u_id t_id,u_name t_naem,u_pwd t_pwd,u_date t_date from u_user
select>

2、resultMap

用于自定义映射关系,一旦使用resultMap将不在采用自动映射机制。

<resultMap type="Student" id="s1">
    
    <id column="u_id" property="t_id"/>
    
    <result column="u_name" property="t_name"/>
    <result column="u_pwd" property="t_pwd"/>
    <result column="u_date" property="t_date"/>
resultMap>

<select id="queryAll2" resultMap="s1">
    select * from u_user
select>

java程序

@Test
public void test2() {
    SqlSession session = MyBatisUtil.getSqlSession();
    StudentMapper mapper =  session.getMapper(StudentMapper.class);
    List<Student> list = mapper.queryAll1();
    list.forEach(System.out::println);
    session.close();
}
运行结果
Student [t_id=1, t_name=null, t_pwd=123456, t_date=Sun Mar 15 18:41:45 CST 2020]
Student [t_id=2, t_name=null, t_pwd=123123, t_date=Sun Mar 15 18:41:45 CST 2020]
Student [t_id=3, t_name=null, t_pwd=112233, t_date=Sun Mar 15 18:41:45 CST 2020]
Student [t_id=4, t_name=null, t_pwd=123456789, t_date=Sun Mar 15 18:41:45 CST 2020]
Student [t_id=5, t_name=null, t_pwd=666666, t_date=Sun Mar 15 18:41:45 CST 2020]
Student [t_id=6, t_name=null, t_pwd=88888888, t_date=Sun Mar 15 18:41:45 CST 2020]
Student [t_id=20, t_name=null, t_pwd=#{item.u_pwd}, t_date=Mon Mar 16 10:49:46 CST 2020]
Student [t_id=7, t_name=null, t_pwd=123123, t_date=Sun Mar 15 22:09:03 CST 2020]
Student [t_id=30, t_name=null, t_pwd=123456, t_date=Mon Mar 16 11:41:07 CST 2020]
Student [t_id=60, t_name=null, t_pwd=123456, t_date=Mon Mar 16 11:41:07 CST 2020]
Student [t_id=80, t_name=null, t_pwd=123456, t_date=Mon Mar 16 11:41:07 CST 2020]
Student [t_id=54, t_name=null, t_pwd=11223344, t_date=Mon Mar 16 19:09:11 CST 2020]
Student [t_id=55, t_name=null, t_pwd=221133, t_date=Mon Mar 16 19:09:11 CST 2020]
Student [t_id=56, t_name=null, t_pwd=789456, t_date=Mon Mar 16 22:41:51 CST 2020]

你可能感兴趣的:(MyBatis框架的简单使用)