Mybatis笔记
三层对应的处理框架
界面层—servlet—springmvc (框架)
业务逻辑层—service类–spring(框架)
数据访问层—dao类–mybatis(框架)
Mybatis的特性
- MyBatis是支持定制化SQL、存储过程以及高级映射的优秀的持久层框架,MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集
- MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录
- MyBatis是—个半自动的ORM (Object Relation Mapping)框架
创建maven工程
1.打包方式:jar包
2.配置mybais-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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/book"/>
<property name="username" value="root"/>
<property name="password" value="yz"/>
</dataSource>
</environment>
</environments>
<!--创建映射关系-->
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>
3.创建mapper接口,对应的实体类。
4.创建映射文件
1、映射文件的命名规则:
表所对应的实体类的类名+Mapper,xml
例如:表t_user,映射的实体类为User,所对应的映射文件为UserMapper.xml因此一个映射文件对应一个实体类,对应一张表的操作
MyBatis映射文件用于编写SQL,访问以及操作表中的数据
MyBatis映射文件存放的位置是src/main/resources/mappers目录下
2、MyBatis中可以面向接口操作数据,要保证两个—致:
a>mapper接口的全类名和映射文件的命名空间(namespace)保持─致
b>mapper接口中方法的方法名和映射文件中编写SQL的标签的id属性保持─致
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uaFUVZFH-1646900631746)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220307145551332.png)]
//UserMapper
package com.mapper;
public interface UserMapper {
/**
* a>mapper接口的全类名和映射文件的命名空间(namespace)保持─致
*
* b>mapper接口中方法的方法名和映射文件中编写SQL的标签的id属性保持一致
*/
//插入方法
int insertUser();
}
//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">
<!--namespace与Mapper接口路径保持一致-->
<mapper namespace="com.mapper.UserMapper">
<!--id与接口的抽象方法保持一致-->
<insert id="insertUser">
insert into t_user values(null,"Jack","3321","163@qq.com")
</insert>
</mapper>
//核心配置文件
<?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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/book"/>
<property name="username" value="root"/>
<property name="password" value="yz"/>
</dataSource>
</environment>
</environments>
<!--创建映射关系-引入映射文件-->
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
</configuration>
//Test
package com.mybatis;
import com.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;
public class MybatisTest {
@Test
public void test() throws IOException {
//加载核心配置文件
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//获取Sqlsession对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取mapper接口对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//调用insert抽象方法
int i = mapper.insertUser();
//mybatis是需要自己进行事务提交的
//手动提交
sqlSession.commit();
System.out.println("result:" + i);
}
}
至此,入门结束。
log4j
1,导入依赖
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
2.配置文件.xml
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LlzA3giI-1646900631747)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220307153645351.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bBz0EVsb-1646900631748)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220307153711253.png)]
CRUD测试
//接口
//插入方法
int insertUser();
/**
* 修改方法
*/
void update();
/**
* 查询方法
*
*/
User queryUser();
/**
* 查询所有的用户信息
*/
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">
<!--namespace与Mapper接口路径保持一致-->
<mapper namespace="com.mapper.UserMapper">
<!--id与接口的抽象方法保持一致-->
<insert id="insertUser">
insert into t_user values(null,"Alan","123455","163@qq.com")
</insert>
<!-- void update();-->
<update id="update">
update t_user set username ="Tom" where id = 7
</update>
<!-- */
User queryUser();-->
<select id="queryUser" resultType="com.pojo.User">
select * from t_user where id = 7
</select>
<!--List<User> getAllUser();-->
<select id="getAllUser" resultType="com.pojo.User">
select * from t_user
</select>
</mapper>
//Test
@Test
public void CRUD() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//mapper.update();
//查询某一用户的用户信息
/*User user = mapper.queryUser();
System.out.println(user);*/
List<User> users = mapper.getAllUser();
users.forEach(user -> System.out.println(user));
}
///没有删除
核心配置文件
起别名
<typeAliases>
<typeAlias type="com.pojo.User"></typeAlias>
</typeAliases>
当需要引入多个映射文件时,可以放包里,然后访问
<!---引入映射文件-->
<mappers>
<!-- <mapper resource="mapper/UserMapper.xml"/>-->
<!--当需要引入多个映射文件时,可以导入包
需要两个条件:
1.xml的包路径必须要与接口的包路径保持一致
2.接口名必须要与映射文件名字一样
附:在resources里创建文件时,要以/做分割,如果以.的话只是一个文件名-->
<package name="com.mapper"></package>
</mappers>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MnFqmjKK-1646900631748)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220307184031011.png)]
将该核心配置文件设置成为模板
Mybatis获取参数值 的两种方式(重点)
1.一种是${} 一种是#{}
2.${} 的本质是字符串拼接,#{} 的本质是占位符赋值。
传递单个参数(根据用户名来获取用户信息)
//接口
//根据用户名来查询用户信息
User getUserbyUsername(String username);
//Usermapper.xml
<!-- User getUserbyUsername(String username);-->
<select id="getUserbyUsername" resultType="User" >
select * from t_user where username = '${username_}'
select * from t_user where username = #{username_}
</select>
//Test
@Test
public void CRUD() throws IOException {
SqlSession sqlSession = SqlSessionutils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User alan = mapper.getUserbyUsername("Alan");
System.out.println(alan);
}
传递多个参数
//接口
//传递多个参数时,可以验证账号密码
User checkloginin(String username,String password);
//Usermapper.xml
<!-- User checkloginin(String username,String password);
注意:Mybatis是以arg0,arg1,param0,param1的方式存取的,把参数放在map集合里,
所以sql语句里必须要在{}里写上键(arg0。。。)的方式,传入参数
2.两种sql语句的写法:
select * from t_user where username= #{arg0} and password= #{arg1}
select * from t_user where username= '${arg0}' and password= '${arg1}'-->
<select id="checkloginin" resultType="User">
select * from t_user where username= '${arg0}' and password= '${arg1}'
</select>
//Test
@Test
public void CRUD() throws IOException {
SqlSession sqlSession = SqlSessionutils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User tom = mapper.checkloginin("Tom", "3321");
System.out.println(tom);
上一个原理(传递多个参数)
多参数时,mybatis是帮我们创建一个map集合来存放需要传递的参数,现在我们来自己创建一个map集合来实现多参数传递。
//接口
User checkloginbyMap(Map<String, Object> map);
//Usermapper.xml
<!--User checkloginbyMap(Map<String, Object> map);-->
<select id="checkloginbyMap" resultType="User">
select * from t_user where username = #{username} and password = #{password}
</select>
//Test
@Test
public void CRUD() throws IOException {
SqlSession sqlSession = SqlSessionutils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Map<String, Object> map = new HashMap<>();
map.put("username","Tom");
map.put("password",3321);
User user = mapper.checkloginbyMap(map);
System.out.println(user);
}
Mybatis的各种查询功能
查询单个根据id和查询所有的用户信息,返回的是属性,属性值
//接口
public interface SelectMapper {
/**
* 查询某一个用户的信息
*/
User getUserById(@Param("id") Integer id);
/**
*
* 查询所有的用户xx
*/
List<User> getAllUser();
}
//SelectMapper.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">
<!--namespace与Mapper接口路径保持一致-->
<mapper namespace="com.mapper.SelectMapper">
<!--void getUserById(@Param("id") Integer id);-->
<select id="getUserById" resultType="User">
select * from t_user where id = #{id}
</select>
<!--List<User> getAllUser();-->
<select id="getAllUser" resultType="User">
select * from t_user
</select>
</mapper>
//Test
public class SelectTest {
@Test
public void testSelectOne(){
SqlSession sqlSession = SqlSessionutils.getSqlSession();
SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
User userById = mapper.getUserById(1);
System.out.println(userById);
}
//查询所有的用户信息
@Test
public void getAll(){
SqlSession sqlSession = SqlSessionutils.getSqlSession();
SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
List<User> allUser = mapper.getAllUser();
allUser.forEach(User-> System.out.println(User));
}
}
查询单行单列的情况
/**
* 获取单行单列的信息
*/
Integer getCount();
//xml
//注意:这里的resultType返回值本来是,java.lang.Integer
//亻是mybatis有自己的别名,如下表,
<!--Integer getCount();-->
<select id="getCount" resultType="int">
select count(*) from t_user
</select>
//查询单行单列的信息
@Test
public void getCount(){
SqlSession sqlSession = SqlSessionutils.getSqlSession();
SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
Integer count = mapper.getCount();
System.out.println(count);
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1GqjvOKG-1646900631748)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220309071056859.png)]
查询单个信息根据id,返回map集合对象
//接口
Map<String,Object> getUserByIdToMap(@Param("id") Integer id);
//xml
<select id="getUserByIdToMap" resultType="map">
select * from t_user where id = #{id}
</select>
//Test
@Test
public void testSelectOne(){
SqlSession sqlSession = SqlSessionutils.getSqlSession();
SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
Map userById = mapper.getUserByIdToMap(1);
System.out.println(userById);
}
查询所有的用户信息,返回map集合
//第一种方法
//接口
List<Map<String,Object> >getUserByIdToMap(@Param("id") Integer id);
//第二种方法,用注解MapKey来将id设置成为键,其余作为值
//接口
@MapKey("id")
Map<String,Object> getUserByIdToMap();
模糊查询
xml如下
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gMRNXAU3-1646900631748)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220309083829658.png)]
批量删除
/**
* 批量删除
*注意:1,sql语句的写法。2,不能使用#{}
*/
、//接口
int removemore(@Param("ids") String ids);
//xml
<mapper namespace="com.mapper.DeleteMapper">
<!-- int removemore(@Param("ids") String ids);-->
<delete id="removemore" >
delete from t_user where id in (${ids})
</delete>
//Test
public class DeleteTest {
@Test
public void deleteTest(){
SqlSession sqlSession = SqlSessionutils.getSqlSession();
DeleteMapper mapper = sqlSession.getMapper(DeleteMapper.class);
int removemore = mapper.removemore("1,3");
System.out.println(removemore);
}
}
查询指定表的信息
注意:不能使用#{}
/**
* 查询指定表的所有信息
*/
List<User> getUserByTablename(@Param("tablename") String tablename);
//xml
<!-- List<User> getUserByTablename(@Param("tablename") String tablename);-->
<select id="getUserByTablename" resultType="User">
select *from ${tablename}
</select>
@Test
public void queryByTablename(){
SqlSession sqlSession = SqlSessionutils.getSqlSession();
SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
List<User> list = mapper.getUserByTablename("t_user");
System.out.println(list);
}
获取自增的主键
xml
<!-- int insertUser(User user);
-useGeneratedKeys表示是否用了自增
keyProperty表示用传递的参数(user中的id)来表示获取id-->
<insert id="insertUsers" useGeneratedKeys="true" keyProperty="id">
insert into t_user values(null,#{username},#{password},#{email})
</insert>
自定义映射ResultMap
一,字段名与属性名不一致时
第一种方法:.在sql语句里,为字段名起个别名
<!-- List<Emp> getAllEmp();-->
<select id="getAllEmp" resultType="Emp">
select eid id,ename name,eage age,email,did from t_emp
</select>
第二种方方法:全局配置mybatis-config.xml[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3KkWn1zd-1646900631749)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220309130614421.png)]
第三种方式:ResultMap来配置映射关系
注意:Result id 对应的是resultMap,type是实体类类型,result id是对应的主键,result property对应的是属性名,column对应的是字段名。
<resultMap id="EmpresultMap" type="Emp">
<id property="id" column="eid"/>
<result property="name" column="ename"/>
<result property="age" column="eage"/>
<result property="email" column="email"/>
<result property="did" column="did"/>
</resultMap>
<!-- List<Emp> getAllEmp();-->
<select id="getAllEmp" resultMap="EmpresultMap">
select * from t_emp
</select>
二,多对一映射关系
方式一:级联属性赋值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QigyinMG-1646900631750)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220309141141016.png)]
//接口
/**
* 查询员工以及和员工部门的信息
*/
Emp getEmpAndDept(int id);
//xml
<resultMap id="getEmpAndDeptone" type="Emp">
<id property="id" column="eid"/>
<result property="name" column="ename"/>
<result property="age" column="eage"/>
<result property="email" column="email"/>
<result property="dept.did" column="did"/>
<result property="dept.name" column="d_name"/>
</resultMap>
<!-- Emp getEmpAndDept(int id);-->
<select id="getEmpAndDept" resultMap="getEmpAndDeptone">
SELECT * FROM t_emp,t_dept where t_emp.eid = t_dept.did and t_emp.eid=#{id}
</select>
///Test
@Test
public void testgetEmpAndDept(){
SqlSession sqlSession = SqlSessionutils.getSqlSession();
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
Emp empAndDept = mapper.getEmpAndDept(2);
System.out.println(empAndDept);
}
方式二:association:处理多对一的映射关系
property:需要处理多对的映射关系的属性名
javaType:该属性的类型
//如下:只是将方式一的xml小改了一下
<resultMap id="getEmpAndDeptone" type="Emp">
<id property="id" column="eid"/>
<result property="name" column="ename"/>
<result property="age" column="eage"/>
<result property="email" column="email"/>
<!--
<result property="dept.did" column="did"/>
<result property="dept.name" column="d_name"/>-->
<association property="dept" javaType="Dept">
<id property="did" column="did"/>
<result property="name" column="d_name"/>
</association>
</resultMap>
<!-- Emp getEmpAndDept(int id);-->
<select id="getEmpAndDept" resultMap="getEmpAndDeptone">
SELECT * FROM t_emp,t_dept where t_emp.eid = t_dept.did and t_emp.eid=#{id}
</select>
方式三:分步查询
select:设置分步查询的sqL的唯一标识(namespace.sQLId或mapper接口的全类名.方法名)
column:设置分布查询的条件
DeptMapper.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">
<!--namespace与Mapper接口路径保持一致-->
<mapper namespace="com.mapper.DeptMapper">
<resultMap id="getAllResult" type="Dept">
<id property="did" column="did"></id>
<result property="name" column="d_name"/>
</resultMap>
<!-- Dept getAll(int did);-->
<select id="getAll" resultMap="getAllResult">
select * from t_dept where did =#{did}
</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">
<!--namespace与Mapper接口路径保持一致-->
<mapper namespace="com.mapper.EmpMapper">
<resultMap id="EmpresultMap" type="Emp">
<id property="id" column="eid"/>
<result property="name" column="ename"/>
<result property="age" column="eage"/>
<result property="email" column="email"/>
<result property="did" column="did"/>
</resultMap>
<!-- List<Emp> getAllEmp();-->
<select id="getAllEmp" resultMap="EmpresultMap">
select * from t_emp
</select>
<resultMap id="getEmpAndDeptByStep" type="Emp">
<id property="id" column="eid"/>
<result property="name" column="ename"/>
<result property="age" column="eage"/>
<result property="email" column="email"/>
<!--
<result property="dept.did" column="did"/>
<result property="dept.name" column="d_name"/>-->
<!--<association property="dept" javaType="Dept">
<id property="did" column="did"/>
<result property="name" column="d_name"/>
</association>-->
<association property="dept"
select="com.mapper.DeptMapper.getAll"
column="did"></association>
</resultMap>
<!-- Emp getEmpAndDept(int id);-->
<select id="getEmpAndDept1" resultMap="getEmpAndDeptByStep">
select * from t_emp where eid = #{idd}
</select>
</mapper>
EmpMapper.xml
延迟加载
分步查询的优点:可以实现延迟加载,但是必须在核心配置文件中设置全局配置信息:
lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有关联对象都会延迟加载
aggressiveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性。否则,每个属性会按需加载
此时就可以实现按需加载,获取的数据是什么,就只会执行相应的sql。此时可通过association和collection中的fetchType属性设置当前的分步查询是否使用延迟加载,fetchType=“lazy(延迟加载)/eager(立即加载)”
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hA2nqrbC-1646900631750)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220309153644104.png)]
三,一对多映射关系
1,collection
//DeptMapper.xml
<resultMap id="getDeptAndEmpREsultMap" type="Dept">
<id property="did" column="did"/>
<result property="name" column="d_name"/>
<collection property="emp" ofType="Emp">
<id property="id" column="eid"/>
<result property="name" column="ename"/>
<result property="age" column="eage"/>
<result property="email" column="email"/>
</collection>
</resultMap>
<!-- Dept getDeptAndEmp(@Param("did") int did);-->
<select id="getDeptAndEmp" resultMap="getDeptAndEmpREsultMap">
select * from t_dept left join t_emp on t_dept.did = t_emp.eid where t_dept.did = #{did}
</select>
2,分步查询
关键代码如下
//deptMapper.xml
<!-- Dept getDeptAndEmp(@Param("did") int did);-->
<select id="getDeptAndEmp" resultMap="getDeptAndEmpREsultMap">
select * from t_dept left join t_emp on t_dept.did = t_emp.eid where t_dept.did = #{did}
</select>
<resultMap id="ByStepResultMap" type="Dept">
<id property="did" column="did"/>
<result property="name" column="d_name"/>
<collection property="emp"
select="com.mapper.EmpMapper.getAll"
column="did">
</collection>
</resultMap>
<!--Dept getDeptAndEmpByStep(@Param("did") int did);-->
<select id="getDeptAndEmpByStep" resultMap="ByStepResultMap">
select *from t_dept where did = #{did}
</select>
//EmpMapper.xml
<resultMap id="T" type="Emp">
<id property="id" column="eid"/>
<result property="name" column="ename"/>
<result property="age" column="eage"/>
<result property="email" column="email"/>
</resultMap>
<!-- List<Emp> getAll(@Param("id") int id);-->
<select id="getAll" resultMap="T">
select * from t_emp where did = #{did}
</select>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kaGOcQgx-1646900631751)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220309184726613.png)]
动态sql
1,if:
根据标签中test属性所对应的表达式决定标签中的内容是否需要拼接到SsQL中
2,where :
当where标签中有内容时,会自动生成where关键字,并且将内容前多余的and或or去掉当where标签中没有内容时,此时where标签没有任何效果
*注意:where标签不能将其中内容后面多余的and或or去掉
3,trim :
prefix/suffix:将trim标签中内容前面或后面添加指定内容
suffixoverrides|prefixoverrides:将trim标签中内容前面或后面去掉指定内容
<!-- List<Emp> getEmpByChoose(Emp emp);-->
<select id="getEmpByChoose" resultMap="R">
select * from t_emp
<where>
<choose>
<when test="id != null and id!= ''" >
eid = #{id}
</when>
<when test="id != null and id!= ''" >
ename = #{id}
</when>
<when test="id != null and id!= ''" >
eage = #{id}
</when>
<when test="id != null and id!= ''" >
email = #{id}
</when>
<otherwise>
did = 1
</otherwise>
</choose>
</where>
</select>
4, 传递一个数组实现批量删除
delete from t_emp where eid in( ?,?,?)
//接口
Integer deleteByNums(@Param("eids") Integer[] nums);
<!-- Integer deleteByNums(Integer[] nums);-->
<delete id="deleteByNums">
delete from t_emp where eid in
<foreach collection="eids" item="eid" open="(" close=")" separator="," >
#{eid}
</foreach>
</delete>
delete from t_emp where eid =? or eid = ?
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C82GYsWZ-1646900631751)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220310134838442.png)]
5.collection实现批量添加
/**
* collection实现批量添加
*/
Integer indertBycollection(@Param("emps") List<Emp> emps);
<!-- Integer indertBycollection(List<Emp> emps);-->
<insert id="indertBycollection" >
insert into t_emp values
<foreach collection="emps" item="emp" separator=",">
(null,#{emp.name},#{emp.age},#{emp.email},null)
</foreach>
</insert>
@Test
public void testsql(){
SqlSession sqlSession = SqlSessionutils.getSqlSession();
SqlMapper mapper = sqlSession.getMapper(SqlMapper.class);
Emp a = new Emp(null, "A", 19, "qq.com", null);
Emp b= new Emp(null, "B", 14, "qq.com", null);
Emp c = new Emp(null, "C", 15, "qq.com", null);
List<Emp> list = Arrays.asList(a, b, c);
System.out.println(mapper.indertBycollection(list));
}
6.sql标签
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vTjoQn4U-1646900631752)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220310142610497.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k5f6OIO0-1646900631752)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220310142731371.png)]
mybatis缓存----------------------------查询有效
一级缓存(默认开启)
一级缓存是SqlSession级别的,通过同一个SqlSession查询的数据会被缓存,下次查询相同的数据,就会从缓存中直接获取,不会从数据库重新访问
使─级缓存失效的四种情况:
1)不同的SqlSession对应不同的—级缓存
2)同一个SqlSession但是查询条件不同
3)同一个SqlSession两次查询期间执行了任何一次增删改操作
4)同—个SalSession两次杳询期间手动清空了缓存
二级缓存
2、MyBatis的二级缓存
二级缓存是SqlSessionFactory级别,通过 SqlSessionFactory创建的SqlSession查询的结果会被缓存;此后若再次执行相同的查询语句,结果就会从缓存中获取。
二级缓存开启的条件:
a>在核心配置文件中,设置全局配置属性cacheEnabled=“true”,默认为true,不需要设置
b>在映射文件中设置标签
c>二级缓存必须在SqlSession关闭或提交之后有效
d>查询的数据所转换的实体类类型必须实现序列化的接口
使二级缓存失效的情况:
两次查询之间执行了任意的增删改,会使一级和二级缓存同时失效
二级缓存的相关配置
在mapper配置文件中添加的cache标签可以设置一些属性:
eviction属性:缓存回收策略
LRU (Least Recently Used)-最近最少使用的:移除最长时间不被使用的对象。FIFO (First in First out)-先进先出:按对象进入缓存的顺序来移除它们。
SOFT-软引用:移除基于垃圾回收器状态和软引用规则的对象。
WEAK–弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。默认的是 LRu。
. flushInterval属性:刷新间隔,单位毫秒
默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新·
size属性:引用数目,正整数
代表缓存最多可以存储多少个对象,太大容易导致内存溢出.
readOnly属性:只读,true/false
true:只读缓存;会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。
false:读写缓存;会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是false。
Mybatis缓存的查询的顺序
·先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用。·如果二级缓存没有命中,再查询—级缓存
·如果—级缓存也没有命中,则查询数据库
. SqlSession关闭之后,—级缓存中的数据会写入二级缓存
Mybatis逆向工程
·正向工程:先创建Java实体类,由框架负责根据实体类生成数据库表。Hibernate是支持正向工程的。
·逆向工程:先创建数据库表,由框架负责根据数据库表,反向生成如下资源:
o Java实体类
o Mapper接口
o Mapper映射文件
分页
*使用MyBatis的分页插件实现分页功能,需要在查询功能之前开启分页
rpageHeLper.startpage(int pageNum,int pagesize)
2、在查询功能之后获取分页相关信息
*Pageinfo page = new PageInfo<>(list,5)
化的接口
使二级缓存失效的情况:
两次查询之间执行了任意的增删改,会使一级和二级缓存同时失效
二级缓存的相关配置
在mapper配置文件中添加的cache标签可以设置一些属性:
eviction属性:缓存回收策略
LRU (Least Recently Used)-最近最少使用的:移除最长时间不被使用的对象。FIFO (First in First out)-先进先出:按对象进入缓存的顺序来移除它们。
SOFT-软引用:移除基于垃圾回收器状态和软引用规则的对象。
WEAK–弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。默认的是 LRu。
. flushInterval属性:刷新间隔,单位毫秒
默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新·
size属性:引用数目,正整数
代表缓存最多可以存储多少个对象,太大容易导致内存溢出.
readOnly属性:只读,true/false
true:只读缓存;会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。
false:读写缓存;会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是false。
Mybatis缓存的查询的顺序
·先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用。·如果二级缓存没有命中,再查询—级缓存
·如果—级缓存也没有命中,则查询数据库
. SqlSession关闭之后,—级缓存中的数据会写入二级缓存
Mybatis逆向工程
·正向工程:先创建Java实体类,由框架负责根据实体类生成数据库表。Hibernate是支持正向工程的。
·逆向工程:先创建数据库表,由框架负责根据数据库表,反向生成如下资源:
o Java实体类
o Mapper接口
o Mapper映射文件
分页
*使用MyBatis的分页插件实现分页功能,需要在查询功能之前开启分页
rpageHeLper.startpage(int pageNum,int pagesize)
2、在查询功能之后获取分页相关信息
*Pageinfo page = new PageInfo<>(list,5)