1:idea数据库的链接
2:第一个mybatis流程
1:maven所需要的包和xml拦截器进行拦截扫描
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>mybatis-study</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
//子工程
<modules>
<module>mybatis-01-hello</module>
<module>mybatis-02-baseKnowledge</module>
</modules>
<dependencies>
<!-- mysql-->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- mybatis-->
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<!-- junit-->
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- 实体类自动生成get set和构造方法和toString -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
</dependencies>
<!-- 拦截识别xml用的 -->
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
2:工具类:进行获取sqlSession
package com.atshikai.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 ----》sqlSession
public class MyBatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
// 使用mybatis的第一步:获取sqlSessionFactory工厂
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
// 相当于getConnection注解的时候使用
public static SqlSession getSqlSession(){
// 改为true是自动提交事务
return sqlSessionFactory.openSession(true);
}
}
关于sqlsession
1一旦创建SqlSessionFactory,SqlSessionFactoryBuilder就会被销毁—局部变量
2 SqlSessionFactory:可以想象为:数据库连接池,一旦创建在运行期间一直存在单例模式
3 SqlSession连接到连接池的一个请求,不能被共享,用完之后赶紧关闭
4一个mappe就相当于一个具体的业务!!!
3: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>
<!--1引入配置文件-->
<properties resource="db.properties"/>
<!--2设置日志文件-->
<settings>
<!-- 解决数据库和实体类名不一致问题(严格的驼峰式命名) 数据库g_shi==实体类gShi-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!--需要导入包进行操作-->
<!-- <setting name="logImpl" value="LOG4J"/>-->
</settings>
<!-- 3 类名首字母小写的去起别名,然后供返回值使用-->
<typeAliases>
<package name="com.atshikai.pojo"/>
</typeAliases>
<!--4环境配置-->
<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>
<!-- 5 注册一下mapper 进行映射-->
<mappers>
//直接绝对路径查找
<!--<mapper resource="com/atshikai/dao/userMapper.xml"/>-->
//下面两个需要在同一个路径下才可以
<mapper class="com.atshikai.dao.UserMapper"/>
<!-- <package name="com.atshikai.dao"/>-->
</mappers>
</configuration>
4:实体类
package com.atshikai.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data //get,set
@NoArgsConstructor //无参构造
@AllArgsConstructor //有参构造
public class User {
private int id;
private String name;
private String pwd;
}
Logj打印日志的生成
5:实体类接口
package com.atshikai.dao;
import com.atshikai.pojo.User;
import java.util.List;
import java.util.Map;
public interface UserMapper {
List<User> getUserList();
//通过id查询
User selectById(int id);
// 模糊查询
List<User> selectIgnore(String name);
// 增
int insertUser(User user);
// 使用map进行添加User对象
int addUser(Map<String,Object> map);
// 删
int deleteUser(int id);
// 改
int updateUser(User user);
}
6:实体类接口(写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">
<mapper namespace="com.atshikai.dao.UserMapper">
<select id="getUserList" resultType="com.atshikai.pojo.User">
select * from mybatis.user
</select>
<select id="selectById" resultType="com.atshikai.pojo.User" parameterType="int">
select * from mybatis.user where id=#{id};
</select>
<!-- 模糊查询-->
<select id="selectIgnore" parameterType="String" resultType="com.atshikai.pojo.User">
select * from mybatis.user where name like #{value}
</select>
<insert id="insertUser" parameterType="com.atshikai.pojo.User">
insert into mybatis.user(id,name,pwd) values(#{id},#{name},#{pwd});
</insert>
<!-- 使用map进行添加对象 传参数的时候应该用 #{} 不是${}-->
<insert id="addUser" parameterType="java.util.Map">
insert into mybatis.user values(#{id},#{name},#{pwd});
</insert>
<delete id="deleteUser" parameterType="int">
delete from mybatis.user where id=#{id};
</delete>
<update id="updateUser" parameterType="com.atshikai.pojo.User">
update mybatis.user set name=#{name},pwd=#{pwd} where id=#{id};
</update>
</mapper>
7:进行测试
import com.atshikai.dao.UserMapper;
import com.atshikai.pojo.User;
import com.atshikai.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MyTest {
@Test
public void testSelect(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = mapper.getUserList();
for (User user:userList){
System.out.println(user);
}
sqlSession.commit();
sqlSession.close();
}
@Test
public void testInsert(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
int i = mapper.insertUser(new User(4, "盖世凯5", "666"));
System.out.println(i);
sqlSession.commit();
sqlSession.close();
}
// 用map进行添加用户
@Test
public void testMapAdd(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Map<String,Object> map=new HashMap<String, Object>();
map.put("id",7);
map.put("name","张建");
map.put("pwd","888");
mapper.addUser(map);
sqlSession.commit();
sqlSession.close();
}
// 模糊查询
@Test
public void selectIgnore(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> users = mapper.selectIgnore("%盖%");
for(User user:users){
System.out.println(user);
}
sqlSession.commit();
sqlSession.close();
}
@Test
public void selectById(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.selectById(2);
System.out.println(user);
sqlSession.commit();
sqlSession.close();
}
@Test
public void deleteUser(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
int i = mapper.deleteUser(2);
System.out.println(i);
sqlSession.commit();
sqlSession.close();
}
@Test
public void updateUser(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
int i = mapper.updateUser(new User(1, "凯凯", "888"));
System.out.println(i);
sqlSession.commit();
sqlSession.close();
}
}
3:写sql#() 和${}的区别
都可以使用但是#{} 可以防止sql注入,更安全
4resultType和resultMap
resultType
1:resultType可以把查询结果封装到pojo类型中,但必须pojo类的属性名和查询到的数据库表的字段名一致。
2:如果sql查询到的字段与pojo的属性名不一致,则需要使用resultMap将字段名和属性名对应起来,进行手动配置封装,将结果映射到pojo中
resultMap
resultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。
5:多表查询(一对多,多对一)
总结:注意点
多对一(多个学生对应一个老师)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atshikai.dao.StudentMapper">
<!-- 按照结果嵌套处理 resultMap关联外部的sql-->
<select id="getStudents1" resultMap="studentMap1">
select s.id sid,s.name sname,t.id,t.name tname
from student s,teacher t
where s.tid=t.id;
</select>
<resultMap id="studentMap1" type="student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<!-- 对于复杂的查询,我们需要单独处理,对象:association 集合:collection-->
<association property="teacher" javaType="Teacher">
<result property="id" column="id"/>
<result property="name" column="tname"/>
</association>
</resultMap>
<!-- ================================================================ -->
<!--
思路:1 查询所有学生的信息,2 根据查出来的学生id,寻找对应的老师
-->
<resultMap id="studentMap" type="student">
<result property="id" column="id"/>
<result property="name" column="name"/>
<!-- 对于复杂的查询,我们需要单独处理,对象:association 集合:collection-->
<association property="teacher" column="tid"
javaType="Teacher" select="getTeacher"/>
</resultMap>
<select id="getStudents" resultMap="studentMap">
select * from student
</select>
<select id="getTeacher" resultType="teacher">
select * from teacher where id=#{Tid};
</select>
</mapper>
一对多(一个老师对应多个学生)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atshikai.dao.TeacherMapper">
<!-- 子查询-->
<select id="getTeachers1" resultMap="teacherMap1">
select * from teacher t where t.id=#{Tid}
</select>
<resultMap id="teacherMap1" type="Teacher">
<result property="id" column="id"/>
<result property="name" column="name"/>
<collection property="students" ofType="Student"
javaType="ArrayList" select="queryStudentByTid" column="id"/>
</resultMap>
<select id="queryStudentByTid" resultType="Student">
select * from student where tid=#{Tid}
</select>
<!-- =====================================================-->
<!-- 联合查询-->
<select id="getTeachers" resultMap="teacherMap">
select s.id sid,s.name sname, t.id tid,t.name tname
from student s,teacher t
where s.tid=tid and tid=#{Tid}
</select>
<resultMap id="teacherMap" 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>
</mapper>
5:动态sql语句
对于自动生成的id类
package com.atshikai.utils;
import java.util.UUID;
public class IdUtils {
public static String getId(){
return UUID.randomUUID().toString().replace("-","");
}
}
- sql片段:查询include(尽量include中不使用where)
<sql id="if-title-author">
<if test="title!=null">
and title=#{title}
</if>
<if test="author!=null">
and author=#{author}
</if>
</sql>
<select id="queryBlogIf" parameterType="map" resultType="blog">
select * from blog where 1=1
<include refid="if-title-author"></include>
</select>
- 查询where,choose,when(where嵌套可以智能的去掉无用的and,如果where嵌套的没有东西,不影响代码执行)
<select id="queryBlogChoose" parameterType="map" resultType="blog">
select * from blog
<where>
<choose>
<when test="title!=null">
and title=#{title}
</when>
<when test="author!=null">
and author=#{author}
</when>
<otherwise>
views=#{views}
</otherwise>
</choose>
</where>
</select>
- 更新set(可以智能的去掉不需要的,如果set中没有东西,就会出错)
<update id="updateBlog" parameterType="map">
update blog
<set>
<if test="title!=null">
title=#{title},
</if>
<if test="author!=null">
author=#{author}
</if>
</set>
where id=#{id}
</update>
- 查询forEach
<select id="queryByIDs" parameterType="map" resultType="blog">
select * from blog
<where>
<foreach collection="ids" item="id"
open="(" separator="or" close=")">
id=#{id}
</foreach>
</where>
</select>
6:mybatis一级二级缓存
详细看狂神27,28,29集
小结:
一级缓存:相当于一个map
缓存失效的情况:
1查询不同的东西;
2增删改操作,可能会改变之前的操作,所以必定刷新
3查询不同的Mapper.xml
4手动清理缓存(一级缓存默认是开启的,关不掉)sqlSession.clearCache();
二级缓存
就是我(一级缓存)死了,然后吧缓存遗传给你(二级缓存)