1.什么是MyBatis?
环境:
JDK:1.8
Mysql–5.7
maven–3.6.1
个人笔记:
1.先配置一个mybatis-config.xml文件,对应UserMapper.xml
2.然后在UserMapper.xml中设置好
id(对应接口的id)、对应的实体类
数据库中对应的表格
3.编写工具类—在这里 获取sqlSessionFactory对象
编写一个sqlSessionFactory.openSession();的getSqlSession方法
4.开始测试–先调用getSqlSession方法,然后再调用sqlsession的getMapper方法,去映射
UserDao.class,然后再调用.getUserList();方法去遍历它
最后关闭sqlsession。
如何获取MyBatis
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
2.第一个MyBatis程序
2.1搭建环境
搭建数据库(创建mysql表)
CREATE DATABASE `mybatis`;
USE `mybatis`;
CREATE TABLE `user`(
`id` INT(20) NOT NULL PRIMARY KEY,
`name` VARCHAR(30) DEFAULT NULL,
`pwd` VARCHAR(30) DEFAULT NULL
)ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO `user`(`id`,`name`,`pwd`) VALUES
(1,'名字1','123456'),
(2,'名字2','123456'),
(3,'名字3','123456')
新建maven项目(多个步骤)
1.新建一个普通的maven项目
2.删除src文件夹
3.导入依赖
<dependencies>
<!-- mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<!-- 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>
</dependency>
</dependencies>
2.2创建模块
在父项目下创建新module–普通的maven项目
编写mybatis核心配置文件
mybatis文档下载地址
https://www.jb51.net/books/716594.html#downintro2
创建xml文件
粘贴代码(记得!!!一定要删除配置文件中的注释!!!!!一定要记得!!)
<?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核心配置文件-->
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/qiu/dao/UserMapper.xml"/>
</mappers>
</configuration>
编写mybatis工具类
创建表格
package com.qiu.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;
//sqlSessionFactory
public class MyBatisUtils {
private static SqlSessionFactory sqlSessionFactory;//提升作用域
static{
try {
//获取sqlSessionFactory对象
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
//sqlSession完全包含了面向数据库执行SQL命令所需的所有方法
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
2.3编写代码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Lyz0kEef-1648915175427)(https 😕/img-blog.csdnimg.cn/3c91e20d47a24dcbbaf45433b5d2b019.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAcWR5b25lcw==,size_11,color_FFFFFF,t_70,g_se,x_16)]
实体类
package com.qiu.pojo;
//实体类
public class User {
private int id;
private String name;
private String pwd;
public User() {
}
public User(int id, String name, String pwd) {
this.id = id;
this.name = name;
this.pwd = pwd;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", pwd='" + pwd + '\'' +
'}';
}
}
dao接口
package com.qiu.dao;
import com.qiu.pojo.User;
import java.util.List;
public interface UserDao {
List<User> getUserList();
}
接口实现类
●namespace名字要和Dao/mapper接口名一致
●id:就是对应的namespace中的方法名; T
ID:就是对应的命名空间中的方法名;T
●resultType: Sql语句执行的返回值!
结果类型:sql语句执行的返回值!
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace=绑定一个对应的Dao/Mapper接口-->
<mapper namespace="com.qiu.dao.UserDao">
<!-- select查询语句-->
<select id="getUserList" resultType="com.qiu.pojo.User">
select * from mybatis.user
</select>
</mapper>
2.4测试
第一步检查核心配置文件有没有注册
<?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核心配置文件-->
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- 每一个Mapper.xml都需要在Mybatis核心配置文件中注册-->
<mappers>
<mapper resource="com/qiu/dao/UserMapper.xml"/>
</mappers>
</configuration>
第二步检查pom文件有没有文件无法导出的情况
<!-- maven由于他的约定大于配置,我们之后可以能遇到我们写的配置文件,无法被导出或者生效的问题,-->
<!-- 解决方案:-->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes> <include>**/*.properties</include>
<include>**/*.xml</include> </includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes> <include>**/*.properties</include>
<include>**/*.xml</include> </includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
最后一步创建一一对应的Test文件
最后放入以下测试类代码
package com.qiu.dao;
import com.qiu.pojo.User;
import com.qiu.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class UserDaoTest {
@Test
public void test(){
//第一步获得sqlsession对象
SqlSession sqlSession = MyBatisUtils.getSqlSession();
//第二步执行sqlsession,方式一:
UserDao userDao = sqlSession.getMapper(UserDao.class);
List<User> userList = userDao.getUserList();
for (User user : userList) {
System.out.println(user);
}
//关闭sqlsession
sqlSession.close();
//官方文档建议使用try catch finally保证关闭
}
}
3.增删改查实现(重点)
只需要改动这三个文件就可以实现增删改查
UserDao
package com.qiu.dao;
import com.qiu.pojo.User;
import java.util.List;
public interface UserDao {
//查询User所有的用户
List<User> getUserList();
//insert一个用户--增
int addUser(User user);
//删除用户----删
int deleteUser(int id);
//修改用户---改
int updateUser(User user);
//根据用户ID查询用户---查
User getUserById(int id);
}
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.qiu.dao.UserDao">
<select id="getUserList" resultType="com.qiu.pojo.User" >
select * from mybatis.user
</select>
<insert id="addUser" parameterType="com.qiu.pojo.User" >
insert into mybatis.user (id,name,pwd) value (#{id},#{name},#{pwd});
</insert>
<delete id="deleteUser" parameterType="int">
delete from mybatis.user where id=#{id};
</delete>
<update id="updateUser" parameterType="com.qiu.pojo.User">
update mybatis.user set name=#{name},pwd=#{pwd} where id=#{id};
</update>
<select id="getUserById" parameterType="int" resultType="com.qiu.pojo.User">
select * from mybatis.user where id=#{id}
</select>
</mapper>
UserDaoTest
package com.qiu.dao;
import com.qiu.pojo.User;
import com.qiu.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class UserDaoTest {
//注意点:增删改需要提交事务!!!!!!!!!!!!!!!!!!!!!!!!!
@Test
public void test(){
//第一步获得sqlsession对象
SqlSession sqlSession = MyBatisUtils.getSqlSession();
//第二步执行sqlsession,方式一:
UserDao userDao = sqlSession.getMapper(UserDao.class);
List<User> userList = userDao.getUserList();
for (User user : userList) {
System.out.println(user);
}
//关闭sqlsession
sqlSession.close();
//官方文档建议使用try catch finally保证关闭
}
@Test
public void addUser(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
int res = mapper.addUser(new User(4, "名字4", "123456"));
//判断是会否提交成功
if (res>0){
System.out.println("提交成功");
}
//提交事务
sqlSession.commit();
sqlSession.close();
}
@Test
public void deleteUser(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
mapper.deleteUser(4);
sqlSession.commit();
sqlSession.close();
}
@Test
public void updateUser(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
mapper.updateUser(new User(4,"赫赫","12313456"));
sqlSession.commit();
sqlSession.close();
}
@Test
public void getUserById(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
User user = mapper.getUserById(1);
System.out.println(user);
sqlSession.close();
}
}
4.Map和模糊查询拓展
4.1万能Map
UserDao
package com.qiu.dao;
import com.qiu.pojo.User;
import java.util.List;
import java.util.Map;
public interface UserDao {
//查询User所有的用户
List<User> getUserList();
//insert一个用户--增
int addUser(User user);
//删除用户----删
int deleteUser(int id);
//修改用户---改
int updateUser(User user);
//根据用户ID查询用户---查
User getUserById(int id);
//根据用户ID查询用户(用Map)
User getUserById2(Map<String,Object> map);
//用map增加多个用户
int addUser2(Map<String,Object> map);
}
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.qiu.dao.UserDao">
<select id="getUserList" resultType="com.qiu.pojo.User" >
select * from mybatis.user
</select>
<insert id="addUser" parameterType="com.qiu.pojo.User" >
insert into mybatis.user (id,name,pwd) value (#{id},#{name},#{pwd});
</insert>
<insert id="addUser2" parameterType="map">
insert into mybatis.user (id,name,pwd) values (#{userid},#{userName},#{passWord});
</insert>
<delete id="deleteUser" parameterType="int">
delete from mybatis.user where id=#{id};
</delete>
<update id="updateUser" parameterType="com.qiu.pojo.User">
update mybatis.user set name=#{name},pwd=#{pwd} where id=#{id};
</update>
<select id="getUserById" parameterType="int" resultType="com.qiu.pojo.User">
select * from mybatis.user where id=#{id};
</select>
<select id="getUserById2" parameterType="map" resultType="com.qiu.pojo.User">
select * from mybatis.user where id=#{helloId} and name=#{name};
</select>
</mapper>
UserDaoTest
package com.qiu.dao;
import com.qiu.pojo.User;
import com.qiu.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.HashMap;
import java.util.List;
public class UserDaoTest {
//注意点:增删改需要提交事务!!!!!!!!!!!!!!!!!!!!!!!!!
@Test
public void test(){
//第一步获得sqlsession对象
SqlSession sqlSession = MyBatisUtils.getSqlSession();
//第二步执行sqlsession,方式一:
UserDao userDao = sqlSession.getMapper(UserDao.class);
List<User> userList = userDao.getUserList();
for (User user : userList) {
System.out.println(user);
}
//关闭sqlsession
sqlSession.close();
//官方文档建议使用try catch finally保证关闭
}
@Test
public void addUser(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
int res = mapper.addUser(new User(4, "名字4", "123456"));
//判断是会否提交成功
if (res>0){
System.out.println("提交成功");
}
//提交事务
sqlSession.commit();
sqlSession.close();
}
@Test
public void addUser2(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
HashMap<String, Object> map = new HashMap<>();
map.put("userid",5);
map.put("userName","Hello");
map.put("passWord","156416");
mapper.addUser2(map);
sqlSession.commit();
sqlSession.close();
}
@Test
public void deleteUser(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
mapper.deleteUser(4);
sqlSession.commit();
sqlSession.close();
}
@Test
public void updateUser(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
mapper.updateUser(new User(4,"赫赫","12313456"));
sqlSession.commit();
sqlSession.close();
}
@Test
public void getUserById(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
User user = mapper.getUserById(1);
System.out.println(user);
sqlSession.close();
}
@Test
public void getUserById2(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
HashMap<String, Object> map = new HashMap<>();
map.put("helloId",1);
mapper.addUser2(map);
sqlSession.commit();
sqlSession.close();
}
}
4.2模糊查询
UserDao.java
//模糊查询
List<User> getUserLike(String value);
UserMapper.xml
<select id="getUserLike" resultType="com.qiu.pojo.User">
select * from mybatis.user where name like #{value}
</select>
UserDaoTest.java
//模糊查询
@Test
public void a(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
List<User> userLike = mapper.getUserLike("%李%");
for (User user : userLike) {
System.out.println(user);
}
sqlSession.commit();
sqlSession.close();
}
5.配置属性优化
环境配置
MyBatis可以配置成适应多种环境
不过要记住:尽管可以配置多个环境,但每个SqlSessionFactory实例只能选择-种环境。
属性
编写配置环境
db.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&;useUnicode=true&;characterEncoding=UTF-8
username=root
password=123456
mybatis-config.xml文件中严格按照顺序执行,
mybatis-config.xml引入外部文件
外部文件db.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8
username=root
password=123456
mybatis-config.xml
<?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="db.properties"/>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/qiu/dao/UserMapper.xml"/>
</mappers>
</configuration>
!!注意点:
如果两个文件拥有同一个字段,优先使用外部配置文件
6.配置之别名优化
方法一
mybatis-config.xml中第三顺位加入以下代码
<typeAliases>
<typeAlias type="com.qiu.pojo.User" alias="User"/>
</typeAliases>
UserMapper.xml中的参数类型就可以直接修改成别名
<select id="getUserList" resultType="User" >
select * from mybatis.user
</select>
方法二
另外:============================
除了上面的别名以外也可以指定一个包名, MyBatis 会在包名下面搜索需要的Java Bean,
比如官方文档给出的:如下
每一个在包 domain.blog 中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。 (通俗的话就是指定某一个包,包下的实体类的小写作为UserMapper.xml文件中语句的返回值类型)
官方示例:
<typeAliases>
<package name="domain.blog"/>
</typeAliases>
接下来举个例子:
mybatis-config.xml
<typeAliases>
<!-- <typeAlias type="com.qiu.pojo.User" alias="User"/>-->
<package name="com.qiu.pojo"/>
</typeAliases>
UserMapper.xml
<select id="getUserList" resultType="user" >
select * from mybatis.user
</select>
两种别名的区别
实体类比较少的时候用方法一
实体类比较多的时候用方法二
第一种可以自定义别名,
第二种则是用实体类名字的小写,如果第二种非要使用自定义的别名
则需要在实体类上添加注解@Alias
7.配置之映射器说明(mybatis-config.xml)
每次注册一个dao都需要注册mapper
方式一(使用xml文件,推荐)
举例:
<mappers>
<mapper resource="com/qiu/dao/UserMapper.xml"/>
</mappers>
!!方式二(使用类文件)
注意点!!!
接口和他的Mapper配置文件必须同名!
接口和他的Mapper配置文件必须在同一个包下!
<mappers>
<!-- <mapper resource="com/qiu/dao/UserMapper.xml"/>-->
<mapper class="com.qiu.dao.UserDao"/>
</mappers>
!!方式三(使用扫描包注入)
注意点!!与方式二相同的注意点
<mappers>
<!-- <mapper resource="com/qiu/dao/UserMapper.xml"/>-->
<!-- <mapper class="com.qiu.dao.UserDao"/>-->
<package name="com.qiu.dao"/>
</mappers>
8.ResultMap结果集映射
解决实体类属性名和数据库字段名不一致的问题
举例:
实体类有id、name、password
而UerMappper.xml中
<select id="getUserById" parameterType="int" resultType="com.qiu.pojo.User">
select * from mybatis.user where id=#{id};
</select>
这里的 select * from mybatis.user where id=#{id};相当于
select id,name,pwd from mybatis.user where id=#{id};
而实体类中的字段是password,所以查询不出来password
解决方法一:
<select id="getUserById" parameterType="int" resultType="com.qiu.pojo.User">
select id,name,pwd as password from mybatis.user where id=#{id};
</select>
解决方式二:resultMap
UserMapper.xml文件中添加结果集映射(相当于又开辟了一个盒子用userMap告诉人User实体类里面的各个属性代表什么字段)
<resultMap id="UserMap" type="User">
<result column="id" property="id"/>
<result column="name" property="name"/>
<result column="pwd" property="password"/>
</resultMap>
<select id="getUserList" resultType="UserMap" >
select * from mybatis.user
</select>
9.日志工厂
配置setting,看setting的就可以
注意点:不可以有空格,完全按照官方文档来,尤其是大小写不要写错了
以下的setting是标准的
<?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="db.properties"/>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<typeAliases>
<!-- <typeAlias type="com.qiu.pojo.User" alias="User"/>-->
<package name="com.qiu.pojo"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/qiu/dao/UserMapper.xml"/>
<!-- <mapper class="com.qiu.dao.UserMapper"/>-->
<!-- <package name="com.qiu.dao"/>-->
</mappers>
</configuration>
10.Log4j讲解
第一步–先导包
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
第二步创建资源文件
log4j.properties
第三步配置日志
<settings>
<!-- <setting name="logImpl" value="STDOUT_LOGGING"/>-->
<setting name="logImpl" value=""/>
</settings>
第四步去使用
1.在测试类中导入包为import org.apache.log4j.Logger;
2.日志对象,参数为当前类的class
使用↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
package com.qiu.dao;
import org.junit.Test;
import org.apache.log4j.Logger;
public class UserDaoTest {
static Logger logger=Logger.getLogger(UserDaoTest.class);
@Test
public void testLog4j(){
logger.info("info,jinru");
logger.debug("debug,jinru");
logger.error("error,jinru");
}
}
10.Limit实现分页
简单了解
语法: SELECT * from user limit startIndex, pagesize;(第一个参数是第几页,第二个参数是一页显示多少)
SELECT * from user 1imit 3;(之给定一个参数的时候那就是只从0开始显示到n)
#[0,n]
使用MyBatis实现分页,核心就是SQL
log4j.appender.stdout.layout.ConversionPattern错误
1旁边的空格去掉
log4j.appender.console.layout.ConversionPattern = %d{ABSOLUTE} %5p %c{1}:%L - %m%n
接口
//Limit查询
List<User> getUserLimit(Map<String,Integer> map);
Mapper.xml
第一种是我自己使用的
<select id="getUserLimit" parameterType="map" resultType="User">
select * from mybatis.user limit #{startIndex},#{pageSize};
</select>
第二种是自己要配置Map
<select id="getUserLimit" parameterType="map" resultMap="UserMap">
select * from mybatis.user limit #{startIndex},#{pageSize};
</select>
测试
@Test
public void getUserLimit(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
HashMap<String,Integer> map = new HashMap<>();
map.put("startIndex",0);
map.put("pageSize",1);
List<User> userLimit = mapper.getUserLimit(map);
for (User user : userLimit) {
System.out.println(user);
}
sqlSession.close();
}
11.RowBounds分页
RowBounds省略
分页插件
自行百度
12.使用注解开发
使用注解开发的好处就是直接省略了UserMapper.xml文件,就不需要了
思路:
1.UserMapper接口类中使用注解(编写sql语句)
但是记得如果没有自动导入包,需要在接口中手动导入
import org.apache.ibatis.annotations.Select;(这个是距离的那个例子)
2.测试类中直接调用方法即可
注解
package com.qiu.dao;
import com.qiu.pojo.User;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface UserMapper {
@Select("select * from mybatis.user")
List<User> getUser();
}
public class UserMapperTest {
@Test
public void test(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> user = mapper.getUser();
for (User user1 : user) {
System.out.println(user1);
}
sqlSession.close();
}
在配置文件中绑定接口
mybatis-config.xml中最后加入
<mappers>
<mapper class="com.qiu.dao.UserMapper"/>
</mappers>
注解的本质就是反射机制
底层:动态代理
13.Mybatis执行流程剖析
流程图自己百度
14.注解增删改查
自动提交设置
注解的增删改查
UsreMapper.java 接口
package com.qiu.dao;
import com.qiu.pojo.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
public interface UserMapper {
@Select("select * from mybatis.user")
List<User> getUser();
@Select("select * from user where id=#{id}")
User getUserById(@Param("id")int id2);
// @Select("select * from user where id=#{id}")
// User getUserById(int num);
@Insert("insert into user(id,name,pwd) values (#{id},#{name},#{pwd})")
int addUser(User user);
@Update("update user set name=#{name},pwd=#{pwd} where id=#{id}")
int upDate(User user);
@Delete("delete from user where id=#{uid}")
int delete(@Param("uid")int id);
}
测试
import com.qiu.dao.UserMapper;
import com.qiu.pojo.User;
import com.qiu.utils.MyBatisUtils;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
//测试类的名字绝对不能也叫Test,我尝试过了不好用,会挂
public class UserMapperTest {
@Test
public void test(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> user = mapper.getUser();
for (User user1 : user) {
System.out.println(user1);
}
sqlSession.close();
}
@Test
public void getUserById() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
System.out.println(mapper.getUserById(1));
sqlSession.close();
}
@Test
public void addUser() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.addUser(new User(5,"Hello","654321"));
sqlSession.close();
}
@Test
public void upDate() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.upDate(new User(3,"不好","4864896"));
sqlSession.close();
}
@Test
public void delete() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.delete(3);
sqlSession.close();
}
}
注意点
#{} 与${}区别
尽量使用#{} ,防止sql注入
15Lombok的使用
安装Lombok插件
导入Lombok的jar包
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
Lombok的注解使用(解释)
@Getter and @Setter
@FieldNameConstants
@ToString
@EqualsAndHashCode
@AllArgsConstructor, @RequiredArgsConstructor and @NoArgsConstructor
@Log, @Log4j, @Log4j2, @Slf4j, @XSlf4j, @CommonsLog, @JBossLog, @Flogger, @CustomLog
@Data
@Builder
@SuperBuilder
@Singular
@Delegate
@Value
@Accessors
@Wither
@With
@SneakyThrows
@val
@var
experimental @var
@UtilityClass
Lombok config system
在实体类中添加注解
//实体类
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String name;
private String pwd;
}
常用注解的解释
@Date---生成了get、set、tostring、hashcode,、equals-----最常用
@AllArgsConstructor---有参构造(生成之后必须加一个无参构造,有参加了之后无参构造就不会生成)
@NoArgsConstructor--无参构造
注意点
举例:如果get注解放在类上就生成类的所有get方法
如果放在方法上就生成当前方法的get方法
16.复杂查询环境搭建
测试环境搭建
1.导入lombok
2.新建实体类Teacher, Student
3.建立Mapper接口
4.建立Mapper .XML文件
5.在核心配置文件中绑定注册我们的Mapper接口或者文件! [方式很多, 随心选]
6.测试查询是否能够成功!
17.多对一的处理(查询绑定关联)
两张表自己建(随便一下,但是要有Styudent的tid和Teacher的id对应)
依次创建三个文件
package com.qiu.dao;
import com.qiu.pojo.Student;
import java.util.List;
public interface StudentMapper {
//查询所有学生的信息,并且查询对应的老师
public List<Student> getStudent();
public List<Student> getStudent2();
}
<?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.qiu.dao.StudentMapper">
<select id="getStudent2" resultMap="StudentTeacher2">
select s.id sid,s.name sname,t.name tname
from student s,teacher t
where s.tid=t.id;
</select>
<resultMap id="StudentTeacher2" type="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<association property="teacher" javaType="Teacher">
<result property="name" column="tname"/>
</association>
</resultMap>
<select id="getStudent" resultMap="StudentTeacher">
select * from student
</select>
<resultMap id="StudentTeacher" type="Student">
<result property="id" column="id"/>
<result property="name" column="name"/>
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>
<select id="getTeacher" resultType="Teacher">
select * from teacher where id=#{tid};
</select>
</mapper>
package com.qiu.dao;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import com.qiu.pojo.Teacher;
public interface TeacherMapper {
@Select("select * from teacher where id=#{tid}")
Teacher getTeacher(@Param("tid")int id);
}
学生实体类和老师实体类
package com.qiu.pojo;
import lombok.Data;
@Data
public class Student {
private int id;
private String name;
//学生需要关联老师
private Teacher teacher;
}
package com.qiu.pojo;
import lombok.Data;
@Data
public class Teacher {
private int id;
private String name;
}
18.一对多的处理
针对17章节修改实体类
package com.qiu.pojo;
import lombok.Data;
@Data
public class Student {
private int id;
private String name;
private int tid;
}
package com.qiu.pojo;
import lombok.Data;
import java.util.List;
@Data
public class Teacher {
private int id;
private String name;
//一个老师拥有多个学生
private List<Student> students;
}
修改两个文件
下面的两个方法第一个是按照结果嵌套处理
第二个是按照查询嵌套处理
package com.qiu.dao;
import com.qiu.pojo.Teacher;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface TeacherMapper {
//获取老师
// List<Teacher> getTeacher();
//获取指定老师下所有学生的信息和老师的信息
Teacher getTeacher(@Param("tid")int id);
Teacher getTeacher2(@Param("tid")int id);
}
<?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.qiu.dao.TeacherMapper">
<select id="getTeacher" resultMap="TeacherStudent">
select s.id sid,s.name sname,t.name tname,t.id tid
from student s,teacher t
where s.tid=t.id and t.id=#{tid}
</select>
<resultMap id="TeacherStudent" type="Teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
<collection property="students" ofType="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<result property="tid" column="tid"/>
</collection>
</resultMap>
<select id="getTeacher2" resultMap="TeacherStudent2">
select * from mybatis.teacher where id=#{tid};
</select>
<resultMap id="TeacherStudent2" type="Teacher">
<collection property="students" javaType="ArrayList" ofType="Student" select="getStudent" column="id"/>
</resultMap>
<select id="getStudent" resultType="Student">
select * from mybatis.student where tid=#{tid}
</select>
</mapper>
出现 1 字节的 UTF-8 序列的字节 1 无效。
删除TeacherMappper.xml文件中的中文注释,不论什么文件最好都不要注释
面试高频
Mysql引擎
InnoDB底层
索引
索引优化
19.动态sql
动态sql就是根据不同的条件生成不同的sql语句
搭建环境
创建一张表
创建基础工程
1.导包
lombok依赖(省略)
2.编写配置文件
3.编写实体类
package com.qiu.pojo;
import lombok.Data;
import java.util.Date;
@Data
public class Blog {
private String id;
private String title;
private String author;
private Date createTime;//属性名和字段名不一致
private int views;
}
package com.qiu.utils;
import org.junit.Test;
import java.util.UUID;
public class IDUtils {
public static String getID(){
return UUID.randomUUID().toString().replaceAll("-","");
}
@Test
public void test(){
System.out.println(IDUtils.getID());
}
}
4.编写实体类对应的Mappper接口和Mapper.xml文件
package com.qiu.dao;
import com.qiu.pojo.Blog;
public interface BlogMapper {
//插入数据
int addBook(Blog blog);
}
<?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.qiu.dao.BlogMapper">
<insert id="addBook" parameterType="blog">
insert into mybatis.blog(id,title,author,creat_time,views)
values (#{id},#{title},#{author},#{createTime},#{views});
</insert>
</mapper>
mybatis-config.xml文件中设置
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
测试类
import com.qiu.dao.BlogMapper;
import com.qiu.pojo.Blog;
import com.qiu.utils.IDUtils;
import com.qiu.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.Date;
public class MyTest {
@Test
public void test(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
Blog blog = new Blog();
blog.setId(IDUtils.getID());
blog.setTitle("MyBatis如此简单");
blog.setAuthor("CSDN");
blog.setCreateTime(new Date());
blog.setViews(9999);
mapper.addBook(blog);
blog.setId(IDUtils.getID());
blog.setTitle("MyBatis如此简单");
blog.setAuthor("CSDN");
blog.setCreateTime(new Date());
blog.setViews(9999);
mapper.addBook(blog);
blog.setId(IDUtils.getID());
blog.setTitle("MyBatis如此简单");
blog.setAuthor("CSDN");
blog.setCreateTime(new Date());
blog.setViews(9999);
mapper.addBook(blog);
sqlSession.close();
}
}
科普
1.就是数据库的字段例如是ac_bc那么实体类中的属性名可以命名为acBc
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
2.去除所有的波浪号等等的提示
@SuppressWarnings("all")
20.动态sql之if语句(多条件集合去查询)
where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。
BlogMapper接口
public interface BlogMapper {
//插入数据
int addBook(Blog blog);
//查询博客
List<Blog> queryBlogIF(Map map);
}
BlogMapper.xml
<insert id="addBook" parameterType="blog">
insert into mybatis.blog(id,title,author,creat_time,views)
values (#{id},#{title},#{author},#{createTime},#{views});
</insert>
<select id="queryBlogIF" parameterType="map" resultType="blog">
select * from blog
<where>
<if test="title!=null">
and title=#{title}
</if>
<if test="author!=null">
and author=#{author}
</if>
</where>
</select>
测试类
@Test
public void test(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
Blog blog = new Blog();
blog.setId(IDUtils.getID());
blog.setTitle("MyBatis如此简单");
blog.setAuthor("CSDN");
blog.setCreateTime(new Date());
blog.setViews(9999);
mapper.addBook(blog);
blog.setId(IDUtils.getID());
blog.setTitle("MyBatis如此简单");
blog.setAuthor("CSDN");
blog.setCreateTime(new Date());
blog.setViews(9999);
mapper.addBook(blog);
blog.setId(IDUtils.getID());
blog.setTitle("MyBatis如此简单");
blog.setAuthor("CSDN");
blog.setCreateTime(new Date());
blog.setViews(9999);
mapper.addBook(blog);
sqlSession.close();
}
@Test
public void queryBlogIF() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap map = new HashMap();
map.put("title","java如此简单");
map.put("author","CSDN");
List<Blog> blogs = mapper.queryBlogIF(map);
for (Blog blog : blogs) {
System.out.println(blog);
}
sqlSession.close();
}
21.动态sql语句常用标签
where、set(筛选条件修改 )
<update id="updateBlog" parameterType="map">
update mybatis.blog
<set>
<if test="title!=null">
title=#{title},
</if>
<if test="author!=null">
author=#{author}
</if>
</set>
where id=#{id}
</update>
@Test
public void updateBlog() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap map = new HashMap();
//因为语句写了根据id的位置修改标题和作者的动态修改,所以以下也可以注释掉其中一个只修改另外一个
map.put("id",1);
map.put("title","java如此简单");
map.put("author","CSDp");
mapper.updateBlog(map);
sqlSession.close();
}
choose(when、otherwise)(符合某一条件就开始查询)
解释:设置多个条件,按照条件顺序执行,从前往后执行,如果碰到符合条件的那个属性,就按照这个
条件执行查询,有点像 Java 中的 switch 语句,符合条件就退出~
官方解释:传入了 “title” 就按 “title” 查找,传入了 “author” 就按 “author” 查找的情形。若两者都没有传入,就返回标记为 featured 的 BLOG
List<Blog> queryBlogChoose(Map map);
<select id="queryBlogChoose" parameterType="map" resultType="blog">
select * from blog
<where>
<choose>
<when test="title!=null">
title=#{title}
</when>
<when test="author!=null">
and author=#{author}
</when>
<otherwise>
and views=#{views}
</otherwise>
</choose>
</where>
</select>
@Test
public void test3() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap map = new HashMap();
map.put("views",9999);
List<Blog> blogs = mapper.queryBlogChoose(map);
for (Blog blog : blogs) {
System.out.println(blog);
}
sqlSession.close();
}
where-set(选择id选择设置值)
//更新博客
int updateBlog(Map map);
<update id="updateBlog" parameterType="map">
update mybatis.blog
<set>
<if test="title!=null">
title=#{title},
</if>
<if test="author!=null">
author=#{author}
</if>
</set>
where id=#{id}
</update>
@Test
public void test4() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap map = new HashMap();
//因为语句写了根据id的位置修改标题和作者的动态修改,所以以下也可以注释掉其中一个只修改另外一个
map.put("id",1);
map.put("title","java如此简单");
map.put("author","CSDp");
mapper.updateBlog(map);
sqlSession.close();
}
注意点
where元索只会在至少有一个子元索的条件返回SQL子句的情况下才去插入“WHERE"子句。
而且,若语句的开头为"AND"或“OR",where 元素也会将它们去除。
22.动态sql之Foreach(不同id选择筛选查询)
//查询第1-2-3号记录的博客
List<Blog> queryBlogForeach(Map map);
<select id="queryBlogForeach" parameterType="map" resultType="blog">
select * from mybatis.blog
<where>
-- 1=1 and
<foreach collection="ids" item="id" open="(" close=")" separator="or">
id=#{id}
</foreach>
</where>
</select>
@Test
public void test5(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap map = new HashMap();
ArrayList<Integer> ids = new ArrayList<Integer>();
ids.add(1);
// ids.add(2);
// ids.add(3);
map.put("ids",ids);
List<Blog> blogs = mapper.queryBlogForeach(map);
for (Blog blog : blogs) {
System.out.println(blog);
}
sqlSession.close();
}
23.缓存
查询一次的结果给它缓存起来
读写分离、主从复制
什么样子的数据可以进行缓存–经常查询而不经常改变的数据
一级缓存:sqlSession,默认是开启的
二级缓存:namespace,需要手动开启和配置
一级缓存
一级缓存只有在一次sqlSession之间有效
测试在一个session中查询两次记录
package com.qiu.dao;
import com.qiu.pojo.User;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface UserMapper {
//根据id查询用户
User queryUserById(@Param("id") int id);
}
<?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.qiu.dao.UserMapper">
<select id="queryUserById" resultType="user">
select * from user where id=#{id}
</select>
</mapper>
import com.qiu.dao.UserMapper;
import com.qiu.pojo.User;
import com.qiu.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
public class MyTest {
@Test
public void queryUserById(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.queryUserById(1);
System.out.println(user);
System.out.println("===================================");
User user1 = mapper.queryUserById(1);
System.out.println(user1);
sqlSession.close();
}
}
缓存失效的情况
1.查询两个不同的id就需要两次session
2.查询一次id,中间如果修改了数据库(update),那之后查询同一id也会失效
3.查询不同的Mapper.xml
4.手动清理缓存
sqlSession.clearCache();
二级缓存
官方解释:默认情况下,只启用了本地的会话缓存,它仅仅对一个会话中的数据进行缓存。要启用全局的二 级缓存,只需要在你的SQL映射文件中添加一行:
开启全局缓存
1.一个会话查询一条数据,这个数据就会被放在当前会话的一-级缓存中;
2.如果当前会话关闭了,这个会话对应的一-级缓存就没了;但是我们想要的是,会话关闭了,- -级缓存中的
数据被保存到二级缓存中;
3.新的会话查询信息,就可以从二级缓存中获取内容;
4.不同的mapper查出的数据会放在自己对应的缓存(map) 中;
=========================================
!!!开启全局缓存步骤:
1.配置文件加入
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
2.UserMapper.xml文件
useCache="true"开启二级缓存
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
<select id="queryUserById" resultType="user" useCache="true">
select * from user where id=#{id}
</select>
============
3.测试
import com.qiu.dao.UserMapper;
import com.qiu.pojo.User;
import com.qiu.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
public class MyTest {
@Test
public void queryUserById(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
SqlSession sqlSession2 = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.queryUserById(1);
System.out.println(user);
sqlSession.close();
UserMapper mapper2 = sqlSession.getMapper(UserMapper.class);
User user2 = mapper2.queryUserById(1);
System.out.println(user2);
sqlSession2.close();
}
}
小结:
只要开启了二_级缓存,在同- -个Mapper下就有效
所有的数据都会先放在一级缓存中;
只有当会话提交,或者关闭的时候,才会提交到二级缓存中
二级缓存序列化实体类
@Data
public class User implements Serializable {
private int id;
private String name;
private String pwd;
}
24.自定义缓存Ehcache(了解即可)
第一步- 导入依赖
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.2.2</version>
</dependency>
第二步–Mapper.xml
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
第三步–添加资源配置
百度
工作中用Redis做缓存
N.补充
默认开启提交事务
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession(true);
}