Mybatis相关笔记(自己忘了看的)
- MyBatis 是⼀款优秀的持久层框架,它⽀持定制化 SQL、存储过程以及⾼级映射。MyBatis 避免了⼏乎所有的 JDBC 代码和⼿动设置参数以及获取结果集。MyBatis 可以使⽤简单的 XML 或注解来配置和映射原⽣信息,将接⼝和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录
一、配置文件的方式:
1.pom.xml文件的相关依赖
<dependencies>
<!-- 添加驱动包(mysql.jar和mybatis的jar包)-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
<!-- 单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.7.1</version>
</dependency>
<!-- log4j依赖-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<!-- 分页需要的jar-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.6</version>
</dependency>
</dependencies>
2.配置mybatis.xml文件(连接数据库的配置⽂件)
作用:
(1).指定连接数据库的url,username,password,driver
(2).由框架⾃动获取连接
(3).指定了事务的管理对象
<?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>
<!-- 给类取别名-->
<typeAliases>
<!-- 1.一个一个的指定别名-->
<!-- <typeAlias type="com.yx.bean.Student" alias="student"></typeAlias>-->
<!-- 2.通过包来表示,类名就是实体类的首字母小写的全名(针对多个类时)-->
<package name="com.yx.bean"/>
</typeAliases>
<!-- 分页插件-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
</plugin>
</plugins>
<!-- 连接数据库的环境 default="development" 环境的id-->
<environments default="a1">
<environment id="a1">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!-- 解决数据库传入值过程乱码问题 ?useUnicode=true&characterEncoding=utf-8-->
<property name="url" value="jdbc:mysql://localhost:3306/spring?useUnicode=true&characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="123"/>
</dataSource>
</environment>
<environment id="a2">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/spring?useUnicode=true&characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="123"/>
</dataSource>
</environment>
</environments>
<!-- 指定maper⽂件的路径(maven项⽬从resources源⽂件夹下找资源)-->
<mappers>
<mapper resource="StudentMapper.xml"/>
<mapper resource="StudentMapper2.xml"/>
<mapper resource="GradeMapper.xml"/>
</mappers>
</configuration>
3.创建实体类(Student)
public class Student {
private int id;
private String name;
private String classBj;
private String stept;}
4.创建dao层
这里创建的是方法,具体的实现在StudentMapper.xml中进行相关sql的使用
package com.yx.dao;
import com.yx.bean.Student;
import java.util.List;
import java.util.Map;
public interface StudentDao1 {
//定义增删改查的方法
public List<Student> getAll();
//查询单个
public Student getOne();
//新增student
public int insertStu(Student student);
//新增传入多个参数时用map集合封装
public int insertStu2(Map map);
//查询最大值和最小值,平均值
public Map getMMA();
}
5.创建实现dao层接口的配置文件
<?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">
<!-- //dao类的全限定名-->
<mapper namespace="com.yx.dao.StudentDao1">
<!-- resultMap 定义实体类中属性与数据库中列名不一致时做对应-->
<resultMap id="res" type="com.yx.bean.Student">
<!-- property="stept" 实体类中的属性 column="stept"对应表中的列名-->
<result property="stept" column="stept"></result>
</resultMap>
<!-- id对应方法名 student:是在mybatis.xml文件中给com.yx.bean.Student取的别名-->
<select id="getAll" resultMap="res">
select *from student
</select>
<select id="getOne" parameterType="int" resultType="com.yx.bean.Student">
select *from student where id=#{id}
</select>
<!-- 增删改 返回的是行数不用配置resultType-->
<!-- 1.增加-->
<!-- 直接传入对象 useGeneratedKeys="true" keyProperty="id" 可以得到自增的id值并赋值到Student 的id属性上-->
<insert id="insertStu" parameterType="com.yx.bean.Student" useGeneratedKeys="true" keyProperty="id" >
insert into student(name,classbj,stept) values (#{name},#{classBj},#{stept})
</insert>
<!-- 传入map集合 (#{name},#{classBj},#{stept}) 读取的是map的key值-->
<insert id="insertStu2" parameterType="com.yx.bean.Student" >
insert into student(name,classbj,stept) values (#{name},#{classBj},#{stept})
</insert>
<!-- 查询最大值和最小值,平均值-->
<select id="getMMA" resultType="map">
select avg(id) avg,MAX(id) max,MIN(id) min from student
</select>
</mapper>
6.创建获取SqlSession的实现工具类(SqlSessionUtil.java)
- 介绍:ThreadLocal是什么呢?其实ThreadLocal并⾮是⼀个线程的本地实现版本,它并不是⼀个Thread,⽽是threadlocalvariable(线程局部变量)。也许把它命名为ThreadLocalVar更加合适。线程局部变量(ThreadLocal)其实的功⽤⾮常简单,就是为每⼀个使⽤该变量的线程都提供⼀个变量值的副本,是Java中⼀种较为特殊的线程绑定机制,是每⼀个线程都可以独⽴地改变⾃⼰的副本,⽽不会和其它线程的副本冲突。
package com.yx.util;
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.Reader;
public class SqlSessionUtil {
private static ThreadLocal<SqlSession> threadLocal=new ThreadLocal<SqlSession>();
private static SqlSessionFactory sqlSessionFactory;
static {
try {
Reader resourceAsReader = Resources.getResourceAsReader("mybatis.xml");
sqlSessionFactory=new SqlSessionFactoryBuilder().build(resourceAsReader);
} catch (IOException e) {
e.printStackTrace();
}
}
//开启
public static SqlSession getSession(){
SqlSession sqlSession = threadLocal.get();
if (sqlSession == null){
sqlSession=sqlSessionFactory.openSession();
threadLocal.set(sqlSession);
}
return sqlSession;
}
//关闭
public static void closeSession(){
SqlSession sqlSession = threadLocal.get();
if (sqlSession!=null){
sqlSession.close();
threadLocal.remove();//移除线程中内容
}
}
}
7.创建测试类做数据的增删改查
package com.yx.test;
import com.yx.bean.Student;
import com.yx.dao.StudentDao1;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.RowBounds;
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 java.io.IOException;
import java.io.Reader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class Test1 {
/**
* 过程简化
* */
@Test
public void testJH(){
try {
//1.得到SqlSession对象
Reader reader = Resources.getResourceAsReader("mybatis.xml");
SqlSession sqlSession = new SqlSessionFactoryBuilder().build(reader).openSession();
//2.通过接口对象反射的方式得到方法
StudentDao1 studentDao = sqlSession.getMapper(StudentDao1.class);
List<Student> all = studentDao.getAll();
for (Student student : all) {
System.out.println(student);
}
//3.关闭资源
reader.close();
sqlSession.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 1.1.查询所有
* */
@Test
public void test01(){
try {
//1.加载配置文件
Reader reader = Resources.getResourceAsReader("mybatis.xml");
//2.得到sqlSessionFactoryBuilder
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
// SqlSessionFactory build = builder.build(reader);
SqlSessionFactory build = builder.build(reader,"a2");//用于切换数据源
//3.得到SqlSession
SqlSession sqlSession = build.openSession();
//4操作sql
List<Student> students = sqlSession.selectList("com.yx.dao.StudentDao1.getAll");//方法参数是配调取的sql的完整路径=namespace+id
//5.遍历
for (Student student : students) {
System.out.println(student);
}
//6.关闭资源
reader.close();
sqlSession.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 1.2.查询id
* */
@Test
public void test02(){
try {
//1.加载配置文件
Reader reader = Resources.getResourceAsReader("mybatis.xml");
//2.得到sqlSessionFactoryBuilder
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
// SqlSessionFactory build = builder.build(reader);
SqlSessionFactory build = builder.build(reader,"a2");//用于切换数据源
//3.得到SqlSession
SqlSession sqlSession = build.openSession();
//4操作sql
Student student = sqlSession.selectOne("com.yx.dao.StudentDao1.getOne",2);//方法参数是配调取的sql的完整路径=namespace+id
System.out.println(student);
//6.关闭资源
reader.close();
sqlSession.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 2.1 通过对象新增
* */
@Test
public void test03(){
try {
//1.加载配置文件
Reader reader = Resources.getResourceAsReader("mybatis.xml");
//2.得到sqlSessionFactoryBuilder
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
// SqlSessionFactory build = builder.build(reader);
SqlSessionFactory build = builder.build(reader,"a2");//用于切换数据源
//3.得到SqlSession
SqlSession sqlSession = build.openSession();
//4操作sql
Student student1 = new Student();
student1.setName("王王");
student1.setClassBj("178");
student1.setStept("java");
int insert = sqlSession.insert("com.yx.dao.StudentDao1.insertStu",student1);//方法参数是配调取的sql的完整路径=namespace+id
sqlSession.commit();
System.out.println("id="+student1.getId());
System.out.println(insert);
//6.关闭资源
reader.close();
sqlSession.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
*2.2通过参数添加 参数要封装到map集合中
* */
@Test
public void test04(){
try {
//1.加载配置文件
Reader reader = Resources.getResourceAsReader("mybatis.xml");
//2.得到sqlSessionFactoryBuilder
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
// SqlSessionFactory build = builder.build(reader);
SqlSessionFactory build = builder.build(reader,"a2");//用于切换数据源
//3.得到SqlSession
SqlSession sqlSession = build.openSession();
//4操作sql
Map map = new HashMap<String,String>();
map.put("name","王伟2");
map.put("classBj","186");
map.put("stept","大数据");
int insert = sqlSession.insert("com.yx.dao.StudentDao1.insertStu",map);//方法参数是配调取的sql的完整路径=namespace+id
sqlSession.commit();
System.out.println(insert);
//6.关闭资源
reader.close();
sqlSession.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
*1.3查询最大值,最小值,平均值,返回的是表头与数据的键值对
* */
@Test
public void test05(){
try {
//1.加载配置文件
Reader reader = Resources.getResourceAsReader("mybatis.xml");
//2.得到sqlSessionFactoryBuilder
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
// SqlSessionFactory build = builder.build(reader);
SqlSessionFactory build = builder.build(reader,"a2");//用于切换数据源
//3.得到SqlSession
SqlSession sqlSession = build.openSession();
//4操作sql
Map map = sqlSession.selectOne("com.yx.dao.StudentDao1.getMMA");//方法参数是配调取的sql的完整路径=namespace+id
//5.遍历
Set<Map.Entry> set = map.entrySet();
for (Map.Entry entry : set) {
System.out.println(entry);
}
//6.关闭资源
reader.close();
sqlSession.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
8 .log4j.properties的配置
- 用于显示SQL语句以及相关的日志
#日志级别
log4j.rootLogger=DEBUG, Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.java.sql.ResultSet=INFO
log4j.logger.org.apache=INFO
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
二、注解的方式
1.pom.xml文件的配置
org.mybatis mybatis 3.4.6 mysql mysql-connector-java 8.0.23 junit junit 4.12 test org.junit.jupiter junit-jupiter-api 5.7.1 org.slf4j slf4j-api 1.7.30 org.slf4j slf4j-log4j12 1.7.12 log4j log4j 1.2.12 com.github.pagehelper pagehelper 5.1.6 <dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.2</version>
</dependency>
</dependencies>
2.mybatis.xml文件的配置
- 修改下方的语句即可
<mappers>
<mapper class="com.yx.dao.StudentDao3"></mapper>
</mappers>
3.注解的使用
- 所有的SQL语句需要传入参数的,多个使用map集合传递,在SQL语句中的占位符就相当于是map集合的key值使用对象传递时,对象的属性名要与之对应。
//增加的方式,直接使用@Insert(里面是SQL语句,与配置文件类似)
@Insert(“insert into student(name,classbj,stept) values(#{name},#{classBj},#{stept})”)//查询使用:@Select() @Select("select *from student") //更新使用:@Update() @Update("update student set name=#{name},classbj=#{classBj},stept=#{stept} where id=#{id}") //删除使用:@Delete() @Delete("delete from student where id=#{id}") //@Param("")---可以实现参数的对应(可以实现不使用集合的方式随意的传参) @Insert("insert into student(name,classbj,stept) values(#{name},#{bj},#{zy})") @Options(useGeneratedKeys = true,keyProperty = "id")//获取新增数据id public int insertStu3(@Param("name") String name,@Param("bj") String classBj,@Param("zy") String stept);
@Insert(“insert into student(name,classbj,stept) values(#{name},#{classBj},#{stept})”)
@Options(useGeneratedKeys = true,keyProperty = “id”,useCache = true,flushCache = Options.FlushCachePolicy.FALSE,timeout = 10000)//获取新增数据id
public int insertStu(Student student);
@Options(useCache = true,flushCache = Options.FlushCachePolicy.FALSE,timeout = 10000)
@Select("select *from student")
@Results({
@Result(column = "name",property = "name")
})
public List<Student> findAll();
@Options(useCache = true,flushCache = Options.FlushCachePolicy.FALSE,timeout = 10000)
@Update("update student set name=#{name},classbj=#{classBj},stept=#{stept} where id=#{id}")
public int updateStu(Student student);
@Options(useCache = true,flushCache = Options.FlushCachePolicy.FALSE,timeout = 10000)
@Delete("delete from student where id=#{id}")
public int deleteStu(int id);
@Insert("insert into student(name,classbj,stept) values(#{name1},#{classBj1},#{stept1})")
@Options(useGeneratedKeys = true,keyProperty = "id")//获取新增数据id
public int insertStu2(Map map);
@Insert("insert into student(name,classbj,stept) values(#{name},#{bj},#{zy})")
@Options(useGeneratedKeys = true,keyProperty = "id")//获取新增数据id
public int insertStu3(@Param("name") String name,@Param("bj") String classBj,@Param("zy") String stept);
4.测试类的实现
```xml
```xml
```java
package com.yx;
import com.yx.bean.Student;
import com.yx.dao.StudentDao3;
import com.yx.util.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Test01 {
@Test
public void test01(){
SqlSession session = SqlSessionUtil.getSession();
StudentDao3 mapper = session.getMapper(StudentDao3.class);
Student student = new Student();
student.setName("小华2");
student.setStept("python");
student.setClassBj("184");
int i = mapper.insertStu(student);
System.out.println(i);
System.out.println("id="+student.getId());
session.commit();//提交事务
SqlSessionUtil.closeSession();
}
@Test
public void test02(){
SqlSession session = SqlSessionUtil.getSession();
StudentDao3 mapper = session.getMapper(StudentDao3.class);
List<Student> students = mapper.findAll();
for (Student student : students) {
System.out.println(student);
}
SqlSessionUtil.closeSession();
}
@Test
public void test03(){
SqlSession session = SqlSessionUtil.getSession();
StudentDao3 mapper = session.getMapper(StudentDao3.class);
Student student = new Student();
student.setId(2);
student.setName("小华3");
student.setStept("大数据");
student.setClassBj("183");
int i = mapper.updateStu(student);
session.commit();
System.out.println("i="+i);
SqlSessionUtil.closeSession();
}
@Test
public void test04(){
SqlSession session = SqlSessionUtil.getSession();
StudentDao3 mapper = session.getMapper(StudentDao3.class);
int i = mapper.deleteStu(20);
session.commit();
System.out.println("i="+i);
SqlSessionUtil.closeSession();
}
/**
* 集合方式增加(分开添加多个数据)
* */
@Test
public void test011(){
SqlSession session = SqlSessionUtil.getSession();
StudentDao3 mapper = session.getMapper(StudentDao3.class);
Map map = new HashMap();
map.put("name1","小华44");
map.put("classBj1","167");
map.put("stept1","java");
int i = mapper.insertStu2(map);
session.commit();
System.out.println("i="+i);
SqlSessionUtil.closeSession();
}
/**
* 参数方式添加
* */
@Test
public void test012(){
SqlSession session = SqlSessionUtil.getSession();
StudentDao3 mapper = session.getMapper(StudentDao3.class);
int i = mapper.insertStu3("小华阿虎","188","大数据");
session.commit();
System.out.println("i="+i);
SqlSessionUtil.closeSession();
}
}
5.Lombok插件的使用
需要先安装插件
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.2</version>
</dependency>
</dependencies>
- lombok的使⽤
@Data 注解在类上;提供类所有属性的 getting 和 setting ⽅法,此外还提供了equals、canEqual、
hashCode、toString ⽅法
@Setter :注解在属性上;为属性提供 setting ⽅法
@Getter :注解在属性上;为属性提供 getting ⽅法
@Log4j :注解在类上;为类提供⼀个 属性名为log 的 log4j ⽇志对象
@NoArgsConstructor :注解在类上;为类提供⼀个⽆参的构造⽅法
@AllArgsConstructor :注解在类上;为类提供⼀个全参的构造⽅法
@Cleanup : 可以关闭流
@Builder : 被注解的类加个构造者模式
@Synchronized : 加个同步锁
@SneakyThrows : 等同于try/catch 捕获异常
@NonNull : 如果给参数加个这个注解 参数为null会抛出空指针异常
@Value : 注解和@Data类似,区别在于它会把所有成员变量默认定义为private final修饰,并且不会⽣
成set⽅法。
@ToString 重写toString()⽅法