Mybatis

Mybatis
一、需要导入的包
mysql-connector-java
mybatis
二、在src->resource下创建mybatis-config.xml文件,配置数据库

<environments default="development">
    <!--配置mysql的环境-->
    <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/mybatis"/>
            <property name="username"  value="root"/>
            <property name="password"  value="password"/>

        </dataSource>
    </environment>
</environments>
<!--指定映射配置文件的位置,映配置文件-->
<mappers>
    <mapper   resource="com/kuang/dao/UserMapper.xml"/>
</mappers>
三、编写Mybatis工具类

package com.kuang.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;

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();
}
}
//既然有了SqlSessionFactory,顾名思义,我们就可以从中获得SqlSession的实例了
//SqlSession完全包含了面向数据库执行SQL命令的所有方法
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();

}

}
③步骤②中最重要的两步代码
(1)Public static SqlSession getSqlSession(){
return sqlSessionFactory openSession();
}
(2)sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream)
四、在pojo层写ORM类
五、在dao接口层写各种方法

 package com.kuang.dao;

import com.kuang.pojo.User;
import java.util.List;
import java.util.Map;

public interface UserDao {
//查询全部用户
List getUserList();
//根据ID查询用户
User getUserById(int id);
//增加用户
void addUser(User user);
//修改用户
void updateUser(User user);
//删除一个用户
void deleteUser(int id);
void addUser2(Map<String,Object> map);
User getUserById2(Map<String,Object>map);
List getUserLike(String value);
}
六、接口实现类由原来的UserDaoImpl转变为一个Mapper配置文件xxxMapper.xml
<?xml version="1.0" encoding="UTF-8"?>

select * from user; select * from mybatis.user where id=#{id}; insert into mybatis.user(id,name,pwd) values(#{id},#{name},#{pwd}); insert into user(id,name,pwd) values(#{userid},#{userName},#{passWord}); update mybatis.user set name=#{name},pwd=#{pwd}where id=#{id}; delete from mybatis.user where id=#{id}; select * from user where id=#{id}; select * from user where name like #{value} 七、Test代码 (1)获取SqlSession对象 SqlSession sqlsession =Mybatisutils.getSqlSession(); //方式一:getMapper UserDao userDao=sqlSession.getMapper(UserDao.class); List userList=userDao.getUserList(); for(User user:userList){ System.out.println(user); } 八、CRUD操作及配置解析 (1)需求:给数据库增加一个用户 //添加一个用户 int addUser(User user); ( 2 ) 在UserMapper.xml中添加insert语句 insert into user(id,name,pwd)values(#{id},#{name},#{pwd}) (3)测试 @Test public void testAddUser(){ SqlSession session =MybatisUtils.getSession(); UserMapper mapper=session.getMapper(UserMapper.class); User user =new User(5,“王五”,“zxcvbn”); int i =mapper.addUser(user); System.out.println(i); session.commit(); session.close(); } 注意点:增、删、改操作需要提交事务 (1)修改 同理,编写接口方法 int updateUser(User user) (2)编写对应的配置文件SQL update user set name=#{name},pwd=#{pwd} where id=#{id} (3)测试 @Test public void testUpdateUser(){ SqlSession session =MybatisUtils.getSession(); UserMapper mapper =session.getMapper(UserMapper.class); User user =mapper.selectUserById(1); user.setPwd(“asdfgh”); int i=mapper.updateUser(user); System.out.println(i); session.commit(); session.close(); } (1)删除 //根据id删除用户 int deleteUser(int id); (2)编写对应的配置文件SQL delete from user where id=#{id} (3)测试 @Test public void testDeleteUser(){ SqlSession session =MybatisUtils.getSession(); UserMapper mapper =session.getMapper(UserMapper.class); int i=mapper.deleteUser(5); System.out.println(i); session.commit();//提交事务 session.close();

}
九、模糊查询like语句该怎么写
第一种:在Java代码中添加sql通配符
string wildcardname=“%smi%”;
list names =mapper.selectlike(wildcardname);

select * from foo where bar like #{value}

第二种:在sql语句中拼接通配符,会引起sql注入
string wildcardname=“smi”;
list names =mapper.selectlike(wildcardname);

select * from foo where bar like "%"#{value}"%" 十、配置之属性优化一 (1)在resources下,创建db.properties driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/mybatis username=root password=password (2) 在 mybatis-config.xml第一行下引入外部文件 (3)在下面value中配置 value=${ "driver"} 十一、 typeAliases优化 类型别名是为java类型设置一个短的名字。它只和XML配置有关,存在的意义仅在于用来减少类完全限定名的冗余

log4j.rootLogger=DEBUG,console,file

#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n

#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/kuang.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n

#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
③setting设置日志实现



④ 在程序中使用Log4j进行输出!
//注意导包:org.apache.log4j.Logger
static Logger logger = Logger.getLogger(MyTest.class);

@Test
public void selectUser() {
logger.info(“info:进入selectUser方法”);
logger.debug(“debug:进入selectUser方法”);
logger.error(“error: 进入selectUser方法”);
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
List users = mapper.selectUser();
for (User user: users){
System.out.println(user);
}
session.close();
}
十五、limit实现分页
①#语法
SELECT * FROM table LIMIT stratindex,pageSize
select * from table limit 5,10;
②修改Mapper文件

select * from user limit #{startindex},#{pageSize}

③Mapper接口,参数为map
//选择全部用户实现分页
List selectUser(Map<String,Integer> map);
④在测试类中传入参数测试
起始位置=(当前页面-1)*页面大小
@Test
public void testSelectUser() {
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);

int currentPage = 1; //第几页
int pageSize = 2; //每页显示几个
Map<String,Integer> map = new HashMap<String,Integer>();
map.put(“startIndex”,(currentPage-1)*pageSize);
map.put(“pageSize”,pageSize);

List users = mapper.selectUser(map);

for (User user: users){
System.out.println(user);
}

session.close();
}
十六、使用注解开发
注意:使用注解开发就不需要mapper.xml映射文件了
①、我们在我们的接口中添加注解
//查询全部用户
@Select(“select id,name,pwd password from user”)
public List getAllUser();
②、在mybatis的核心配置文件中注入




③、我们去测试
@Test
public void testGetAllUser(){
Sqlsession session=MybatisUtils.getSession();
//本质上利用了jvm的动态代理
UserMapper mapper=session.getMapper(UserMapper.class);
List users=mapper.getAllUser();
for(User user:users){
System.out.println(user);
}
session.close();
}
十七、多对一处理
①按查询嵌套处理
(1)给StudentMapper接口增加方法
//获取所有学生及对应老师的信息
public List getStudent();
(2)编写对应的Mapper文件
<?xml version="1.0" encoding="UTF-8" ?>


<!–
需求:获取所有学生及对应老师的信息
思路:
1. 获取所有学生的信息
2. 根据获取的学生信息的老师ID->获取该老师的信息
3. 思考问题,这样学生的结果集中应该包含老师,该如何处理呢,数据库中我们一般使用关联查询?
1. 做一个结果集映射:StudentTeacher
2. StudentTeacher结果集的类型为 Student
3. 学生中老师的属性为teacher,对应数据库中为tid。
多个 [1,…)学生关联一个老师=> 一对一,一对多
4. 查看官网找到:association – 一个复杂类型的关联;使用它来处理关联查询

select * from student;







select * from teacher where id=#{id}


(4)编写完毕去Mybatis配置文件中,注册Mapper!
5.测试
@Test
public void testGetStudents(){
SqlSession session =MybatisUtils.getSession();
StudentMapper mapper=session.getMapper(StudentMapper.class);
List students =mapper.getStudents();
for(Student student:students){
System.out.println(
“学生名”+student.getName()
+“\t老师:”+student.getTeacher().getName());

}
}
②按照结果进行嵌套处理
(1)接口方法编写
public List getStudents2();
(2)编写对应的mapper文件

select s.id sid,s.name, sname,t.name tname
from student s,teacher t
where s.tid=t.id









十七、一对多处理
①(1)实体类编写
@Data
public class Student {
private int id;
private String name;
private int tid;
}
@Data
public class Teacher {
private int id;
private String name;
//一个老师多个学生
private List students;
}
(2)TeacherMapper接口编程方法
//获取指定老师,及老师下的所有学生
public Teacher getTeacher(int id);
(3)编写接口对应的Mapper配置文件


select s.id sid,s.name sname,t.name tname,tid tid
from student s,teacher t
where s.tid=t.id and t.id=#{id}










(4)将Mapper文件注册到MyBatis-config文件中



(5)测试
@Test
public void testGetTeacher(){
SqlSession session =MybatisUtils.getSession();
TeacherMapper mapper=session.getMapper(TeacherMapper.class);
Teacher teacher=mapper.getTeacher(1);
System.out.println(teacher.getName);
System.out.println(teacher.getStudents())
}
②按查询嵌套处理
1.TeacherMapper接口编写方法
public Teacher getTeacher2(int id);
2.编写接口对象的Mapper配置文件

select * from teacher where id=#{id}





select * from student where tid=#{id}

十八、缓存
1.什么是缓存[Cache]?
.存在内存中的临时数据。
.将用户经常查询的数据放在缓存中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。
2.为什么使用缓存?
.减少和数据库的交互次数,减少系统开销,提高系统效率
3.什么样的数据能使用缓存?
.经常查询并且不经常该表的数据
4.Mybatis缓存
.Mybatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。
.Mybatis系统中默认定义了两级缓存:一级缓存和二级缓存
.默认情况下,只有一级缓存开启(SqlSession级别的缓存,也称为本地缓存0
.二级缓存需要手动开启和配置,他是基于namespace级别的缓存.
.为了提高扩展性,Mybatis定义了缓存接口Cache。我们可以通过实现Cache接口来定义二级缓存
5.一级缓存
一级缓存也叫本地缓存
.与数据库同一次会话期间查询到的数据会放到本地缓存中。
.以后如果需要获取相同的数据,直接从缓存中拿,没必须再去查询数据库;
6.测试
(1)在mybatis中加入日志,方便测试结果
(2)编写接口方法
//根据id查询用户
User queryUserById(@Param(“id”) int id);
(3)接口对应的Mapper文件

select * from user where id=#{id}

(4)测试
@Test
public void testQueryUserById(){
SqlSession session=MybatisUtils.getSession();
UserMapper mapper=session.getMapper(UserMapper.class);
User user=mapper.queryUserById(1);
Sysetm.out.println(user);
User user2=mapper.queryUserById(1);
System.out.println(user2);
System.out.println(user==user2);
session.close();
}
7.结果分析
在这里插入图片描述
8.一级缓存失效的四种情况
一级缓存是SqlSession级别的缓存,是一直开启的,我们关闭不了它;
一级缓存失效情况:没有使用到当前的一级缓存,效果就是,还需要再向数据库中发起一次查询请求!
①.sqlSession不同
@Test
public void testQueryUserById(){
SqlSession session = MybatisUtils.getSession();
SqlSession session2 = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
UserMapper mapper2 = session2.getMapper(UserMapper.class);

User user = mapper.queryUserById(1);
System.out.println(user);
User user2 = mapper2.queryUserById(1);
System.out.println(user2);
System.out.println(user==user2);

session.close();
session2.close();
}
结论:每个sqlSession中的缓存相互独立
②sqlSession相同,查询条件不同
@Test
public void testQueryUserById(){
SqlSession session =MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
UserMapper mapper2 = session.getMapper(UserMapper.class);

User user = mapper.queryUserById(1);
System.out.println(user);
User user2 = mapper2.queryUserById(2);
System.out.println(user2);
System.out.println(user==user2);

session.close();
}
③、sqlSession相同,两次查询之间执行了增删改操做
@Test
public void testQueryUserById(){
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);

User user = mapper.queryUserById(1);
System.out.println(user);

HashMap map = new HashMap();
map.put(“name”,“kuangshen”);
map.put(“id”,4);
mapper.updateUser(map);

User user2 = mapper.queryUserById(1);
System.out.println(user2);

System.out.println(user==user2);

session.close();
}
④、sqlSession相同,手动清除一级缓存
@Test
public void testQueryUserById(){
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);

User user = mapper.queryUserById(1);
System.out.println(user);

session.clearCache();//手动清除缓存

User user2 = mapper.queryUserById(1);
System.out.println(user2);

System.out.println(user==user2);

session.close();
}
9、二级缓存
…二级缓存也叫全局缓存,一级缓存作用域太低了,所以就诞生了二级缓存
.基于namespace级别的缓存,一个名称空间,对应一个二级缓存;
工作机制
.一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中;
.如果当前会话关闭了,这个会话对应的一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据就保存到二级缓存中;
.新的会话查询信息,就可以从二级缓存中获取内容;
.不同的mapper查出的数据会放在自己对应的缓存中;
①使用步骤
开启全局缓存【mybatis-config.xml】

②、去每个mapper.xml中配置使用二级缓存,这个配置非常简单

官方示例=====>查看官方文档

这个更高级的配置创建了一个 FIFO 缓存,每隔 60 秒刷新,最多可以存储结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此对它们进行修改可能会在不同线程中的调用者产生冲突。
③代码测试
@Test
public void testQueryUserByid(){
SqlSession session =MybatisUtils.getSession();
SqlSession session2=MybatisUtils.getSession();
UserMapper mapper =session.getMapper(UserMapper.class);
UserMapper mapper2=session2.getMapper(UserMapper.class);
User user =mapper.queryUserById(1);
System.out.println(user);
session.close();
User user2=mapper2.queryUserByid(1);
System.out.println(user2);
System.out.println(user==user2);
session2.close();
}
结论:
.只要开启了二级缓存,我们在同一个Mapper中的查询,就可以在二级缓存中拿到数据
.查出的数据都会被默认先放在一级缓存中
.只有会话提交或者关闭以后,一级缓存中的数据才会转到二级缓存中
十九、Mybatis详细的执行流程
①Resources加载全局配置文件
②实例化SqlSessionFactoryBuilder构建器
③由XMLConfigBuilder解析配置文件流
④把配置信息存放在Configuration中
⑤实例化SqlSessionFactory实现类DefaultSqlSessionFactory
⑥由TransactionFactory创建一个Transaction事务对象
⑦创建执行器Excutor
⑧创建SqlSession接口实现类DefaultSqlSession
⑨实现CRUD
10.执行是否成功
11.提交事务
12.关闭。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值