mvc: web开发中使用mvc模式。m:数据;v:视图;c:控制器
c控制器:接收请求,调用servlet对象,显示请求处理的结果,当前使用servlet作为控制器
v视图:目前使用jsp,html,css,js.显示请求的处理结果,把m中数据展示出来
m数据:来自数据库mysql,来自文件,来自网络。
mvc作用:
- 实现解耦合
- 让mvc各司其职
- 使得系统扩展更好
三层架构:
- 界面层(视图层):接收用户的请求,调用service,显示请求的处理结果的包含了jsp,servlet,html等对象
- 业务逻辑层:处理业务逻辑,使用算法处理数据的。将数据返回给界面层,对应的是service包和包中的很多XXService类,例如:StudentService,OrderService
- 持久层(数据库访问):访问数据库,或者读取文件,访问网络,获取对象,对应的包是dao包。dao包中很多的StudentDao,OrderDao,ShopDao等。
用户发起请求—>界面层----->业务逻辑层----->持久层----->数据库
3.为什么使用三层架构?- 结构清晰
- 可维护性高
- 有利于标准化
- 开发人员可以只关注整个结构的其中某一层的功能实现
- 有利于各层逻辑的复用
每一层对应一个框架
1)界面层—SpringMVC框架(3天)
2)业务层—Spring框架(4.5-5天)
3)持久层—MyBatis(2.5-3天)
5.框架1) 什么是框架
框架:就是一个软件,完成了部分的功能。软件中的类和类之间的方法调用都已经规定好了。通过这些可以完成某些功能。框架可以看作是一个模板。
框架是可以升级的,改造的,框架是安全的
框架是对某一方面有用的,不是全能的。
6.框架解决的问题-
框架能实现技术的整合
-
提升开发效率,降低难度
优点:
- 直观,易理解,易上手
缺点:
- 创建很多对象Connection,Statement,ResultSet
- 注册驱动
- 执行sql语句
- 把resultSet转为Student,List集合
- 关闭资源
- sql语句和业务逻辑混在一起
概述:
Mybatis是一个持久层框架,本是apache的一个开源项目 iBatis,2010年这个项目有apache software foundation 迁移到了google code,并且改名为MyBatis。2013年11月项目迁移到了GitHub。
Mybatis能够操作数据库,对数据库进行增删改查。可以看作高级的jdbc,解决jdbc的缺点
MyBtis能做什么
- 注册驱动
- 创建jdbc中使用的Connection,Statement,ResultSet
- 执行sql语句,得到ResultSet
- 处理ResultSet,把记录集中的数据转为java对象,同时能把java对象放入到List集合中
- 关闭资源
- 实现sql语句和java代码的解耦合
官网:https://mybatis.org/mybatis-3/zh/index.html
第二章 Mybatis入门 2.1第一个例子实现步骤:
-
创建student表(id,name,email,age)
-
创建maven项目
-
修改pom.xml
1) 加入mybatis依赖
org.mybatis mybatis 3.5.1 2) 再标签中加入资源插件
src/main/java/ ***.properties false -
创建实体类Student,定义属性,属性名和列名一致
-
创建Dao接口,定义操作数据库的方法
-
创建xml文件(mapper文件),写sql语句
mybatis框架推荐按使用是把sql语句和java代码分开
mapper文件:定义和dao接口再同一目录,一个表一个mapper文件
select * from Blog where id = #{id} -
创建mybatis主配置文件
1)定义创建连接实例的数据源(DataSource对象)
2)指定其他mapper文件的位置
-
创建测试的内容
使用main方法,测试mybatis访问数据库
也可以使用junit访问数据库
1.自动提交:当你的SQL语句执行完毕后,提交事务。数据库更新操作直接保存数据
创建mapper文件模板
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n2hx1TNU-1633593739857)(C:UserslinhuashangAppDataRoamingTyporatypora-user-imagesimage-20211006101857855.png)]
第三章 Mybatis的代理 3.1Dao代理 3.1.1 mybatis提供代理:mybatis框架创建Dao接口的实现类对象,完成对sql语句的执行
换言之:mybatis创建一个对象代替你的dao实现类功能。
3.1.2 使用mybatis代理要求:1.mapper文件中的sapcename必须是dao接口的全限定名称
2.mapper文件中标签的id是到接口中的方法名称(二者必须完全一致)
使用SqlSession对象的方法getMapper(dao.class)
例如:现有StudentDao接口
SqlSession sqlSession=MyUtil.getSqlSession(); StudentDao studentDao=sqlSession.getMapper(StudentDao.class); Student student=studentDao.selectById(1001); //上述代码中 StudentDao studentDao=sqlSession.getMapper(StudentDao.class); //等同于 StudentDao studenrDao=new StudentDaoImpl(); //StudentDaoImpl:StudentDao接口的实现类3.2 理解参数
理解参数是:通过java程序把数据传入到mapper文件中的sql语句。参数主要指的是dao接口方法的形参
3.2.1 parameterTypeparameterType:表示参数类型,指定dao方法的形参数据类型。这个形参的数据类型是给mybatis使用。
mybatis在给sql语句的参数赋值时使用。PreparedStatement.setXXX(位置,值)
select id,name,email,age from student where id=#{studentId};
3.2.2 dao接口方法参数为简单数据类型
//dao接口的方法形参是一个简单类型 //简单类型:java基本数据类型和String Student selectByEmail(String email);
mapper文件
3.2.3 dao接口方法有多个简单类型参数@Param:命名参数。在方法形参前使用,定义参数名。这个名称可以用在mapper中
dao接口方法定义:
mapper文件写法:
List3.2.4 dao接口方法使用一个对象作为参数selectByNameOrEmail(@Param("myName") String name,@Param("myEmail") String email);
方法的形参是一个Java对象,这个java对象表示多个参数,使用对象的属性值作为参数使用。
ListselectByObject(Student student);
mapper文件:
3.25 复杂的获取属性值语法:#{property,javaType=java中数据类型名,jdbcType=数据类型名称(数据库中的类型)}
3.2.6 Dao接口中多个简单类型参数,按位置传递参数(了解)参数位置:dao接口中方法的形参列表,从左往右,参数位置是0,1,…
语法格式:#{arg0},#{arg1},#{arg2},#{arg3},(mybatis 3.4以后支持)依次代表参数1,参数2,…
不建议使用(代码可读性不好)
dao接口的方法
ListselectByPosition(String name,Integer age);
mapper文件
3.2.6 dao接口参数是map(了解)ListselectStudentByMap(Map map);
mapper文件
测试代码
@Testpublic void testSelectByMap(){ SqlSession sqlSession=MyBatisUtil.getSqlSession(); StudentDao dao=sqlSession.getMapper(StudentDao.class); Student st=new Student(1001,"宋江","songjiang@qq.com",23); Map data=new HashMap<>(); data.put("myname","宋江"); data.put("myage",20); List list=dao.selectStudentByMap(data); for(Student s:list){ System.out.println(s); } sqlSession.close();}
依然不建议使用
3.2.7 #和$区别 1. 语法:#{字符}mybatis处理#{}使用jdbc对象是PreparedStatement对象
#{}特点:
- 使用的PreparedStatement对象,执行SQL语句,效率高
- 使用的PreparedStatement对象,能避免sql注入,sql语句执行更安全
- #{}常常作为列值使用,位于等号的右侧,#{}位置的值和数据类型有关
语法:${字符}
mybatis执行${}占位符的sql语句
select id,name,email,age from student where id=${studentId} ${}表示字符串连接,把sql语句的其他内容和${}内容使用字符串连接的方式连在一起String sql="select id,name,email,age from student where id="+"1001";mybatis创建的是Statement对象,执行sql语句Statement stmt=conn.createStatement(sql);ResultSet rs=stmt.excuteQuery();//执行sql语句
${}特点
- 使用Statement对象,执行sql语句,效率低
- ${}占位符的值,使用的是字符串拼接,有sql注入危险,有代码安全问题
- ${}数据是原样使用的,不会区分数据类型
- 常 用 在 表 名 或 列 明 , 在 保 证 数 据 安 全 的 前 提 下 使 用 {}常用在表名或列明,在保证数据安全的前提下使用 常用在表名或列明,在保证数据安全的前提下使用{}
使用大体与#{}类似;
注意:
- dao接口简单参数必须使用@Param()
- ${}数据是原样使用的;若传入参数为“lisi”,
select id,name,email,age from student where id=${studentname}
则执行sql语句:
select id,name,email,age from student where id=lisi
而不是
select id,name,email,age from student where id=‘lisi’
-
同样,按列名排序使用${}而不使用#{};
select id,name,email,age from student orderby ${param}(param变量,可从方法参数传入以实现按不同列排序)
封装输出结果:MyBatis执行sql语句后,得到ResultSet,转为java对象。
有两个:resultType,resultMap
3.3.1 resultTyperesultType属性:在执行select时使用,作为标签的属性出现的
result Type:表示结果类型,mysql执行sql语句,得到java对象的类型,它的值有两种:
- java的全限定名称
- 使用别名
1)resultType表示java自定义对象
2)resultType表示简单类型
dao接口方法
long countStudent();
mapper文件
3)resultType表示map结构
dao接口
Map
mapper文件
3.4.2 resultMapresultMap:结果映射。自定义列表和java对象属性的对应关系。常用在列表名和属性名不同的情况
用法:
-
先定义resultMap标签,指定列名和属性名对应关系
-
在select标签中使用resultMap属性,指上面定义的resultMap的id
MyBatis提供的对java类型简短定义,名称好记
自定义别名的步骤:
-
在MyBatis的主配置文件,使用typeAliase标签声明别名
-
在mapper文件中,resultType=“别名”
第一种方式
第二种方式
建议使用全限定名称,可读性好。
3.6 列名与java对象属性名称不一样解决方式- 使用resultMap:自定义列名和属性名称对应关系
- 使用resultType:使用列的别名,使列的别名与对象属性名相同。
第一种方式:在java程序中,把like的内容组装好,把这个内容传入到sql语句
dao
//模糊查询第一种方式ListselectLikeOne(@Param("name") String name);
mapper
测试代码
@Testpublic void testSelectLikeOne(){ SqlSession sqlSession=MyBatisUtil.getSqlSession(); StudentDao dao=sqlSession.getMapper(StudentDao.class); String name="%李%"; List stus=dao.selectLikeOne(name); for(Student s:stus){ System.out.println(s); } sqlSession.close();}
第二种方式:在sql语句中组织like的内容
sql语句中like的格式:where name like “%“空格#{name}空格”%”
dao
ListselectLikeTwo(@Param("name1") String name);
mapper
Test
@Testpublic void testSelectLikeTwo(){ SqlSession sqlSession=MyBatisUtil.getSqlSession(); StudentDao dao=sqlSession.getMapper(StudentDao.class); String name="李"; List stus=dao.selectLikeTwo(name); for(Student s:stus){ System.out.println(s); } sqlSession.close();}
第四章 动态sql
什么是动态sql:同一个dao的方法,跟进不同的条件可以表示不同的sql语句,主要是where部分变化
使用mybatis提供的标签,实现动态sql,主要学习if,where,foreach,sql。
使用动态sql时dao方法的形参要使用java对象
4.1 if语法:可以有多个if,没有else
主要用于多条件查询。
sql代码 sql代码 sql代码 在mapper文件中
注意sql语句中小于号”<" 报错使用实体
实体符号表
| < | 小于 | < |
|---|---|---|
| > | 大于 | > |
| <= | 小于等于 | <= |
| >= | 大于等于 | >= |
使用if标签时,容易引起sql语法错误,使用where标签可以解决if产生的语法问题
使用where时,里面是一个或多个if条件,当有一个if标签判断条件为true,where标签会转为where关键字附加到sql语句后面,如果没有一个if条件为true,忽略where和里面的if
where标签会删除据它最近的那个or或and
语法:
dao
ListselectWhere(Student student);
mapper
测试
@Testpublic void testSelectWhere(){ SqlSession sqlSession=MyBatisUtil.getSqlSession(); StudentDao dao=sqlSession.getMapper(StudentDao.class); Student stu=new Student(1006,"李广","wangwu@qq.com",45); List list=dao.selectWhere(stu); for(Student s:list){ System.out.println(s); } sqlSession.close();}
4.3 foreach循环
手动实现sql语句
@Testpublic void testFor(){ List idList=new ArrayList<>(); idList.add(1001); idList.add(1002); idList.add(1003); //查询id在idlist中的student //select * from student where id in(1001,1002,1003) StringBuffer sql=new StringBuffer(); sql.append("select * from student where id in "); sql.append("("); //使用循环,把List数据追加到sql中 for(int i=0;i
使用foreah可以循环数组,list集合,一般使用在in语句中
语法:
#{item的值} 标签属性:collection:表示循环的对象 是数组 还是List集合。如果dao接口方法参数 是数组,collection="array",如果是List,collection="list"open:循环开始的字符 sql.append("(");close:循环结束时的字符 sql.setCharAt(sql.length()-1,')');item:集合成员,自定义的变量separator:集合成员间的分隔符 如','#{item}:获取item的值
List集合存放简单类型数据:
dao:
List selectForeach1(List idlist);
mapper文件
test
@Testpublic void testSelectForeahOne(){ SqlSession sqlSession=MyBatisUtil.getSqlSession(); StudentDao dao=sqlSession.getMapper(StudentDao.class); List idList=new ArrayList<>(); idList.add(1001); idList.add(1002); idList.add(1003); List list= dao.selectForeach1(idList); for(Student s:list){ System.out.println(s); } sqlSession.close();}
list存的是对象
List selectForeach2(List idlist);
mapper
test
@Testpublic void testSelectForeach2(){ SqlSession sqlSession=MyBatisUtil.getSqlSession(); StudentDao dao=sqlSession.getMapper(StudentDao.class); List idList=new ArrayList<>(); Student s1=new Student(); Student s2=new Student(); s1.setId(1001); s2.setId(1002); idList.add(s1); idList.add(s2); List list= dao.selectForeach2(idList); for(Student s:list){ System.out.println(s); } sqlSession.close();}
4.4 代码片段
代码标签用于定义sql片段,以便于其他标签使用该SQL片段,需要使用子标签.该标签可以dingyisql语句中的任何部分,所以子标签可以放在动态sql的任何位置
接口方法:
ListselectStudentSqlFragment(List stuList);
mapper文件:
select * from student where id in #{student.id} 1=-1
test
@Testpublic void selectStudentSqlFragment(){ SqlSession sqlSession=MyBatisUtil.getSqlSession(); StudentDao dao=sqlSession.getMapper(StudentDao.class); List idList=new ArrayList<>(); Student s1=new Student(); Student s2=new Student(); s1.setId(1001); s2.setId(1002); idList.add(s1); idList.add(s2); List list= dao.selectStudentSqlFragment(idList); for(Student s:list){ System.out.println(s); } sqlSession.close();}
第五章 MyBatis配置文件
MyBatis配置文件有两大类:
- 主配置文件,提供Mybatis全局设置的.包含的内容有 日志,数据源,mapper文件位置等
- mapper文件:写sql语句的.一个表一个mapper文件
5.1 settings部分
settings是mybatis的全局设置,影响整个mybatis的运行.这个设置一般用默认值就行.
完整的settings
5.2 typeAlias
设置别名,可用可不用
5.3 配置环境
enviroments:环境标签,里面那可以配置多个enviroment
- enviroment:表示一个数据库的连接信息
- 属性id 自定义的环境标识.唯一值
- 属性default必须是某个enviroment的id属性值,表示mybatis默认连接数据库.
- transactionManager:事务管理器
- type:标识事务管理器类型
属性值:1)JDBC:使用Connection对象,由mybatis自己完成事务处理
2)MANAGED:管理,表示把事务交给容器实现(由其他软件完成事务的提交回滚)
- dataSource: 数据源,创建Cennection对象,连接数据库
- type属性:表示数据源的类型;
- 属性值:1.POOLED表示mybatis会在内存中创建PooledDataSource类,管理多个Connection对象,使用的连接池
- 2.UNPOOLED,不使用连接池,mybatis创建一个UnPooledDataSource类,每次执行sql语句先创建Connection对象,再执行sql语句,最后关闭Connection(基本不用)
- 3.JDNI:java的命名和目录服务.
5.4 使用数据库配置文件(掌握)
需要把把数据库的配置信息放到一个单独文件中,独立管理,这个文件扩展名是properties.在这个文件中使用自定义的key=value的格式表示数据
使用步骤:
-
在resource目录中,创建xxx.properties文件
-
在文件和中使用key=vaule的格式定义数据
例如:jdbc.url=jdbc:mysql://localhost:3306/springdb
-
在mybatis主配置文件,使用properties标签引用外部的属性配置文件
-
在使用值得位置,使用${key}获取key对应的value(等号的右侧)
properties文件
jdbc.driver=com.mysql.cj.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/ssm?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMTjdbc.username=rootjdbc.password=root123456
主配置文件
5.5 mapper 标签
使用mapper指定其他文件的位置
mapper标签使用格式:有两种常用方式
-
第一种方式: resources=“mapper文件路径”;
优点:文件清晰,加载哪个文件一目了然,文件的位置灵活;
缺点:文件较多时代码量比较大,管理难度大
-
第二种方式:name=“包名”. mapper文件所在的包名
特点:将该包中的所有所有mapper文件一次加载.
使用要求:mapper文件和dao接口在同一目录,且与dao接口名称完全一致.
第六章 PageHelper
PageHelper做数据分页.在你的select语句后面加入分页的sql内容.如果你使用的mysql数据库,它就是在select* from student 后加上limit语句
使用步骤
-
加入pagehelper依赖
com.github.pagehelper pagehelper 5.1.10
-
在mybatis主配置未见加入plugin声明
-
在select语句之前,调用PageHelper.startPage(页码,每页大小)(页码从1开始)
测试使用:
@Testpublic void testPageHelper(){ SqlSession sqlSession=MyBatisUtil.getSqlSession(); StudentDao dao=sqlSession.getMapper(StudentDao.class); List idList=new ArrayList<>(); PageHelper.startPage(2,3); List list= dao.selectAllStudent(); for(Student s:list){ System.out.println(s); } sqlSession.close();}
控制台输出结果:
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@8297b3a]==> Preparing: SELECT count(0) FROM student ==> Parameters: <== Columns: count(0)<== Row: 7<== Total: 1==> Preparing: select * from student order by id LIMIT ?, ? ==> Parameters: 3(Integer), 3(Integer)<== Columns: id, name, email, age<== Row: 1004, 公明, gongming@qq.com, 47<== Row: 1005, 李广, liguang@qq.com, 20<== Row: 1006, 武松, wusong@qq.com, 38<== Total: 3Student{id=1004, name='公明', email='gongming@qq.com', age=47}Student{id=1005, name='李广', email='liguang@qq.com', age=20}Student{id=1006, name='武松', email='wusong@qq.com', age=38}



