Mybatis框架总结

Mybatis框架总结

作用:数据访问层框架,底层是对JDBC的封装
优点:不需要实现类,只需要写执行的sql语句

环境搭建

  1. 导入jar包
    在这里插入图片描述
  2. src下新建全局配置文件Mybatis.xml,,该文件中主要是对连接数据库的配置,对JDBC的封装。
    全局配置文件内容:
<?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>
	<!-- default引用environment的id,当前所使用的环境 -->
	<environments default="default">
		<!-- 声明可以使用的环境 -->
		<environment id="default">
			<!-- 使用原生JDBC事务 -->
			<transactionManager type="JDBC"></transactionManager>
			<dataSource type="POOLED">
				<property name="driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
				<property name="url" value="jdbc:sqlserver://localhost:8080/Student"/>
				<property name="username" value="sa"/>
				<property name="password" value="123456"/>
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<mapper resource="mapper/StudentMybatis.xml"/>
	</mappers>
</configuration>
其中:
<transactionManager /> type属性可取值:
	JDBC:事务管理使用JDBC原生事务管理方式
	MANAGED:将事务管理转交给其他容器
<dataSource />type属性:
	POOLED:用数据库连接池
	UNPOOLED:和直接使用JDBC一样
	JNDI:java命名目录接口
  1. 在src下新建mapper包,创建实体类名Mapper.xml文件,作用是编写需要执行的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">
<!-- namesapce:理解成实现类的全路径(包名+类名) -->
<mapper namespace="a.b" >
	<!-- id:方法名 
		parameterType:定义参数类型
		resultType:返回值类型.
		
		如果方法返回值是list,在resultType中写List的泛型,因为mybatis
		对jdbc封装,一行一行读取数据
	-->
	<select id="selAll" resultType="pojo/Student">
		select * from flower
	</select>
</mapper>

  1. 在src下创建事件类的包pojo,并创建实现类文件。
package pojo;

public class Student {
	private int snum;
	private String sname;
	private int sex;
	private String sclass;
	
	
	public Student() {
		super();
		
	}

	public Student(int snum, String sname, int sex, String sclass) {
		super();
		this.snum = snum;
		this.sname = sname;
		this.sex = sex;
		this.sclass = sclass;
	}

	@Override
	public String toString() {
		return "student [snum=" + snum + ", sname=" + sname + ", sex=" + sex
				+ ", sclass=" + sclass + "]";
	}
	
	public int getSnum() {
		return snum;
	}
	public void setSnum(int snum) {
		this.snum = snum;
	}
	public String getSname() {
		return sname;
	}
	public void setSname(String sname) {
		this.sname = sname;
	}
	public int getSex() {
		return sex;
	}
	public void setSex(int sex) {
		this.sex = sex;
	}
	public String getSclass() {
		return sclass;
	}
	public void setSclass(String sclass) {
		this.sclass = sclass;
	}
	
	
}

  1. 在src下创建service包,创建实现类的接口,并实现接口
package service;

import java.io.IOException;
import java.util.List;

import pojo.PageInfo;
import pojo.Student;

public interface StudentService {
	//查看全部信息
	
	List<Student>  show() throws IOException;
	
	//对数据进行分页显示,输入每页大小和当前页数
	PageInfo showPage(int PageSize,int PageNum) throws IOException;
}

package service;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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 pojo.PageInfo;
import pojo.Student;

public class StudentServiceImpl implements StudentService{
	
	public List<Student> show() throws IOException{
		InputStream is=Resources.getResourceAsStream("Mybatis.xml");
		//使用简单工厂类
		SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(is);
		SqlSession session=factory.openSession();
		List<Student> list=session.selectList("mapper.StudentMapper.xml");
		session.close();
		return list;
	}
	
	public PageInfo showPage(int PageSize,int PageNum) throws IOException{
		//使用工厂设计模式
		InputStream is=Resources.getResourceAsStream("Mybatis.xml");
		SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(is);
		SqlSession session=factory.openSession();
		
		PageInfo pi=new PageInfo();
		pi.setPageNum(PageNum);//设定当前页
		pi.setPageSize(PageSize);//设定每页数量
		
		Map<String,Object> map=new HashMap();
		map.put("PageStart", PageSize*(PageNum-1));//页面初始值
		map.put("PageSize", PageSize);
		
		pi.setList(session.selectList("mapper.StudentMapper.xml"));
		
		int count=session.selectOne("mapper.StudentMapper.xml");
		
		pi.setTotol(count%PageSize==0?count/PageSize:count/PageSize+1);
		
		return pi;
		
		
		
	}
}

  1. 子src下创建servlet包,创建servlet。
package servlet;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import pojo.Student;
import service.StudentService;
import service.StudentServiceImpl;

public class selServlet extends HttpServlet {
	
	private StudentService studentservice=new StudentServiceImpl();
	@Override
	public void service(HttpServletRequest req,HttpServletResponse res) throws ServletException, IOException{
		List<Student> list=studentservice.show();
		req.setAttribute("list", list);
		req.getRequestDispatcher("index.jsp").forward(req, res);
		
	}
}

  1. 在src下创建测试包test,并创建Test文件
package test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

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 pojo.Student;

public class TestStudent {
	public static void main(String[] args) throws IOException{
		InputStream is=Resources.getResourceAsStream("mybatis.xml");
		//使用工厂设计模式
		SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(is);
		//生产SqlSession
		SqlSession session=factory.openSession();
		
		List<Student> list=session.selectList("a.b.selAll");
		for(Student student:list){
			System.out.println(student.toString());
		}
		
		session.close();
	}
}

数据库连接池

在内存中开辟一块空间,存放多个数据库连接对象。存在两个状态:

active:当前连接对象被应用程序使用中。
idle:空闲状态,等待应用程序使用
目的:高频率访问数据库时,使用数据库连接池可以降低服务器系统压力,提高程序运行效率。其中,小型项目不适用数据库连接池。

实现JDBC-Tomcat pool的步骤:

  1. 在Web项目中的META-IF中存放context.xml,在context.xml中编写数据库连接池属性。
<?xml version="1.0" encoding="UTF-8"?>
<Context>
	<Resource
		driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
		url="jdbc:sqlserver://localhost:8080/Student"
		username="sa"
		password="123456"
		maxActive="50"
		maxIdle="20"
		name="test"
		auth="Container"
		maxWait="10000"
		type="javax.sql.DataSource"
	/>
</Context>
  1. 发布项目到Tomcat上,在java上使用jndi获取数据库连接池中的对象。

    context:上下文接口,context.xml:文件对象类型		
    

代码如下:
在这里插入图片描述
3 . 当关闭连接对象时,把连接对象归还给数据库连接池,将状态改为idle。

三种查询方式

1.selectList(),返回值为List<resultType 属性控制>适用于查询结果都需遍历的需求。

List<Flower> list = session.selectList("a.b.selAll");
		for (Flower flower : list) {
			System.out.println(flower.toString());
		}

2.selectOne(),返回Object,适用于返回结果只是变量或一行数据。

int count = session.selectOne("a.b.selById");
		System.out.println(count);

3 .selectMap(),返回Map,适用于需要在查询结果中通过某列的值取到这行数据的需求。

//把数据库中哪个列的值当作map的key
		Map<Object, Object> map = session.selectMap("a.b.c", "name123");
		System.out.println(map);

<settings>标签

在mybatis全局配置文件中,控制mybatis全局开关

必须保证有log4j.jar
在src下有log4j.properties
<settings>
	<setting name="LogImpl" value="LOG4J"/>
</settings>

parameterType属性

  1. 在mapper.xml中和等标签的parameterType可以控制参数类型
  2. Sqlession的selectList()和seletOne()的第二个参数和selectMap()的第三个参数都表示方法的参数。
    在这里插入图片描述

#{}和${}的区别

  1. #{}获取参数的内容,索引获取,param1获取指定位置参数并且sql使用?占位。
  2. ${}字符串拼接不使用?,默认找 ${内容}的get/set方法。

Mybatis中实现mysql分页写法

  1. 在pojo下创建page文件
package com.bjsxt.pojo;

import java.util.List;

public class PageInfo {
	//每页显示个数
	private int pageSize;
	//当前第几页
	private int pageNumber;
	//总页数
	private long total;
	//当前页显示的数据
	private List<?> list;
	
	
	public int getPageSize() {
		return pageSize;
	}
	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}
	public int getPageNumber() {
		return pageNumber;
	}
	public void setPageNumber(int pageNumber) {
		this.pageNumber = pageNumber;
	}
	public long getTotal() {
		return total;
	}
	public void setTotal(long total) {
		this.total = total;
	}
	public List<?> getList() {
		return list;
	}
	public void setList(List<?> list) {
		this.list = list;
	}
	
}

  1. 在servlet中创建分页的servlet文件
package servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import pojo.PageInfo;
import service.StudentService;
import service.StudentServiceImpl;

public class PageInfoServlet extends HttpServlet{
	
	private StudentService studentservice=new StudentServiceImpl();
	
	@Override
	public void service(HttpServletRequest req,HttpServletResponse res) throws ServletException, IOException{
		//第一次访问的验证,当没有传递参数,设置默认值
		String PageSizeStr=req.getParameter("PageSize");
		int PageSize=2;//初始化页面大小
		if(PageSizeStr!=null&&!PageSizeStr.equals(" ")){
			PageSize=Integer.parseInt(PageSizeStr);
		}
		String PageNumStr=req.getParameter("PageNum");
		int PageNum=1;//初始化当前页
		if(PageNumStr!=null&&!PageNumStr.equals(" ")){
			PageNum=Integer.parseInt(PageNumStr);
		}
		PageInfo pi=studentservice.showPage(PageSize, PageNum);//将页面大小信息和当前页信息传入
		req.setAttribute("PageInfo", pi);
		req.getRequestDispatcher("index.jsp").forward(req,res);
	}
}

mapper.xml文件中添加以下代码:

<select id="selByPage" resultType="Student" parameterType="map">
		select * from people limit #{PageStart},#{PageSize}
</select>

Mybatis实现插入

JDBC中的executeupdate()执行新增、删除、修改的sql。返回值int,为受影响的行数。
mybatis中<insert>、<delete>、<update>标签无resultType属性,认为属性值都是int。
  • 实现新增

  • 在mapper.xml中添加如下代码:

<insert id="ins" parameterType="pojo.Student">
	insert into student(snum,sname,sex,sclass) values(#{snum},#{sname},#{sex},#{sclass})
</insert>
  • 使用session调用insert()方法
public class Test {
	public static void main(String[] args) throws IOException {
		InputStream is = Resources.getResourceAsStream("mybatis.xml");
		SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
		SqlSession session = factory.openSession();
//		People peo =new People();
//		peo.setId(1);
		//显示几个
//		int pageSize = 2;
		//第几页
//		int pageNumber = 2;
		//如果希望传递多个参数,可以使用对象或map
//		Map<String,Object> map = new HashMap<>();
//		map.put("pageSize", pageSize);
//		map.put("pageStart", pageSize*(pageNumber-1));
//		List<People> p = session.selectList("a.b.page",map);
//		System.out.println(p);
			People p = new People();
			p.setName("新增name1");
			p.setAge(88);
			try {
				int index = session.insert("a.b.ins", p);
				if(index>0){
					System.out.println("成功");
				}else{
					System.out.println("失败");
				}
			} catch (Exception e1) {
//				e1.printStackTrace();
				session.rollback();
			}
			p.setName("aa");
			try {
				int index1 = session.insert("a.b.ins", p);
				if(index1>0){
					System.out.println("成功");
				}else{
					System.out.println("失败");
				}
			} catch (Exception e) {
//				e.printStackTrace();
				session.rollback();
			}
			session.commit();*/

Mybatis实现删除

  • 在mapper.xml中添加如下代码:
<delete id="del" parameterType="pojo.Student">
		delete from student whele id=#{0}
</delete>
  • 使用session调用delete方法
int del = session.delete("a.b.del",3);
		
		if(del>0){
			System.out.println("成功");
		}else{
			System.out.println("失败");
		}
		session.commit();
		
		session.close();
		System.out.println("程序执行结束");

Mybatis实现更新

  • 在Mapper.xml中添加如下代码:
<update id="upd" parameterType="pojo.Student">
	update student set snum=#{snum} whele sname=#{sname}
</update>
  • 使用session调用update方法:
**
		 * 实现修改id=3的name=王五
		 * 
		 * 并输出执行结果
		 */
		People peo = new People();
		peo.setId(4);
		peo.setName("王五");
		int index = session.update("a.b.upd", peo);
		if(index>0){
			System.out.println("成功");
		}else{
			System.out.println("失败");
		}
		session.commit();

Mybatis接口绑定及多参数传递

  • 作用:实现创建一个接口后把mapper.xml由mybatis生成接口的实现类,通过调用接口对象就可以获得mapper.xml的sql语句。
  • 实现步骤:
    • 在mapper.xml中创建一个接口,包名和接口名为namespace中的值,接口中的方法名和mapper.xml的id属性一样。
    • 在mybatis.xml中使用<package>进行扫描接口。
      多参数实现方法步骤:
    • 在mybatis.xml中<mappers>中使用<package>
<mappers>
 		<package name="mapper"/>
</mappers>
  • 在mapper下新建接口
public interface LogMapper{
	List<Log> selAll();
	}
  • 在mapper.xml中新建LogMapper.xml。namespace必须和接口全限定路径一致,id值必须是和接口中的方法名一致,当接口中方法是多参数,,可省略parameterType
<mapper namespace="com.bjsxt.mapper.LogMapper">
	<insert id="ins" parameterType="log">
		insert into log values(default,#{accOut},#{accIn},#{money})
	</insert>
</mapper>

动态SQL

根据不同的条件需要执行不同的SQL命令。Mybatis中动态SQL在mapper.xml中添加逻辑判断。

  • if使用
<select id="selByAccinAccout" resultType="log">
		select * from log where 1=1
		OGNL表达式,直接写key或对象的属性.不需要添加任何特字符号
		<if test="accin!=null and accin!=''">
			and accin=#{accin}
		</if>
		<if test="accout!=null and accout!=''">
			and accout=#{accout}
		</if>
</select>
  • where
    如果内容中第一个是and去掉第一个and,如果where中有内容会生成where关键字,如果没有内容不生成where关键字。
<select id="selByAccinAccout" resultType="log">
		select * from log 
		<where>
			<if test="accin!=null and accin!=''">
				and accin=#{accin}
			</if>
			<if test="accout!=null and accout!=''">
				and accout=#{accout}
			</if>
		</where>
</select>
  • choose、when、otherwise
    只要有一个成立,其他都不执行。
<select id="selByAccinAccout" resultType="log">
		select * from log 
		<where>
			<choose>
				<when test="accin!=null and accin!=''">
					and accin=#{accin}
				</when>
				<when test="accout!=null and accout!=''">
					and accout=#{accout}
				</when>
			</choose>
		</where>
</select>
  • set用来修改SQL中的set语句。可以去掉最后一个逗号,如果set里面有内容生成set关键字,没有就不生成。
<update id="upd" parameterType="log" >
		update log 
		<set>
			id=#{id},
			<if test="accIn!=null and accIn!=''">
				accin=#{accIn},
			</if>
			<if test="accOut!=null and accOut!=''">
				accout=#{accOut},
			</if>
		</set>
		where id=#{id}
</update>
  • Trim
    prefix在前面添加内容,prefixOverrides去掉前面内容,suffix在后面添加内容,suffixOverrides去掉后面的内容。
<update id="upd" parameterType="log">
		update log
		<trim prefix="set" suffixOverrides=",">
		a=a,
		</trim>
		where id=100
</update>
<select id="selByLog" parameterType="log" resultType="log">
		select * from log
		<trim prefix="abc" prefixOverrides="abc">abc</trim>
</select>
  • bind
    作用:给参数重新赋值
    使用场景:模糊查询,在原内容的前后添加内容
<select id="selByLog" parameterType="log" resultType="log">
		<bind name="accin" value="'%'+accin+'%'"/>
		#{money}
</select>
  • foreach
    循环参数内容,在内容前后添加内容,加分隔符。
<select id="selIn" parameterType="list" resultType="log">
		select * from log where id in
		<foreach collection="list" item="abc" open="(" close=")" separator=",">
			#{abc}
		</foreach>
</select>
  • sql和include
    某些sql片段如果希望复用,使用sql定义该片段。
<sql id="mysql">
		id,accin,accout,money
</sql>

在select或delete或update或insert中使用include引用。

<select id="">
		 select <include refid="mysql"></include>
		 from log
</select>

ThreadLocal

线程容器,给线程绑定一个Object内容,以后只要线程不变,可以随时取出。改变线程无法取出内容。代码如下:
在这里插入图片描述

缓存

  • 应用程序和数据库交互的过程是一个相对比较耗时的过程。

  • 缓存存在的意义:让应用程序减少对数据库的访问,提升程序运行效率。

  • Mybatis中默认sqlSession缓存开启

    • 同一个sqlsession对象调用同一个select时,只有第一次访问数据库,之后把查询的结果缓存到sqlsession缓存区中。
    • 缓存的是statement对象。在mybatis中一个select对应一个statement对象。有效范围必须是同一个sqlsession对象。
  • 缓存流程

    • 先到缓存区中找到是否存在statement
    • 返回结果
    • 如果没有缓存statement对象,去数据库获取数据
    • 数据库返回查询结果
    • 将查询结果放到对应的缓存区中
      在这里插入图片描述
  • sqlSessionFactory缓存(二级缓存)

  • 范围:同一个factory内每个sqlsession都可以获取

  • 使用时间::当数据频繁使用,很少被修改

  • 步骤:

    • 在mapper.xml中添加,当不写readOnly=“true”需要把实体类序列化<cache readOnly="true"></cache>
  • 当 SqlSession 对象 close()时或 commit()时会把 SqlSession 缓存 的数据刷(flush)到 SqlSessionFactory 缓存区中。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值