一 关于mabatis
mybatis官方文档中文版: https://mybatis.net.cn/
1.下载mybatis
:MyBatis下载地址:https://github.com/mybatis/mybatis-3
解压之后
搭建开发环境
创建一个空项目
项目名
我们配置之后,当本地已经下载过之后它就会再本地寻找
2.创建maven工程
<dependencies>
<!-- Mybatis核心 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.9</version>
</dependency>
<!-- junit测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.3</version>
</dependency>
</dependencies>
3 创建MyBatis的核心配置文件
4.创建MyBatis的mapper接口
创建数据库
User.java
package com.atguigu.mabatis.pojo;
/**
* @author weijiangquan
* @date 2022/4/19 -17:40
*/
public class User {
private Integer id;
private String username;
private String password;
private Integer age;
private String sex;
private String email;
public User() {
}
public User(Integer id, String username, String password, Integer age, String sex, String email) {
this.id = id;
this.username = username;
this.password = password;
this.age = age;
this.sex = sex;
this.email = email;
}
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 String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
", email='" + email + '\'' +
'}';
}
}
为什么要创建接口,因为该接口中的方法有自动匹配sql语句的功能
5.创建MyBatis的映射文件
6.MyBatis框架之测试添加功能(p11)
测试代码
package com.atguigu.mybatis.test;
import com.atguigu.mabatis.mapper.UserMapper;
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.Test;
import java.io.IOException;
import java.io.InputStream;
/**
* @author weijiangquan
* @date 2022/4/19 -18:17
*/
public class MyBatisTest {
@Test
public void testMyBatis() throws IOException {
//加载核心配置文件
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
// 获取SqlSessionFactoryBuilder
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//获取splSessionFactory
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
//获取SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取mapper接口对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//测试功能
int result = mapper.insertUser();
// 提交事务
sqlSession.commit();
System.out.println("result:"+result);
}
}
运行结果
数据库插入成功
7 MyBatis框架之优化功能
优化一
优化二(加入log4j日志功能)(有问题)
通过日志文件检测对于数据库的操作
问题已经解决
8 测试修改和删除功能
package com.atguigu.mabatis.mapper;
/**
* @author weijiangquan
* @date 2022/4/19 -17:46
*
*/
public interface UserMapper{
/**
*
* Mybatis面向接口编程的两个一致:
* 1.映射文件的namespace要和mapper接口的全类名保持一致
* 2.映射文件中sql语句的id要和mapper接口中的方法名一致
*
* 表---实体类---mapper接口---映射文件
*/
// 添加用户
int insertUser();
// 修改用户信息
void updateUser();
//删除用户信息
void deleteUser();
}
<?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="com.atguigu.mabatis.mapper.UserMapper">
<!--int insertUser();-->
<insert id="insertUser">
insert into t_user values(null,'admin','123456',23,'男','12345@qq.com');
</insert>
<!-- void updateUser();-->
<insert id="updateUser">
update t_user set username = '张三' where id = 6;
</insert>
<!--void deleteUser();-->
<insert id="deleteUser">
delete from t_user where id = 7;
</insert>
</mapper>
测试java代码
package com.atguigu.mybatis.test;
import com.atguigu.mabatis.mapper.UserMapper;
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.Test;
import java.io.IOException;
import java.io.InputStream;
/**
* @author weijiangquan
* @date 2022/4/19 -18:17
*
* sqlSession默认不自动提交事务,若需要自动提交事物
* 可以来使用SqlSessionFactory.openSession(true) 自动提交
*
*
*/
public class MyBatisTest {
@Test
public void testMyBatis() throws IOException {
//加载核心配置文件
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
// 获取SqlSessionFactoryBuilder
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//获取splSessionFactory
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
//获取SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession(true); //为true就是自动提交事务
//获取mapper接口对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class); //底层使用的是代理模式
//测试功能
int result = mapper.insertUser();
/* // 提交事务
sqlSession.commit();*/
System.out.println("result:"+result);
}
// 更新功能
@Test
public void testUpdate() throws IOException {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession(true); //为true就是自动提交事务
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.updateUser();
}
// 删除功能
@Test
public void testCRUD() throws IOException {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession(true); //为true就是自动提交事务
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.deleteUser();
}
}
9 查询功能
运行结果
完整代码
UserMapper.java
package com.atguigu.mabatis.mapper;
import com.atguigu.mabatis.pojo.User;
import java.util.List;
/**
* @author weijiangquan
* @date 2022/4/19 -17:46
*
*/
public interface UserMapper{
/**
*
* Mybatis面向接口编程的两个一致:
* 1.映射文件的namespace要和mapper接口的全类名保持一致
* 2.映射文件中sql语句的id要和mapper接口中的方法名一致
*
* 表---实体类---mapper接口---映射文件
*/
// 添加用户
int insertUser();
// 修改用户信息
void updateUser();
//删除用户信息
void deleteUser();
//根据id查询用户信息 查询功能
User getUserById();
//查询所有的用户信息
List<User> getAllUser();
}
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">
<mapper namespace="com.atguigu.mabatis.mapper.UserMapper">
<!--int insertUser();-->
<insert id="insertUser">
insert into t_user values(null,'admin','123456',23,'男','12345@qq.com');
</insert>
<!-- void updateUser();-->
<insert id="updateUser">
update t_user set username = '张三' where id = 6;
</insert>
<!--void deleteUser();-->
<insert id="deleteUser">
delete from t_user where id = 7;
</insert>
<!--User getUse0rById();-->
<!--查询功能的标签必须设置resultType或resultMap -->
<!--resultType:设置默认的映射关系-->
<!-- <!–resultMap:设置自定义的映射关系–> 字段名和映射名不一致的时候使用这个-->
<select id="getUserById" resultType="com.atguigu.mabatis.pojo.User">
select * from t_user where id = 10;
</select>
<!-- List<User> getAllUser();-->
<select id="getAllUser" resultType="com.atguigu.mabatis.pojo.User">
select * from t_user;
</select>
</mapper>
MyBatisTest.java
package com.atguigu.mybatis.test;
import com.atguigu.mabatis.mapper.UserMapper;
import com.atguigu.mabatis.pojo.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.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* @author weijiangquan
* @date 2022/4/19 -18:17
*
* sqlSession默认不自动提交事务,若需要自动提交事物
* 可以来使用SqlSessionFactory.openSession(true) 自动提交
*
*
*/
public class MyBatisTest {
@Test
public void testMyBatis() throws IOException {
//加载核心配置文件
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
// 获取SqlSessionFactoryBuilder
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//获取splSessionFactory
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
//获取SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession(true); //为true就是自动提交事务
//获取mapper接口对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class); //底层使用的是代理模式
//测试功能
int result = mapper.insertUser();
/* // 提交事务
sqlSession.commit();*/
System.out.println("result:"+result);
}
// 更新功能
@Test
public void testUpdate() throws IOException {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession(true); //为true就是自动提交事务
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.updateUser();
}
// 删除功能
@Test
public void testCRUD() throws IOException {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession(true); //为true就是自动提交事务
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// mapper.deleteUser();
/* // 查询一个用户的所有信息
User user = mapper.getUserById();
System.out.println(user);*/
// 查询所有用户的信息(嘿嘿)
List<User> list = mapper.getAllUser();
list.forEach(user -> System.out.println(user));
}
}
10 核心配置文件(了解)
11 核心配置文件properites
12 核心配置文件之typeAliases
13 核心配置文件mappers
14 映射文件中sql该如何拼接
15 在idea中设置核心配置文件的模板
自己写的模板(在官方文档中复制过来稍微修改一下)
<?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>
<properties resource="jdbc.properties"></properties>
<!-- 设置类型别名(以包的方式)-->
<typeAliases>
<package name=""/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<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=""/>
</mappers>
</configuration>
16.映射文件的模板
官方文档的
<?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="org.mybatis.example.BlogMapper">
<select id="selectBlog" resultType="Blog">
select * from Blog where id = #{id}
</select>
</mapper>
在它的基础上稍微修改一下
修改之后的
<?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="">
</mapper>
17 工具类并测试
工具类的代码
package com.hxut.mybatis.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;
/**
* @author weijiangquan
* @date 2022/4/20 -11:43
*
* 封装的一个工具类
*
*/
public class SqlSessionUtils {
public static SqlSession getSqlSession(){
SqlSession sqlSession = null;
try {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
sqlSession = sqlSessionFactory.openSession(true); //为true就是自动提交事务
} catch (IOException e) {
e.printStackTrace();
}
return sqlSession;
}
}
二 MyBatis获取参数值的两种方式(重点)
MyBatis获取参数值的两种方式:${}和#{}
${}的本质就是字符串拼接,#{}的本质就是占位符赋值
${}使用字符串拼接的方式拼接sql,若为字符串类型或日期类型的字段进行赋值时,需要手动加单引
号;但是#{}使用占位符赋值的方式拼接sql,此时为字符串类型或日期类型的字段进行赋值时,可以自
动添加单引号
1.mybatis获取参数值的各种情况(前三种情况)
MyBatis获取参数的两种方式:${}和#{}
* ${}本质是字符串拼接
* #{}本质是占位符赋值
*
* mybatis来获取参数值的各种情况:
* 1.mapper接口方法参数为单个的字面量类型
* 可以通过${}和#{}以任意的名称获取参数值,但是要注意${}的单引号问
* 2.mapper接口的参数为多个时候
* 此时Mybatis会将这些参数放在一个map集合中,以两种方式进行存储
* ① 以arg0,arg1...为键,以参数为值
* ② 以param1,param2...为键,以参数为值
*
* 因此只需要通过#{}和${}以键的方式访问值即可,但是需要注意${}的单引号问题
* 3.若mapper接口方法的参数有多个时,可以手动将这些参数放在一个map中存储
* 只需要通过#{}和${}以键的方式访问值即可,但是需要注意${}单引号问
测试里面的代码
@Test
public void testGetUserByUsername(){
// 这是静态方法不用通过new的方式创建出来,直接通过点类名的方式弄出来
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
User user = mapper.getByUserName("张三");
System.out.println(user);
}
然后是mapper接口中的方法
映射文件
运行结果
完整代码
package com.hxut.mybatis.test;
import com.hxut.mybatis.mapper.ParameterMapper;
import com.hxut.mybatis.pojo.User;
import com.hxut.mybatis.utils.SqlSessionUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author weijiangquan
* @date 2022/4/20 -11:41
*
* MyBatis获取参数的两种方式:${}和#{}
* ${}本质是字符串拼接
* #{}本质是占位符赋值
*
* mybatis来获取参数值的各种情况:
* 1.mapper接口方法参数为单个的字面量类型
* 可以通过${}和#{}以任意的名称获取参数值,但是要注意${}的单引号问
* 2.mapper接口的参数为多个时候
* 此时Mybatis会将这些参数放在一个map集合中,以两种方式进行存储
* ① 以arg0,arg1...为键,以参数为值
* ② 以param1,param2...为键,以参数为值
*
* 因此只需要通过#{}和${}以键的方式访问值即可,但是需要注意${}的单引号问题
* 3.若mapper接口方法的参数有多个时,可以手动将这些参数放在一个map中存储
* 只需要通过#{}和${}以键的方式访问值即可,但是需要注意${}单引号问
*/
public class ParameterMapperTest{
@Test
public void testCheckLoginByMap(){
// 这是静态方法不用通过new的方式创建出来,直接通过点类名的方式弄出来
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
Map<String,Object> map = new HashMap<>();
map.put("username","张三");
map.put("password","123456");
User user = mapper.checkLoginByMap(map);
System.out.println(user);
}
// 多个参数
@Test
public void testCheckLogin(){
// 这是静态方法不用通过new的方式创建出来,直接通过点类名的方式弄出来
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
User user = mapper.checkLogin("张三","123456");
System.out.println(user);
}
// 单个参数
@Test
public void testGetUserByUsername(){
// 这是静态方法不用通过new的方式创建出来,直接通过点类名的方式弄出来
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
User user = mapper.getByUserName("张三");
System.out.println(user);
}
@Test
public void testGetAllUser(){
// 这是静态方法不用通过new的方式创建出来,直接通过点类名的方式弄出来
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
List<User> list = mapper.getAllUser();
list.forEach(user-> System.out.println(user));
}
}
package com.hxut.mybatis.mapper;
import com.hxut.mybatis.pojo.User;
import java.util.List;
import java.util.Map;
/**
* @author weijiangquan
* @date 2022/4/20 -11:25
*/
public interface ParameterMapper{
/**
* 验证登录(参数为map)
*/
User checkLoginByMap(Map<String,Object> map);
User checkLogin(String username,String password);
// 根据用户查询用户信息
User getByUserName(String username);
/**
* 查询所有的员工信息
*/
List<User> getAllUser();
}
<?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="com.hxut.mybatis.mapper.ParameterMapper">
<!--List<User> getAllUser();-->
<select id="getAllUser" resultType="com.hxut.mybatis.pojo.User">
select * from t_user;
</select>
<!-- User getByUserName(String username);-->
<select id="getByUserName" resultType="com.hxut.mybatis.pojo.User">
<!--select * from t_user where username = #{username} -->
select * from t_user where username = '${username}'
</select>
<!-- User checkLogin(String username,String password);-->
<select id="checkLogin" resultType="com.hxut.mybatis.pojo.User">
select * from t_user where username = #{arg0} and password = #{arg1}
</select>
<!-- User checkLoginByMap(Map<String,Object> map);-->
<select id="checkLoginByMap" resultType="com.hxut.mybatis.pojo.User">
select * from t_user where username = #{username} and password = #{password}
</select>
</mapper>
2 第四种情况
mapper接口的参数是实体类类型的参数 (用的最多的情况)
只需要通过#{}和${}以属性的方式访问属性即可,但是需要注意${}单引号问题
测试代码
// 对应上面的标题4
@Test
public void testInsertUser(){
// 这是静态方法不用通过new的方式创建出来,直接通过点类名的方式弄出来
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
int result = mapper.insertUser(new User(null, "王五", "123", 22, "男", "121@qq.com"));
System.out.println(result);
}
/**
* 添加用户信息
*
*/
int insertUser(User user);
<!-- int insertUser(User user);-->
<insert id="insertUser">
insert into t_user values(null,#{username},#{password},#{age},#{sex},#{email})
</insert>
3第五种情况
* 5.使用@Param注解命名参数
* 此时MyBatis会将这些参数放在一个map集合中,以两种方式进行存储
* a->以@param注解的值为键,以参数为值
* b->a以@param1,param2...为键,以参数为值
* 因此只需要通过#{}和${}以键的方式访问值即可,但是需要注意${}的单引号问题
// 对应上面的标题4
@Test
public void testCheckLoginByParam(){
// 这是静态方法不用通过new的方式创建出来,直接通过点类名的方式弄出来
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
User user = mapper.checkLoginByParam("张三","123456");
System.out.println(user);
}
/**
* 验证登录(使用@Param)
*/
User checkLoginByParam(@Param("username") String username, @Param("password") String password);
<!-- User checkLoginByParam(@Param("username") String username, @Param("password") string password);-->
<select id="checkLoginByParam" resultType="com.hxut.mybatis.pojo.User">
select * from t_user where username = #{username} and password = #{password}
</select>
建议以后就是用实体类的情况和注解的情况,这样更好一点
三 MyBatis的各种查询功能
1 Mybatis各种查询功能(1)
package com.hxut.mybatis.test;
import com.hxut.mybatis.mapper.SelectMapper;
import com.hxut.mybatis.utils.SqlSessionUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
/**
* @author weijiangquan
* @date 2022/4/20 -20:24
*
* Mybatis的各种查询功能
* 1.若查询出的数据只有一条,
* ①可以通过实体类
* ②集合进行接收对象接收
* ③
* 2.若查询的数据有多条,
* ①可以通过list集合接收,
* 注意:一定不能通过实体类对象接收,这个时候会抛出异常 TooManyResultException
* ②
* 3.
*/
public class SelectMapperTest {
// 多条数据的情况下
@Test
public void testGetAllUser(){
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
System.out.println(mapper.getAllUser());
}
@Test
public void testGetUserById(){
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
System.out.println(mapper.getUserById(12));
}
}
package com.hxut.mybatis.mapper;
import com.hxut.mybatis.pojo.User;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author weijiangquan
* @date 2022/4/20 -20:19
*/
public interface SelectMapper {
/**
* 根据id查询用户的信息
*/
User getUserById(@Param("id") Integer id);
// List<User> getUserById(@Param("id") Integer id);
/**
* 查询所有的用户信息
*/
List<User> getAllUser();
}
<?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="com.hxut.mybatis.mapper.SelectMapper">
<!-- User getUserById(@Param() Integer id);-->
<select id="getUserById" resultType="com.hxut.mybatis.pojo.User">
select * from t_user where id = #{id};
</select>
<!-- List<User> getAllUser();-->
<select id="getAllUser" resultType="com.hxut.mybatis.pojo.User">
select * from t_user;
</select>
</mapper>
运行结果
2 Mybatis各种查询功能(2)
* MyBatis中设置了类型别名
* java.lang.Integer -->int,integer
* int -->_int,_Integer
* Map -->map
* String -->String
* 这几个是最常用的
@Test
public void testGetCount(){
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
System.out.println(mapper.getCount());
}
<!-- Integer getCount();-->
<select id="getCount" resultType="java.lang.Integer">
select count(*) from t_user;
</select>
/**
* 查询用户信息的总的记录数
*/
Integer getCount();
3 Mybatis各种查询功能(3)-map集合
@Test
public void testGetUserByIdToMap(){
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
System.out.println(mapper.getUserByIdToMap(13));
}
<select id="getUserByIdToMap" resultType="map">
select * from t_user where id = #{id}
</select>
Map<String,Object> getUserByIdToMap(@Param("id") Integer id);
4.Mybatis各种查询功能(4)
@Test
public void testGetAllUserToMap(){
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
System.out.println(mapper.getAllUserToMap());
}
<!-- Map<String,Object> getAllUserToMap();-->
<select id="getAllUserToMap" resultType="map">
select * from t_user;
</select>
/**
* 查询所有用户信息为map集合
*/
// List<Map<String,Object>> getAllUserToMap();
@MapKey("id")
Map<String,Object> getAllUserToMap();
第二种方式的运行结果
四 特殊SQL查询
1 处理模糊查询(有点问题)
/**
* 根据用户名模糊查询用户信息
*/
List<User> getUserByLike(@Param("username") String username);
@Test
public void testGetUserByLike(){
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
SQLMapper mapper = sqlSession.getMapper(SQLMapper.class);
List<User> list = mapper.getUserByLike("a");
System.out.println(list);
}
2.处理批量删除
@Test
public void testDeleteMore(){
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
SQLMapper mapper = sqlSession.getMapper(SQLMapper.class);
int result = mapper.deleteMore("6,7,8");
System.out.println(result);
}
/**
* 批量删除
*/
int deleteMore(@Param("ids") String ids);
<!-- int deleteMore(@Param("ids") String ids);-->
<delete id="deleteMore">
delete
from t_user
where id in (${ids})
</delete>
</mapper>
3.动态设置表名
4 获取添加功能自增的主键
五 自定义映射resultMap(开启demo3)
1.通过字段名解决字段名和属性名的映射关系
为什么会出现这种情况,由于表有表的命名规范,而属性也有自己的命名规范,就会导致不一致的情况,我们应该如何解决呢
第一种解决方式(取别名)
给字段取别名让其和属性名一致
第二种方式(在配置文件中配置官方提供的方式)
设置全局配置,将_自动映射为驼峰
这个满足的条件就是属性符合属性的规则,字段符合字段的规则
第三种方式(resultMap常用)
通过resultMap设置自定义映射关系
id:用来设置唯一标识,不能重复
type:设置映射关系种的实体类类型
子标签: id设置主键映射关系
result:设置普通字段映射关系
属性:
property:设置映射关系种的属性名,必须是所设置的实体类中的属性名
column:设置映射关系中的字段名:必须是sql语句查询出的字段名
2.多对一的映射
2.1 通过级联属性赋值的方式解决多对一的映射关系方式一
这种方式用到不是很多
员工表如下
部门表如下
<!-- 通过级联的方式进行赋值-->
<resultMap id="empAndDeptResultMapOne" type="Emp">
<id property="eid" column="eid"></id>
<result property="empName" column="emp_name"></result>
<result property="age" column="age"></result>
<result property="email" column="email"></result>
<result property="sex" column="sex"></result>
<result property="dept.did" column="did"></result>
<result property="dept.deptName" column="dept_name"></result>
</resultMap>
<!-- 处理多对一的三种方式-->
<!--Emp getEmpAndDept(@Param("eid") Integer eid);-->
<select id="getEmpAndDept" resultMap="empAndDeptResultMapOne">
select * from t_emp left join t_dept on t_emp.did = t_dept.did where t_emp.eid = #{eid};
</select>
@Test
public void testGetEmpAndDept(){
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
Emp emp = mapper.getEmpAndDept(2);
System.out.println(emp);
}
2.2 通过associastion解决多对一的映射关系
这种方式比第一种方式常用一点
2.3 通过多部查询的方式(用的最多的方式)
我们可以先查询员工,再查询员工多对应的部门信息
3 延迟加载(p45 11min)
用的到的时候再说
4 一对多的映射
4.1 通过collection解决一对多的映射关系
记住一句话,对一对应对象.对多对应集合
现在是部门表对主表
处理一对多的映射关系
- collection
- 分部查询
collection用来处理一对多的映射关系
ofType:表示该属性所对应的集合中存储数据类型
@Test
public void testGetDeptAndEmp(){
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
Dept dept = mapper.getDeptAndEmp(1);
System.out.println(dept);
}
<resultMap id="deptAndEmpResultMap" type="Dept">
<id property="did" column="did"></id>
<result property="deptName" column="dept_name"></result>
<collection property="emps" ofType="Emp">
<id property="eid" column="eid"></id>
<result property="empName" column="emp_Name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<result property="email" column="email"></result>
</collection>
</resultMap>
<!-- Dept getDeptAndEmp(@Param("did") Integer did);-->
<select id="getDeptAndEmp" resultMap="deptAndEmpResultMap">
select * from t_dept left join t_emp on t_dept.did = t_emp.did where t_dept.did = #{did}
</select>
/**
* 部门以及部门种所有的员工信息
*
*/
Dept getDeptAndEmp(@Param("did") Integer did);
4.2 通过分布查询解决一对多的映射关系(p47 12min)
六 动态SQL介绍
1 动态SQL之if标签
<?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="com.hxut.mybatis.mapper.DynamicSQLMapper">
<!-- List<Emp> getEmpByCondition(Emp emp);-->
<select id="getEmpByCondition" resultType="Emp">
select * from t_emp where 1=1
<if test="empName!=null and empName !=''">
emp_name = #{empName}
</if>
<if test="age!=null and age !=''">
and age = #{age}
</if>
<if test="email !=null and email != ''">
and email = #{email}
</if>
</select>
</mapper>
@Test
public void testGetEmpByCondition(){
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
List<Emp> list = mapper.getEmpByCondition(new Emp(null, "张三", 12, "男", "1212@qq.com",null));
System.out.println(list);
}
/**
* 多条件查询
*/
List<Emp> getEmpByCondition(Emp emp);
2 动态SQL之where标签
当where中有内容时,会自动生成where关键字,并且将内容前多余的and或者or去掉
当where标签中没有内容时,此时where标签没有任何效果
注意:where标签不能将内容后面多余的内容去掉
3 动态SQL之trim标签
3.trim(有下面的4个属性)
* prefix="" suffix="" suffixOverrides="" prefixOverrides=""
* prefix|suffix:将trim标签中内容前面或后面添加指定的内容
* suffixOverrides|prefixOverrides:将trim前面或者后面去掉指定的内容
* 若标签中没有内容时,trim标签也没有任何效果
*
<select id="getEmpByCondition" resultType="Emp">
select *
from t_emp
<trim prefix="where" suffix="" suffixOverrides="and|or" prefixOverrides="">
<if test="empName != null and empName != ''">
emp_name = #{empName} and
</if>
<if test="age != null and age != ''">
age = #{age} and
</if>
<if test="age != null and age != ''">
sex = #{sex} and
</if>
<if test="email != null and email != ''">
email = #{email}
</if>
</trim>
</select>
List<Emp> getEmpByCondition(Emp emp);
@Test
public void testGetEmpByCondition(){
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
List<Emp> list = mapper.getEmpByCondition(new Emp(null, null, 12, "男", "1212@qq.com",null));
System.out.println(list);
}
4.SQL之choose,when,otherwise
/**
* 用来测试choose,when,otherwise
*/
List<Emp> getEmpByChoose(Emp emp);
<!-- List<Emp> getEmpByChoose(Emp emp);-->
<select id="getEmpByChoose" resultType="Emp">
select * from t_emp
<where>
<choose>
<when test="empName!=null and empName!='' ">
emp_name = #{empName}
</when>
<when test="age!=null and age!='' ">
age = #{age}
</when>
<when test="empName!=null and empName!='' ">
sex = #{sex}
</when>
<when test="empName!=null and empName!=''">
email = #{email}
</when>
<otherwise>
did = 1
</otherwise>
</choose >
</where>
</select>
5 动态查询之foreach标签
批量删除
/**
* 通过数组来实现批量删除
*/
int deleteMoreByArray(@Param("eids") Integer[] eids);
@Test
public void testDeleteMoreByArray(){
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
int result = mapper.deleteMoreByArray(new Integer[]{6, 7, 8});
System.out.println(result);
}
6 动态查询之foreach标签(2)–使用集合
实现批量添加的功能
7 动态SQL之sql标签
所要解决的问题
我们可以将要经常查询的字段方法sql记录中
在测试中可以看到以代码片段的方式引入过来了
七 Mybatis的缓存
1、MyBatis的一级缓存
一级缓存是SqlSession级别的,通过同一个SqlSession查询的数据会被缓存,下次查询相同的数据,就
会从缓存中直接获取,不会从数据库重新访问
使一级缓存失效的四种情况:
- 不同的SqlSession对应不同的一级缓存
- 同一个SqlSession但是查询条件不同
- 同一个SqlSession两次查询期间执行了任何一次增删改操作
- 同一个SqlSession两次查询期间手动清空了缓存
<select id="getEmpByEid" resultType="Emp">
select * from t_emp where eid = #{eid}
</select>
Emp getEmpByEid(@Param("eid") Integer eid);
2.让一级缓存失效的四种情况(p57-跳)
3.二级缓存(p58跳-p62)
4 Mybatis逆向工程之清晰简洁版(p63)
自动生成代码
5 Mybatis逆向工程奢华版
八 分页插件(有bug)
1、分页插件使用步骤
a>添加依赖
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.2.0</version> </dependency>