原因:
servlet + jsp + db 性能低下
所以就有了 spring + mybatis + springmvc
1.为什么使用框架技术?
通过框架来制定开发规范,
更进一步保证所有开发人员能够快速编写出统一的代码,
让开发人员专注于业务实现。
2.常用框架技术?(SSM)
SSJ 》 spring + springmvc + jdbc
SSH 》spring + structs2 + hibernate
SSM 》spring + springmvc+ mybatis
ssm 最常用 ssh不常用,几乎没了 ssj不用
2.1 Spring
Spring是一个J2EE的框架,这个框架提供了对轻量级IOC的良好支持,
同时也提供了对AOP技术非常好的封装,相比于其他的框架,
Spring框架的设计更加模块化,框架内的每个模块都能完成特定的工作,
而且各个模块可以独立的运行,不会相互的前置,
因此,在使用Spring框架的时候,我们可以使用整个框架,
也可以使用框架中的一部分。
spring是粘合剂 把 springmvc和mybatis产生联系
注意:
1.IOC》 控制反转(依赖注入)》 一种设计思想
IOC理论提出的观点大体是这样的:
借助于“第三方”实现具有依赖关系的对象之间的解耦。
2.AOP (面向切面编程)
AspectJ 框架 最牛逼的框架 专门的人做专门的事
2.2 SpringMVC 前端和后端组合起来
Spring MVC是一个基于Java的实现了MVC设计模式
的请求驱动类型的轻量级Web框架,
通过把Model,View,Controller分离,
将web层进行职责解耦,
把复杂的web应用分成逻辑清晰的几部分,
简化开发,减少出错,方便组内开发人员之间的配合。
2.3 Mybatis (封装jdbc的作用)
Mybatis是一个半ORM(对象关系映射)框架,
它内部封装了JDBC,开发时只需要关注SQL语句本身,
不需要花费精力
去处理加载驱动、创建连接、创建statement等繁杂的过程。
程序员直接编写原生态sql,
可以严格控制sql执行性能,灵活度高。
3.Mybatis框架
实体类和表中间的那个ORM
3.1Mybatis背景
MyBatis前身是iBatis,本是Apache的一个开源的项目
3.2Mybatis拓展
ORM框架,(只要提供了持久化类与表的映射关系,
ORM框架在运行时就能参照映射文件的信息,把对象持久化到数据库中)
3.3Mybatis特点
1.基于SQL语法,简单易学
2.SQL语句封装在配置文件中,便于统一管理与维护,降低程序的耦合度
3.4Mybatis组成部分
(1)核心对象
SqlSessionFactoryBuilder:
MyBatis应用的核心: SqlSessionFactory
SqlSession ==》执行sql语句
通过第一个创建第二个,第二个创建第三个,但我们只用第三个。
(2)核心配置文件 (实体类映射表的)
mybatis-config.xml
//默认的运行环境 ID //运行环境 ID //事务管理器配置 //数据源配置
(3)sql映射文件 映射实体类和我们的数据类表的
select count(1) from user
4.mybatis实战
1.数据库/表t_person
2.创建工程
main/java,main/resources,test/java
3.加入依赖pom.xml
org.mybatis mybatis 3.5.1 mysql mysql-connector-java 8.0.21
3.创建实体类Person.java
cn.kgc.entity/Person
package cn.kgc.entity;
public class Person {
private Integer id;
private String name;
private String nickname;
private Integer age;
//省略getter和setter方法
}
4.创建mapper接口(即dao接口)
cn.kgc.mapper/PersonMapper.java
package cn.kgc.mapper;
import cn.kgc.entity.Person;
//xml名字和这个一模一样,xml才能映射过来
public interface PersonMapper {
//定义查询记录数方法
Integer findCount();
//增加功能
Integer addPerson(Person person);
//修改功能
Integer updatePerson(Person person);
//删除功能
Integer delById(Integer id);
//通过id查询对象
Person findById(Integer id);
//查询所有
List findAll();
//模糊查询
List findByName(String name);
//通过用户名和昵称 绝对查询
List findByPerson(Person person);
//通过用户名和昵称 绝对查询2
List findByPerson2(@Param("name") String name,@Param("nickname") String nickname);
}
注意点:
==>绝对查询2
这里是根据注解来替换的,
并且在PersonMapper.xml不用写parameterType
@Param注解的使用和解析(摘录)
作用: 用注解来简化xml配置的时候
(比如Mybatis的Mapper.xml中的sql参数引入),
@Param注解的作用是给参数命名,
参数命名后就能根据名字得到参数值,正确的将参数传入sql语句中
(一般通过#{}的方式,${}会有sql注入的问题)。
5.创建mybatis映射文件
resources/cn.kgc.mapper/PersonMapper.xml
6.创建mybatis主配置文件
resources/ mybatis-config.xml
dataSource的类型可以配置成其内置类型之一,
如UNPOOLED、POOLED、JNDI。
7.测试类TestMybatis.java
test/cn.kgc.test/ TestMybatis.java
package cn.kgc.test;
import cn.kgc.entity.Person;
import cn.kgc.mapper.PersonMapper;
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 TestMybatis {
@Test
public void testHelloWorld() throws IOException {
//1.定义配置文件
String config = "mybatis-config.xml";
//2.读取配置文件 ==》通过流的机制获取主配置文件mybatis -config . xml的主配置信息
InputStream in = Resources.getResourceAsStream(config);
//3.创建(实例化)SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//4.调用builder对象的build ()方法创建SqlSessionFactory对象
SqlSessionFactory factory = builder.build(in);
//5.调用factory对象的openSession()方法 获取sqlSession对象
SqlSession sqlSession = factory.openSession();
//6. 调用接口方法 执行sql语句
Integer count = sqlSession.getMapper(PersonMapper.class).findCount();
//输出对应的返回值count
System.out.println("count:"+count);
//7.关闭sqlSession对象
sqlSession.close();
}
@Test
public void testInsert() throws Exception{
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession sqlSession = factory.openSession();
//调用 接口 方法
Person p = new Person();
p.setName("张三");
p.setAge(35);
p.setNickname("小张啊");
sqlSession.getMapper(PersonMapper.class).addPerson(p);
// 默认是不提交给数据库 需要手动加 增删改
//如果不写 数据库没添加 但id自增长 id就自动多加一位了
sqlSession.commit();//提交事务,该行代码务必放在关闭sqlSession之前
sqlSession.close();
}
@Test
public void testUpdate() throws Exception{
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession sqlSession = factory.openSession();
Person p = new Person();
p.setId(5);
p.setName("小蓝");
p.setNickname("兰兰");
p.setAge(19);
sqlSession.getMapper(PersonMapper.class).updatePerson(p);
sqlSession.commit();
sqlSession.close();
}
@Test
public void testDel() throws Exception {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession sqlSession = factory.openSession();
sqlSession.getMapper(PersonMapper.class).delById(5);
sqlSession.commit();
sqlSession.close();
}
@Test
public void testFindById() throws Exception {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession sqlSession = factory.openSession();
Person p = sqlSession.getMapper(PersonMapper.class).findById(7);
System.out.println("id:" + p.getId() + " name:" + p.getName() + " nickname:" + p.getNickname() +" age:" + p.getAge());
sqlSession.close();
}
@Test
public void testFindAll() throws Exception {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession sqlSession = factory.openSession();
List list = sqlSession.getMapper(PersonMapper.class).findAll();
for (Person p : list) {
System.out.println("name:" + p.getName() + "t" +"nickname:" + p.getNickname() + "t" +"age:" + p.getAge());
}
sqlSession.close();
}
@Test
public void testFindByName() throws Exception {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession sqlSession = factory.openSession();
List list = sqlSession.getMapper(PersonMapper.class).findByName("x");
for (Person p : list) {
System.out.println("name:" + p.getName() + "t" +"nickname:" + p.getNickname() + "t" +"age:" + p.getAge());
}
sqlSession.close();
}
@Test
public void testFindByPerson2() throws Exception {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession sqlSession = factory.openSession();
List list = sqlSession.getMapper(PersonMapper.class).findByPerson2("wangwu","ww");
for (Person p :
list) {
System.out.println("name:" + p.getName() + "t" +"nickname:" + p.getNickname() + "t" +"age:" + p.getAge());
}
sqlSession.close();
}
}
//<== Total: 1 1个返回值
注意点:
如果报错了,可能是文件夹的问题
记得一个一个创建文件夹。先cn 再kgc再mapper
8.测试
附注:
工程目录结构
注意: 加入日志mybatis-config.xml
logImpl 指定MyBatis所用日志的具体实现,未指定时将自动查找。
STDOUT_LOGGING是标准日志。mybatis自带的
testFindByPerson2()==》
10.测试
升级版,上面的太冗余,下面相当于是优化
11.工具类: cn.kgc.util/MybatisUtil.java
package cn.kgc.util;
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 MyBatisUtil {
private static SqlSessionFactory factory = null;
static {
try {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
factory = builder.build(in);
} catch (IOException e) {
e.printStackTrace();
}
}
// 获取SqlSession
public static SqlSession getSqlSession(){
SqlSession sqlSession = null;
if (factory != null){
sqlSession = factory.openSession();
}
return sqlSession;
}
}
12.测试cn.kgc.test/TestMybatis2.java
》 针对于Integer findCount();
@Test
public void testFindCount(){
SqlSession sqlSession = MyBatisUtil.getSqlSession();
Integer count = sqlSession.getMapper(PersonMapper.class).findCount();
System.out.println(count);
}
13.#和$不同应用场景(面试题 很重要)
#:占位符 语法: 替换值
$: 字符串替换 语法: 替换表名/列名/不同列排序等
$ 不安全: Statement(依赖注入)
# 安全: PreparedStatement
A.PersonMapper.java
public ListfindColList(@Param("colName") String colName);
B.PersonMapper.xml
select * from t_person order by ${colName}
C.TestMybatis
@Test
public void testFindColList(){
SqlSession sqlSession = MyBatisUtil.getSqlSession();
List age = sqlSession.getMapper(PersonMapper.class).findColList("age");
for (Person p : age) {
System.out.println("name:" + p.getName() + "t" +"nickname:" + p.getNickname() + "t" +"age:" + p.getAge());
}
sqlSession.close();
}
结果就是根据age升序排序。
再次优化:
14.使用配置文件
A,resources/jdbc.properties
driver=com.mysql.cj.jdbc.Driver url=jdbc:mysql://localhost:3306/db_mb001?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true username=root password=zjj
B,mybatis-config.xml
。。。省略… (settings标签上面) 。。。mappers标签
附注:
题外话:
1.如何使用Lombok
pom.xml里导入Lombok依赖
org.projectlombok lombok 1.18.20 provided
用处就是可以不用打getter和setter方法
不用打有参和无参方法和toString方法等等
import lombok.*;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class User {
private String name;
private String pwd;
}
2.有下面依赖就可以在resources里创建
spring-config.xml
org.springframework spring-webmvc 5.3.12
XML Configuration File -> Spring Config
3.什么是mybatis?(面试题)
一种持久层框架,类似于JDBC访问数据库的操作,
我们说JDBC使用到的对象有Connection对象,
PreparedStatement对象, ResultSet对象。
而Mybatis框架的核心对象有SqISessionFactoryBuilder对象,
SqISessionFactory对象, SqlSession对象。
并且myibatis框架和hibernate框架最大的区别
就在于mybatis它的灵活性比较高。
4.什么是spring?(面试题)
1.在spring出来之前,service层调用dao层都是 用new的方式。
2.在Sspring出来之后,service层和dao层都会放在spring容器去管理,
这是spring的第一种特性,我们称之为IOC,控制反转。
3.spring还有一种特性, 我们称之为AOP,大白话,“面向切面”,
说白了就是专门的人干专门的事。在项目很多公有的或是
要被重复被调用的模块可以被抽取出来,
利用的就是AOP的特性,例如日志模块。
----2021.11.25&11.26&11.27



