准备实习之前打算整理一下自己的ssm自学笔记,最近在看spring源码好难= =。希望通过源码巩固自己的知识吧,秋招加油。另外说一句Typora记事本yyds,超级好用。可以梳理段落还有很多快捷键极力推荐。如果有需要改正的东西,欢迎交流。
Mybatis
一:Mybatis的基本介绍
1.三层架构
界面层:主要用来接收用户的数据 用户使用程序前端界面HTML CSS js
业务逻辑层:接收表示传递过来的数据,显示请求的处理结果,计算逻辑,调用数据库
数据访问层:就是访问数据库,执行对数据的查询,修改,删除等等
三层的处理请求的交互:
用户->界面层->业务逻辑层->数据访问层->数据库
三层对应的包
界面层:controller包(Servlet)
业务逻辑层:service包(xxxService)
数据访问层:dao包(XXXDao类)
2.框架
界面层:使用SpringMVC
业务逻辑层: Spring
数据访问层:Mybatis
框架是一个舞台,一个模板
模板:
1.规定了一些条款和内容
2.加入自己的东西
框架可以看作是一个模块
1.框架中定义了一些功能,这些功能是可用的。
2.可以假如项目中自己的功能,这些功能可以利用框架中写好的功能
框架是一个软件,半成品的软件,定义好一些基础功能,需要加入你自己的功能就是完整的,基础功能是可重复使用的,可升级的。
框架的特点:
1.框架一般不是全能的,不能做所有的事情
2.框架是针对一个领域有效,特长在某一个方面,比如Mybatis做数据库操作强,但不能做其他的
3.框架是一个软件
3.JDBC的缺陷
1.代码比较多,开发效率低
2.需要关注Connection,Statement,ResultSet对象创建和销毁
3.对ResultSet查询的结果,需要自己封装为list
4.重复的代码比较多
5.业务代码和数据库操作混在一起
4.Mybatis提供了哪些功能
1.提供了创建Connection,Statement,Resultset的能力,不需要开发人员创建了
2.提供了执行sql语句的能力,不需要你来执行sql
3.提供了循环sql,把sql的结果转为java对象,list集合的能力
4.提供了关闭资源的能力,不用你关闭Connection,Statement,ResultSet
开发人员只需要提供sql语句-mybatis处理sql–开发人员的到list集合或java对象
5.实现步骤:
1.新建student表
2.加入maven的mybatis坐标,mysql驱动的坐标
3.创建实体类,student–保存表中的一行数据
package com.bjpowernode.domain;
public class Student {
private Integer id;
private String name;
private String email;
private Integer age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
", age=" + age +
'}';
}
}
4.创建持久层的dao接口,定义操作数据库的方法
package com.bjpowernode.dao;
import com.bjpowernode.domain.Student;
import java.util.List;
public interface StudentDao {
//查询student所有数据
public List<Student > selectStudents();
}
5.创建mapper文件
也叫做sql的映射文件:写sql语句的。一般一个表一个sql映射文件这个文件是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.bjpowernode.dao.StudentDao">
<!-- select表示查询操作。
id: 你要执行的sql语法的唯一标识,mybatis会用这个id的值来找到要执行的sql语句,可以自定义,但是最好使用接口中的方法名称
resultType:表示结果类型,是sql语句执行后得到resultset,遍历这个resultset得到java对象的类型。要写类的全限定名称
-->
<select id="selectStudents" resultType="com.bjpowernode.domain.Student">
select id,name,email,age from student order by id
</select>
</mapper>
<!--
sql映射文件,:写sql,mybatis会执行sql
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">指定约束文件
2.约束文件作用:限制,检查在当前文件中出现的标签,属性必须符合mybatis的要求。
3.mapper是当前文件的根标签
namespace是命名空间,唯一的,可以是自定义的字符串。要求你使用dao接口的全限定名称。
4.在当前文件中可以使用特定的标签进行数据库的特定操作
<select>
<delete>
<insert>
<insert>
-->
6.配置mybatis的主配置文件:
一个项目就一个主配置文件
主配置文件提供了数据库的连接信息和sql映射文件的位置信息
<?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">
<!--
一个数据库信息的配置,环境
id:唯一值,自定义,表示环境的名称
告诉mybatis使用哪个数据库
-->
<environment id="development">
<!--表示事务的类型
使用jdbc中的commit和rollback进行事务处理
-->
<transactionManager type="JDBC"/>
<!--
dataSource表示数据源,连接数据库的类型 pooled表示池化
-->
<dataSource type="POOLED">
<!--
driver url,username password是固定的,不能自定义
-->
<!--
数据库的驱动类名
-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!--连接数据库的url字符串-->
<property name="url" value="jdbc:mysql://loclhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!--sql映射文件的位置-->
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
<!--一个mapper标签指定一个文件的位置
从类路径开始的路径信息-->
</mappers>
</configuration>
<!--
mybatis主配置文件:主要定义了数据库的配置信息,sql映射的位置
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
ybatis-3-config.dtd配置文件,固定值
<configuration>环境配置标签
-->
7.创建使用mybatis类
通过mybatis访问数据库
public static void main(String[] args) throws IOException {
//1.定义mybatis主配置文件的名称
String config="mybatis.xml";
//2.读取这个文件
InputStream in = Resources.getResourceAsStream(config);
//3.创建SqlSessionFactoryBuileder对象
SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
//4.创建sqlSessionFactory对象
SqlSessionFactory factory=builder.build(in);
//5.获取sqlsession对象,从sqlSessionFactory中获取Sqlsession
SqlSession sqlSession=factory.openSession();
//6.指定要执行的sql语句的表示。sql映射文件中的namespace+ "."+标签的id值
String sqlid="com.bjpowernode.dao.StudentDao"+"."+"selectStudents";
//7.执行sql语句,通过sqlid找到语句
List<Student> studentList=sqlSession.selectList(sqlid);//该方法得到多条记录
//8.输出结果
studentList.forEach(student -> System.out.println(student));
//9.关闭sqlsession对象
sqlSession.close();
}
6.添加日志
在配置文件中添加命令
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
二:
1.主要类的介绍
1):Resorces:mybaits中的一个类,负责读取主配置文件
InputStream in=Resorces.getResourceAstream(“mybatis.xml”);
2):SqlSessionFacoryBuilder :创建SqlSessionFactory对象
SqlSessionBuiler builder=new SqlSessionBuilder();
//创建SqlSessionFactory对象
SqlSessionFactory factory=builder.build(in);
3):SqlSessionFactory:
重量级对象,程序创建一个对象耗时比较长,使用资源比较多,在整个项目中有一个就够用了。
SqlSessionFactory:接口,接口实现类:DefaultSqlSessionFactory
SqlSessionFactory作用:获取SqlSession对象。 SqlSession sqlsession=factory.openSession();
openSession()方法说明:
1.openSession():无参数的,获取的非自动提交事务的SqlSession对象
2.openSession(boolean) true自动提交
4):SqlSession
SqlSession接口:定义了操作数据的方法,
SqlSession接口的实现类DefaultSqlSession
使用要求:sqlsession对象不是安全的,需要在方法内部使用,在执行sql语句之前,使用openSession获取Sqlsession对象,在执行完需要关闭,执行SqlSession.close()
2.使用动态代理的条件分析
package com.bjpowernode;
import com.bjpowernode.dao.StudentDao.StudentDao;
import com.bjpowernode.dao.impl.StudentDaoImpl;
import com.bjpowernode.domain.Student;
import org.junit.Test;
import java.util.List;
public class TestMybatis {
@Test
public void TestselectStudents(){
StudentDao dao=new StudentDaoImpl();
List<Student> studentList=dao.selectStudents();
for (Student stu:studentList){
System.out.println(stu);
}
}
}
List studentList=dao.selectStudents();调用
1.dao对象
类型是StudentDao,全限定名称是:com.bjpowernode.dao.StudentDao
全限定名称和namespace是一样的
2.方法名称selecStudents
方法是mapper文件中的id值selectStudents
3.如果dao中方法的返回值可以确定是Mybatis调用的SqlSession方法
如果返回值是List,调用的是SqlSession.selectList()方法
如果返回值int或是非list,看maapper文件中的标签是,就会调用SqlSession的insert,update方法
mybatis的动态管理:mybatis根据dao的方法调用,获取执行sql语句的信息
mybatis根据dao接口,创建出dao接口的实现类,并创建这个类的对象。完成sqlSession调用方法,访问数据库
4.动态代理的实现步骤
1.获取sqlsession对象
sqlSession=factory.openSession();
2.使用sqlSession的getmapper方法
StudentDao dao= sqlSession.getMapper(StudentDao.class);//接口的类文件
3.使用dao接口中的方法,执行mapper的sql语句
5.使用动态代理的要求
1.接口和mapper文件名一致studentdao studentdao.xml
2.接口类和mapper文件在同一目录下
3.mapper文件中的namespace是接口的全限定名称
4.mapper文件中对应的接口中的方法 selectid=“接口中的方法”
三:
理解参数
1.在mapper文件中可以使用paremeterType,设置接口中方法参数的类型
<select id="selectStudentsById" parameterType="java.lang.Integer" resultType="com.bjpowernode.domain.Student">
select name,age,email,age from student where id=#{id}
</select>
2,一个简单类型的参数:
简单类型:mybatis把java的基本数据类型和String都叫简单类型
在mapper文件获取简单类型的一个参数值,使用#{任意字符}
传参方法
1.多个参数利用@param命名参数
接口public List selectMultiParam(@param:“myname” String name,@param"myage" int age)
在mapper文件中占位符填进去自定义命名参数
2.使用java对象传参
在mapper文件中属性值=#{属性名,javaType,JDBCType的值}
简化版=#{属性名}
3.按位置传递参数
<list> Students selectbylocation(String name,Integer age)
<mapper>select id="selectbylocation" ResultType="com.bjpowernode.domain.Student"
select * from student where name=#{arg0} age=#{arg1}
4.使用map传传递参数
在接口方法中李用map传递参数
#和$
#和$占位符(使用preparedstament对象)效率比较高,比较安全
select * from student where id=#{studentID}
在日志中用?进行占位
select * from student where id=${studentID}(使用statement对象)效率比较低可能出现sql注入
结果为id=1001
但$占位符可以替换表名或列名,前提是要在保证数据安全的条件下
四:mybatis的返回结果
mybatis执行了sql,得到了Java对象
1.resultType结果类型:
指将sql语句执行完毕后,数据转为java对象,Java类型是i任意的
结果类型的值:1.类的全限定名称,2.类名的别名
2.处理方式:
1.mybatis执行sql语句,然后mybatis调用类的无参构造方法,创建对象
2.mybatis把resultSet指定值赋给同名的属性
3.自定义resultType:
在配置文件中
<typeAliases>
<typeAlias type="com.bj5powernode.domain.Student" alias="stu"/>
<typeAlias type="com.bjpowernode.vo.Viewstudent" alias="vstu"/>
</typeAliases>
2.此方法别名为包下的类名,但建议使用全限定名称,这样更具有确定性
<typeAliases>
<package name="com.bjpowernode.vo"/>
</typeAliases>
4.返回map
1)列名是map的key,列值是map的value
2)返回map时,最多只能返回一条记录,多于一条是错误的
4.列名和属性名不一致时
方法一
<resultMap id="studentMap" type="com.bjpowernode.domain.Student">
<id column="id" property="id"/>
<result column="name" property="name"/>
</resultMap>
方法二
<select id="selectmystudent" resultType="com.bjpowernode.domain.Mystudent">
select id as sid,name as sna,email as semail,age as sage from student
</select>
5.模糊查询
方法一:
用java代码指定like的内容
用占位符,将属性name赋值之后,传入方法中
方法二:
在mapper中拼接
where name like"%" #{name} “%”
五:动态SQL
动态sql:sql的内容是变化的,可以根据条件获取不同的sql语句
主要是where部分发生变化
动态sql的实现,使用的是mybatis提供的标签,
语法
部分sql语句
1.if标签
<select id="selectStudentif" resultType="com.bjpowernode.domain.Student">
select id,name,age,email from student
where
<if test="name!=null and name!='' ">
name =#{name }
</if>
<if test="age>0">
and age=#{age}
</if>
</select>
2.where标签
标签里面有多个if,如果有一个if判断为true,会在sql后加入where关键字,会去掉无用的and,or等字符
<select id="selectStudentwhere" resultType="com.bjpowernode.domain.Student">
select id,name,age,email from student
<where>
<if test="name!=null and name!='' ">
name =#{name }
</if>
<if test="age>0">
or age>#{age}
</if>
</where>
</select>
3.foreach标签
<foreach collection="" item="" open="" close="" separator="">
</foreach>
collection:表示接口中方法参数的类型,如果数组使用array,如果是list集合使用list
item:自定义的,表示数组和集合成员的变量
open:循环开始时的字符
close:循环结束的分隔符
separator:数组元素之间的分隔符
<select id="selectStudentforeachtwo" resultType="com.bjpowernode.domain.Student">
select * from student where id in
<foreach collection="list" item="stu" open="(" close=")" separator=",">
#{stu.id}
</foreach>
</select>
4.sql代码片段
作用:复用一些语句
步骤:
1.先定义<sql id=“自定义唯一名称” sql语句 ,表名,字段等>
2.再使用
六:mybatis系统配置
<transactionManager type="JDBC"/>
表示事务处理机制
2.managed:把mybatis的事务处理委托给其他容器(一个服务器软件,一个框架)
<dataSource type="POOLED">
datasource:表示数据源,java体系中,规定实现了javax.sql.datasource接口的都是数据源
数据源表示connection对象的
1.pooled:使用连接池,mybatis会创建pooledDataSource类
2.UNPOOLED:不使用连接池,在每次执行sql语句,先创建连接,执行sql,在关闭连接mybatis会创建一个UnpooledDataResource,管理connection对象
3.JNDI:java命名和目录服务(windows注册表)
七:
1.数据库的属性配置文件
把数据库连接信息放在单独一个文件中。和mybatis主配置文件分开,目的是便于修改,保存处理多个数据库的信息。
1)在resources目录中定义一个属性配置文件,
xxx.properties,在属性配置文件定义数据,格式时key=value
key:一般使用,做多级目录的
2)在mybatis的主配置文件,
使用指定文件的位置
在需要使用值的地方${key}
3)多个mapper文件
方法二:使用包名
name:xml文件所在的包名,这个包中的所有xml文件都能加载给mybatis
使用package要满足
mapper文件名称需要与接口名称一样,区分大小写一样
2.mapper文件和dao接口需要在同一目录
4)PageHelper分页
PageHelper进行数据分页
在测试方法中使用
public void Testselectall() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
PageHelper.startPage(2, 2);
//第一个参数表示第几页,第二个参数表示每页的容量
List<Student> students=dao.selectall();
for(Student stu:students){
System.out.println("foreach"+stu);
}
}
八:mybatis一二级缓存
一级缓存是sqlsession级别,默认开启且不能关闭
操作数据库需要创建sqlSession对象,对象中有一个hashMap存储缓存数据,不同sqlsession之间缓存数据区域互不影响
一级缓存的作用域是sqlsession范围内的,在同一个sqlsession中执行两次相同的sql语句时,第一个语句执行会把数据存储在缓存中,第二次查询可以直接在缓存中获取
二级缓存
平时mapper级别默认关闭,多个sqlsession使用同一个mapper的sql语句操作数据库,会存在二级缓存区。