Mybatis实现分页功能(完整流程)

Mybatis实现分页功能

准备数据库

实体类 People

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class People {
private int id;
private String name;
private int age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "People [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}

导入相关jar包

全局配置文件mybatis.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?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"> <!--dtd文件 约束(chm文件可以找到)-->

<configuration>

<typeAliases>
<package name="com.bjsxt.pojo"/> <!-- 起别名 方便在配置的xml里面直接返回值就可以只写类名-->
</typeAliases>

<environments default="default">
<environment id="default">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
<property name="username" value="root"/>
<property name="password" value="njdxrjgc7777777."/>
</dataSource>
</environment>
</environments>

<mappers>
<mapper resource="com/bjsxt/mapper/PeopleMapper.xml"/> <!-- 直接调用配置文件 执行sql语句 -->
</mappers>

</configuration>

配置PeopleMapper.xml

1
2
3
4
5
6
7
8
9
10
11
<?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"> <!--dtd文件 约束(chm文件可以找到)-->

<mapper namespace="com.bjsxt.mapper.PeopleMapper" > <!-- 确定这个mapper名字: 包.类名 -->
<select id="selByPage" resultType="People" parameterType="map"> <!-- 确定方法叫selByPage 返回值给people实体类 传入参数的类型是map -->
select * from people limit #{pageStart},#{pageSize}; <!-- limit 后面通过#{}方式传入两个map参数-->
</select>
</mapper>

构建实体类pageInfo用于传递分层相关的参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

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;
}

}

service和实现层

service层实现代码:

1
2
3
4
public interface PeopleService {
//实现分页展示 传入两个参数
PageInfo showPage(int pageSize,int pageNumber) throws IOException;
}

serviceimpl层实现代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class PeopleServiceImpl implements PeopleService {

@Override
public PageInfo showPage(int pageSize, int pageNumber) throws IOException {

//获取配置资源
InputStream is = Resources.getResourceAsStream("mybatis.xml");

//使用构建者模式(加快工厂实例化)和工厂模式生产session
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
SqlSession session = factory.openSession();

//创建对象
PageInfo pi=new PageInfo();
pi.setPageNumber(pageNumber);
pi.setPageSize(pageSize);

//新建map对象
Map<String,Object> map=new HashMap<>();
map.put("pageStart",pageSize*(pageNumber-1)); //设置好每一页开始的那个数字
map.put("pageSize",pageSize); //设置好每一页有几个
pi.setList(session.selectList("com.bjsxt.mapper.PeopleMapper.selByPage",map)); //要设置返回结果 第二个参数是传入两个key值

//总条数
long count=session.selectOne("com.bjsxt.mapper.PeopleMapper.selCount"); //获取查询总条数

pi.setTotal(count%pageSize==0?count/pageSize:count/pageSize+1); //要设置总共几页 总数/每一页

return pi;
}

}

因为要获得所有数count 要在xml配一个查询所有的select标签

1
2
3
<select id="selCount" resultType="Long">
select count(*) from people
</select>

Servlet类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
@WebServlet("/page")  //使用注解的方式 最后要在web里面写/page才可以

public class ShowPageServlet extends HttpServlet{

//面向接口编程
private PeopleService peopleService=new com.bjsxt.serviceimpl.PeopleServiceImpl();

@Override
protected void service(HttpServletRequest req,HttpServletResponse resp)throws ServletException,IOException{

//第一次访问的验证 如果没有传递参数 设置默认值
String pageSizeStr = req.getParameter("pageSize");
int pageSize=2; //一页显示几个
if(pageSizeStr!=null&&!pageSizeStr.equals(""))
{
pageSize = Integer.parseInt(pageSizeStr); //获取两个参数
}

String pageNumberStr = req.getParameter("pageNumber");
int pageNumber = 1; //显示第几页
if(pageNumberStr!=null&&!pageNumberStr.equals(""))
{
pageNumber = Integer.parseInt(pageNumberStr); //获取两个参数
}

PageInfo pi=peopleService.showPage(pageSize, pageNumber); //分页展示效果给了pageinfo实体类

// 传过去
req.setAttribute("PageInfo", pi);

// 请求转发
req.getRequestDispatcher("index.jsp").forward(req, resp);

}

}

index.jsp页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<table border="1">
<tr>
<th>编号</th>
<th>姓名</th>
<th>年龄</th>
</tr>
<c:forEach items="${PageInfo.list }" var="pi">
<tr>
<td>${pi.id }</td>
<td>${pi.name }</td>
<td>${pi.age }</td>
</tr>
</c:forEach>
</table>

<!-- 跳转通过onclick点击事件 然后js的行内表达方式 取消跳转等功能 c:if进行判断 -->
<a href="page?pageNumber=${PageInfo.pageNumber-1 }&pageSize=${PageInfo.pageSize}" <c:if test="${PageInfo.pageNumber<=1 }"> onclick="javascript:return false;" </c:if> >上一页</a>
<a href="page?pageNumber=${PageInfo.pageNumber+1 }&pageSize=${PageInfo.pageSize}" <c:if test="${PageInfo.pageNumber>=PageInfo.total }"> onclick="javascript:return false;" </c:if> >下一页</a>

</body>
</html>

结果和分析

一定要在输入的后面添加注解的 /path :

完整代码放在mybatis分页的仓库里面


Mybatis实现新增删除修改和事务讲解

前期知识

项目分工

功能:从应用程序角度出发,软件具有哪些功能
业务:完成功能需要的逻辑 – 对应service中一个方法
事务:从数据库角度出发,完成业务时需执行的sql集合 叫做一个事务

mybatis对于JDBC

mybatis中默认是关闭JDBC的自动提交功能

每一个SqlSession默认是不自动提交事务
    1. session.commit() 提交事务
    2. openSession(true) 自动提交 [setAutoCommit(true)]

mybatis底层是对JDBC的封装

1. JDBC中executeUpdate()  执行增加/删除/修改
     返回值都是int
2. mybatis中insert/delete/update标签   执行增加/删除/修改
    没有resultType属性  认为返回值是int

在openSession()时,Mybatis会创建SqlSession+ 创建一个Transaction(事务对象) + autoCommit属性都是false

回滚(用try catch抓) session.rollback()回顾事务


Mybatis实现新增

mapper.xml中提供insert标签

1
2
3
<insert id="tianjia" parameterType="People">       //id是表示现在的方法叫tianjia  然后没有返回值  使用别名People直接用(对整个包取别名)
insert into people values(default,#{name},#{age}) //sql语句 要传进来name 和 age 两个属性
</insert>

test类session提供insert方法

1
2
3
4
5
6
7
8
9
10
11
12
13
 People p=new People();
p.setName("新增name1");
p.setAge(88);

int index1=session.insert("a.b.tianjia",p); //判断是否成功 默认返回值是int类型
if(index1>0)
{
System.out.println("成功");
}
else
{
System.out.println("失败");
}

Mybatis实现mysql分页

Xml文件转义标签

Xml出现一些特殊字符(< > “”)就是用Xml自带的文件转义标签

1
<![CDATA[内容]]>

mysql语句分页演示


mybaitis中实现mysql分页写法

  • *1. ? 不允许(×)出现在关键字前后进行数字运算 (因为原来查出来log4j返回出来sql语句是 id=?的形式) *

  • 2. java中解决(?)方法 – (直接在传之前我就让?的值被计算好)

test类:

1
2
3
4
5
6
7
8
9
10
11
12
13
//显示几个
intpageSize=2;

//第几页
intpageNumber=2;

//如果希望传递多个参数,可以使用对象或map

Map<String,Object>map=newHashMap<>(); //定义一个map集合: 第一个key是字符串 第二个key是object
map.put("pageSize",pageSize); //算好 一页显示几个
map.put("pageStart",pageSize*(pageNumber-1)); //算好 第几页从第几个下标开始

List<People>p=session.selectList("com.bjsxt.pojo.mapper.page",map); //找包下面类的page方法 查出来的结果给list集合

** 在mapper.xml配置文件:**

1
2
3
<select id="page" resultType="com.bjsxt.pojo.People"  parameterType="map">  //传入的参数类型是map
select * from people limit #{pageStart},#{pageSize} //传入两个值
</select>

别名(typeAliases标签)

每一次用sql语句就要写一次select标签的属性然后返回结果list集合给实体类
所以引入了别名的机制更加方便

系统内置别名

1
把类型全小写即可

给某个类(typeAlias标签) 方便一个表的多个方法使用

1.直接在全局配置文件内加typeAliases标签

1
2
3
4
5
//在全局配置文件的<configuration>标签内加:

<typeAliases>
<typeAlias type="com.bjstx.pojo.People" alias="peo"/> //意思就是将type里面的内容取个别名叫做peo
</typeAliases>

2.之后就可以在mapper.xml配置文件的select标签的resultType内容改为别名peo

1
2
3
<select id="page" resultType="peo"  parameterType="map">  //传入的参数类型是map  返回给peo(别名)
select * from people limit #{pageStart},#{pageSize} //传入两个值
</select>

给某个包所有类(package标签) 方便多个表进行操作

1.直接在全局配置文件内加typeAliases标签

1
2
3
4
5
//在全局配置文件的<configuration>标签内加:

<typeAliases>
<package name="com.bjsxt.pojo"/> //这个包下肯定有很多操作数据库的配置文件
</typeAliases>

2.之后就可以在mapper.xml配置文件的select标签的resultType内容直接使用实体类的类名

1
2
3
<select id="page" resultType="People"  parameterType="map">  //传入的参数类型是map  返回值就直接写配置别名的类的类名
select * from people limit #{pageStart},#{pageSize} //传入两个值
</select>

Mybatis查询所有

前期准备

准备数据库

最终结果:

sql语句:

1
2
3
4
5
6
7
8
create table people(
id int(10) primary key auto_increment comment '编号',
name varchar(20) comment '姓名',
age int(3) comment '年龄'
)comment '人员信息表';

insert into people values(default,'张三',21);
insert into people values(default,'李四',22);

准备实体类People

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

public class People {

private int id; //和数据库的属性匹配
private String name;
private int age;

public int getId() { //生成所有的set和get方法
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}

搭建环境

  • *1. 导入mybatis的jar包 + 依赖包 + mysql的jar包 + jstl的jar包 *

  • 2. 搭建全局配置文件

    1. 中文chm文档dtd文件找约束
    2. 写configuration内容 -- 配置数据库
    3. 写mappers的配置 -- 找PeopleMapper.xml(类似于实现类)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?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="default">
<environment id="default">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
<property name="username" value="root"/>
<property name="password" value="njdxrjgc7777777."/>
</dataSource>
</environment>
</environments>

<!--第三步-->
<mappers>
<mapper resource="com/bjstx/mapper/PeopleMapper.xml"/>
</mappers>

</configuration>
  • 3. 搭建类似于实现类的xml文件

    1. 中文chm文档dtd文件找约束
    2. 写mapper配置 -- 里面写sq语句和返回值和方法名等信息
1
2
3
4
5
6
7
8
9
10
11
12
13
<?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.bjsxt.mapper.PeopleMapper" >
<select id="selAll" resultType="com.bjsxt.pojo.People">
select * from people
</select>
</mapper>

准备service层和实现层

PeopleService接口写方法

1
2
3
4
5
public interface PeopleService {

//显示人员
List<People> show() throws IOException;
}

PeopleServiceImpl类实现PeopleService接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/*
* 数据访问层 -- 处理异常和控制器中处理异常 service只是抛出异常
*/
public class PeopleServiceImpl implements PeopleService{

@Override
public List<People> show() throws IOException {
// 1. 找主配置文件
InputStream is = Resources.getResourceAsStream("mybatis.xml");

// 2. 使用工厂模式 实例化工厂对象使用构建者模式 (名称标志后面:Builder)
//构建者设计模式意义:简化对象实例化过程 (我们这个SqlSessionFactory里面还要很多类很多方法比较麻烦)
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(is);

// 3. 创建session
SqlSession session=factory.openSession();

//4. 调用xml配置文件中的功能
List<People> list = session.selectList("com.bjsxt.mapper.PeopleMapper.setAll");

//5. 关闭连接
session.close();

return list;
}

}

准备Servlet层

1
2
3
4
5
6
7
8
9
10
11
12
13
@WebServlet("/abc/b/show")  //1.是给默认属性赋值 省略 value=  2.数组是一个值 省略 {}
public class ShowServlet extends HttpServlet {
//面向接口编程
private PeopleService peopleService=new PeopleServiceImpl();

@Override
protected void service(HttpServletRequest req,HttpServletResponse resp)throws ServletException,IOException{
List<People> list = peopleService.show();
req.setAttribute("list", list);
//使用请求转发 这次是相对路径
req.getRequestDispatcher("/index.jsp").forward(req, resp); // "/" 全路径(对WebContent目录) "" 相对路径
}
}

index.jsp首页

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<table>
<tr>
<th>编号</th>
<th>姓名</th>
<th>年龄</th>
</tr>
<c:forEach items="${list }" var="peo">
<tr>
<td>${peo.id}</td>
<td>${peo.name}</td>
<td>${peo.age}</td>
</tr>
</c:forEach>
</table>
</body>
</html>

Log4J

Log4J

apache推出的开源免费日志处理类库

使用步骤

1. 导入log4j-xxx.jar
2. 在src目录下新建log4j.properties(不能改!!!)

log4j.properties文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//第一行写的是五种错别级别中的哪一种 是输出到console输出台 还是可以到文件LOGFILE

//五种错误: fatal(致命错误 程序员无法解决) > error(错误) > warn(警告) > info(普通信息) > debug(调试信息)

log4j.rootCategory=INFO, CONSOLE


//以下是关于输出到控制台的信息

log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender //使用的是这个类
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout //输出
log4j.appender.CONSOLE.layout.ConversionPattern=- %m%n //输出格式


//以下是关于输出到项目下面的信息

log4j.appender.LOGFILE=org.apache.log4j.FileAppender //使用这个类
log4j.appender.LOGFILE.File=axis.log //输出的文件名称
log4j.appender.LOGFILE.Append=true //是否开启了添加功能(就是往文件里面存)
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n //输出的格式

输出pattern的几个表达式:

%C                       包名+类名
%d{YYYY-MM-dd HH:mm:ss}  时间
%L   行号
%m   信息
%n   换行

settings 标签(全局配置文件)

在mybatis全局配置文件中通过settings标签控制mybatis全局开关

我们鼠标放到configuration上面就会弹出下面标签的顺序和使用个数

配置步骤

1. 准备好jar包 + 实体类 + mybatis全局配置文件 + log4j.properties配置文件
2. configuration标签下写settings标签
    <settings>
        <setting name="LogImpl" value="LOG4J"/>      //settings里面属性就是LogImpl  然后值取log4j
    </settings>

3. log4j可以配置指定内容日志(可以控制输出检查错误)

配置步骤第三步分析:


parameterType 属性(mapper包内配置)

在mapper包里的xml配置文件中 select delete等标签的parameterType可以控制参数类型

配置步骤

1. 需要在mapper包里的xml里面去配置select标签
2. 需要在test测试类里面调用

具体分析

1. 分析mapper包配置文件的具体写法

#{}获取参数

    1. 使用索引       从0开始
    2. 使用#{param1}  从1开始

    里面只有一个参数 --#{随便写}
    参数是对象 --#{属性名}
    参数是map  --#{key}

实现代码:

1
2
3
<select id="selById" resultType="com.bjsxt.pojo.People" parameterType="int">  //原来基础上加parametType属性 里面放的是你传进来数字的类型
select * from people where id=#{0} //#{0} 就是把测试类里面的参数(属性就是parameterType的值)传进来
</select>

2. test测试类session调用

三种方法使用:

    1.session里面的selectList()和selectOne()是第二个参数传入
    2.session里面的selectMap()就是第三个参数传入

实现代码:

1
2
People p=session.selectOne("com.bjsxt.mapper.selById",1);  //传入查询id=1的值
System.out.println(p); //输出结果

3. ${} 和 #{} 区别(面试题)

#{}  索引获取 / param1获取指定位置参数 并且在SQL语句内使用?占位符
${}  字符串拼接 默认去找${内容}中内容的get/set方法 (如果写数字 就是一个数字)

Mybatis全局配置文件详解

全局配置文件内容

transactionManager属性中type取值

 

  1. JDBC    事务管理使用JDBC原生事务管理方式
  2. MANAGED  把事务管理转交给其他容器(spring框架)

setAutoMapping(false);

dataSource中type取值

  1. POOLED   使用数据库连接池
  2. UNPOOLED  不使用数据库连接池,和直接使用JDBC一样
  3. JNDI    为了使用如spring或者应用服务器这类的容器

数据库连接池

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

JDBC tomcat Pool

直接由tomcat产生数据库连接池

  • 图示

实现JDBC tomcat Pool步骤

  1. 在web项目的WebContent/META-INF存放context.xml文件

  1. 书写十个属性(前四个是数据库属性)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="UTF-8"?>    
<Context>
<Resoure
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/eesy"
username="root"
password="njdxrjgc7777777."
maxActive="50" //运行的最大数字
maxIdle="10" //等待的最大数字
name="test"
auth="Container" //由tomcat自动启动
maxWait="10000" //等待最大实现
type="java.sql.DataSoure" //我去name找到数据库连接池的时候对象什么样子

/>
</Context>

三种查询方式 session.方法

selectList()结果需要遍历

selectOne()结果只是变量/一行数据

selectMap()结果只查某列的值


Mybatis(eclipse详细)

用eclipse配置环境

导入相关的jar包

src下新建全局配置mybatis.xml文件(编写JDBC的四个变量)

2.1 xml引入DTD(在mybatis.chm找)

1
2
3
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">

2.2 如果导入DTD后续没有自动提示

2.3 编写和jdbc以及连接数据库有关的资源(自动提示)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<configuration>    
<!-- default引用environment的id 当前使用环境 -->
<environments default="default">
<!-- 声明使用的环境 -->
<environment id="default">
<!--使用原生JDBC事务-->
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="uri" value="jdbc:mysql://localhost:3306/ssm"/>
<property name="username" value="root"/>
<property name="password" value="njdxrjgc7777777."/>
</dataSource>
</environment>
</environments>
</configuration>

新建实体类名Mapper.xml(编写sql语句S)##

3.1 xml引入DTD(在mybatis.chm找)

1
2
3
4
<?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">

*3.2 xml相当于实体类(xml全路径) 以及实现方法和返回值类型(实体类全路径) *

1
2
3
4
5
6
7
8
9
10
11
12
<mapper namespace="com.bjsxt.FlowerMapper"> <!-- 实现类的全路径namespace -->
<!--
id:方法名
parameterType:定义参数类型
resultType:返回值类型 如果返回值是list 在resultType中写List的泛型 因为mybatis对jdbc封装 一行一行读取数据

-->
<select id="selAll" resultType="com.bjsxt.pojo.Flower">
select * from flower
</select>

</mapper>

编写测试类

1.需要生产SqlSession

2.然后我们知道要用工厂设计模式–所以使用对应的SqlSessionFactory接口

3.我们通过ctrl+t打开查看接口实现类–需要关联外部文件夹–选择mybatis-3-mybatis-3.2.7文件的src

4.通过分析接口实现类发现是有参构造方法–需要新建Configuration类

5.因为实例化比较麻烦 –使用构建者模式快速构建对象 – 然后build需要字节流 –所以要用字节流去加载写好的主配置文件

6.使用建造好的实体生产SqlSession –list接xml配置文件的sql执行结果 –for输出

7.最后就是要关闭连接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Test {
public static void main(String[] args) throws IOException {

//因为建造者模式的build需要一个字节流 我们需要将主配置文件导入
InputStream is = Resources.getResourceAsStream("mybatis.xml");

//使用工厂设计模式
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(is); //build(Reader reader) 要用字节流

//生产SqlSession
SqlSession session=factory.openSession();

//调用配置类
List<Flower> list=session.selectList("com.bjsxt.FlowerMapper.setAll"); //找的是xml的namespace全路径
for(Flower flower:list)
{
System.out.println(flower.toString());
}

//关闭(不关的话和数据库还是长连接状态)
session.close();

}
}

相当于实现类的xml需要加载到主配置文件内

要在mybatis.xml里面加载我们的相当于实现类的xml的全路径

1
2
3
<mappers>
<mapper resource="com/bjsxt/mapper/FlowerMapper.xml"></mapper>
</mappers>

总体结构

1: mapper包:存放xml配置文件(相当于实现类的那个xml)
    功能:
         1.1 mapper里面存放namespace自己的全路径
         1.2 我们写的是select(还可以使用其他的) 然后id是需要写的方法名字 resultType写返回值给实体类的全路径
         1.3 select里面要写sql语句

2: pojo包:里面存放的是实体类
    功能:
          2.1 里面写所有数据库属性还有set/get方法 以及tostring方法(test类输出)

3: test包:里面存放测试类
    功能:
            3.1 读取主配置文件
            3.2 使用工厂设计模式和建造者模式创建sqlsession
            3.3 调用配置的xml文件全路径+方法名
            3.4 使用完断开连接

4: 主配置文件:主要用于写使用的JDBC数据池和mysql的配置 以及加载我们的xml(相当于实现类)
    功能:
            4.1 使用transactionManager写原生JDBC事务
            4.2 使用dataSource书写数据池和property的标签写mysql的配置
            4.3 然后mappers就写各种实现类的配置xml(中间写resource就是xml的全路径)        

Mybatis(idea+maven)

框架概念

使用框架前后对比

之前的MVC结构与框架对比:

持久层(Dao)技术解决方案

1. JDBC技术:
           Connection        获取连接
        PreparedStatement   提前处理sql语句
            ResultSet       处理sql语句获得结果

2. Spring的JdbcTemplate(工具类):
        Spring对jdbc的简单封装

3. Apache的DBUtils(工具类):
        和Spring的JdbcTemplate很像,也是简单封装

4. 数据池:
    彻底死掉的C3P0(ssh里面的h框架的内置数据池)
    咸鱼翻身的DBCP
    功能全面的Druid(阿里云)
    性能无敌的HikariCP

Mybatis框架概述

内部封装了jdbc,使开发者只需要关注sql语句本身,而不用花费精力去处理加载驱动、创建连接等工作。

通过xml或者注解的方式将执行的各种statement配置起来,并且通过java对象和statement中的sql动态参数进行映射生成最终的sql语句,最后由框架执行sql语句并且将结果映射给java对象并且返回。

通过ORM思想(Object Relational Mappging 对象关系映射)解决了实体和数据库映射的问题,对jdbc的api底层访问细节,使我们不用于jdbc的api打交道,就可以完成数据库的持久化操作


Mybatis环境搭建

前期环境准备

1.新建数据库

1
2
3
4
5
6
7
8
9
10
CREATE TABLE `user` (
`id` int(11) NOT NULL auto_increment,
`username` varchar(32) NOT NULL COMMENT '用户名称',
`birthday` datetime default NULL COMMENT '生日',
`sex` char(1) default NULL COMMENT '性别',
`address` varchar(256) default NULL COMMENT '地址',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert into `user`(`id`,`username`,`birthday`,`sex`,`address`) values (41,'老王','2018-02-27 17:47:08','男','北京'),(42,'小二王','2018-03-02 15:09:37','女','北京金燕龙'),(43,'小二王','2018-03-04 11:34:34','女','北京金燕龙'),(45,'传智播客','2018-03-04 12:04:06','男','北京金燕龙'),(46,'老王','2018-03-07 17:37:26','男','北京'),(48,'小马宝莉','2018-03-08 11:44:00','女','北京修正');

2.通过无骨架的创建方式创建maven工程

3.通过pom.xml文件去添加mybatis和mysql的jar包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.itheima</groupId>
<artifactId>day01_easy_01mybatis</artifactId>
<version>1.0-SNAPSHOT</version>

<packaging>jar</packaging> <!--通过jar包-->

<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId> <!--通过Mybatis官网找到的框架 只需要更改版本号-->
<version>3.4.5</version>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId> <!--需要mysql-->
<version>5.1.6</version>
</dependency>

<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId> <!--日志文件-->
<version>1.2.12</version>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId> <!--单元测试-->
<version>4.10</version>
<scope>test</scope>
</dependency>
</dependencies>

</project>

书写代码框架

1.main/java里书写domain和dao层代码

dao层IUserDao类:

1
2
3
public interface IUserDao {
List<User> findAll(); //接口写查询所有的方法
}

domain层的User类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public class User implements Serializable {
//和数据库保持一致
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public Date getBirthday() {
return birthday;
}

public void setBirthday(Date birthday) {
this.birthday = birthday;
}

public String getSex() {
return sex;
}

public void setSex(String sex) {
this.sex = sex;
}

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}

@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
}

2.创建Mybatis的主配置文件 sqlMapConfigxml(需要导入外部的约束(就是前面的四行))

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?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">

<!--Mybatis的主配置文件-->
<configuration>
<!--配置环境 default和id必须一致-->
<environments default="mysql">
<!--配置mysql环境-->
<environment id="mysql">
<!--配置事务的类型-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源(连接池)-->
<dataSource type="POOLED">
<!--连接数据库的四个基本信息-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/eesy"/>
<property name="username" value="root"/>
<property name="password" value="njdxrjgc7777777."/>
</dataSource>
</environment>
</environments>

<!--指定映射配置文件的位置 映射配置文件指的是每个dao独立的配置文件-->
<mappers>
<mapper resource="com/itheima/dao/IUserDao.xml"/>
</mappers>

</configuration>

3.创建映射配置文件 IUserDao.xml((需要导入外部的约束(就是前面的四行))

1
2
3
4
5
6
7
8
9
10
11

<?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.itheima.dao.IUserDao">
<!--配置查询所有-->
<select id="findAll">
select * from user;
</select>
</mapper>

Mybatis的xml配置开发

拷贝日志文件(log4j.properties)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE

# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE

# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n

# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d:\axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n

书写Test类

在src/test/java里面写Test类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class MybatisTest {
public static void main(String[] args) throws IOException {
//1.读取配置文件
InputStream in= Resources.getResourceAsStream("SqlMapConfig.xml"); //读取我们的mybatis主配置文件

//2.创建SqlSessionFactory工厂
SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
SqlSessionFactory factory=builder.build(in); //构建流(怎么解析我们不用管)

//3.使用工厂生产SqlSession对象
SqlSession session=factory.openSession();

//4.使用SqlSession创建Dao接口的代理对象
IUserDao userDao=session.getMapper(IUserDao.class); //没有实现类 我们用代理对象去做

//5.使用代理对象执行方法
List<User> users = userDao.findAll();
for (User user:users)
{
System.out.println(user);
}

//6.释放资源
session.close();
in.close();
}
}

更改IUserDao.xml映射文件(增加结果封装到哪里)

1
2
3
<select id="findAll" resultType="com.itheima.domain.User">   <!--我们要把结果封装到User才可以-->
select * from user;
</select>

测试执行

1.最终的入门程序格式:

2.代码执行结果:


xml开发方式中设计模式分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//1.读取配置文件
InputStream in= Resources.getResourceAsStream("SqlMapConfig.xml"); //读取我们的mybatis主配置文件

//2.创建SqlSessionFactory工厂
SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
SqlSessionFactory factory=builder.build(in); //构建者模式

//3.使用工厂生产SqlSession对象
SqlSession session=factory.openSession(); //工厂模式

//4.使用SqlSession创建Dao接口的代理对象
IUserDao userDao=session.getMapper(IUserDao.class); //没有实现类 我们用代理对象去做

//5.使用代理对象执行方法
List<User> users = userDao.findAll();
for (User user:users)
{
System.out.println(user);
}

//6.释放资源
session.close();
in.close();

每一步的解析:


Mybatis注解开发

准备之前的所有东西

1.将pom导入的jar文件写在新的项目的pom.xml里面

2.将上面用xml配置方式的src/java和resource以及test测试类全部拷贝进新项目

进行xml更改为注解方式

3.删除之前的IUserDao.xml的配置方式(里面写的是查询语句和最后返回给User封装)

4.在IUserDao的接口里面使用Select注解(把之前的xml方式的东西挪到里面)

1
2
3
4
public interface IUserDao {
@Select("select * from user")
List<User> findAll();
}

5.那么要删除SqlMapConfig.xml的Mybatis主配置(之前是链接xml的位置 现在是直接找到类名)

1
2
3
4
5
<!--指定映射配置文件的位置 映射配置文件指的是每个dao独立的配置文件-->
<!--如果使用注解来配置文件,此处应该用class属性指定被注解的dao全限定类名-->
<mappers>
<mapper class="com.itheima.dao.IUserDao"/>
</mappers>

Nginx

Nginx(反向代理)

场景需求

  
  原来是1w个访问要去使用tomcat会导致并发太高,然后我们可以通过多开Tomcat服务器从而来分担。所以引入了nginx来分配tomcat。这种方式也叫做反向代理

Nginx概述

  
  Nginx是一款高性能http服务器/反向代理服务器/电子邮件(IMAP/POP3)代理服务器。官方测试nginx能支撑5w的并发连接,而且cpu和内存等资源消耗比较低。

应用场景

1. 网页静态服务器

2. 动态服务器(部署在tomcat里面,通过nginx反向代理搭建集群)

3. 虚拟主机(可以实现一台服务器虚拟出多个网站)

4. 反向代理和负载均衡 


Nginx安装

环境准备

1. 安装gcc环境(之前redis安装就已经安装好了)

1
yum install gcc-c++

2. 安装第三方的开发包(PCRE zlib Openssl)

1
2
3
yum install -y pcre pcre-devel
yum install -y zlib-devel
yum install -y openssl openssl-devel
  • PCRE
    PCRE(Perl Compatible Regular Expressions)是一个 Perl 库,包括 perl 兼容的正则表达式库。nginx 的 http 模块使用 pcre 来解析正则表达式,所以需要在 linux 上安装 pcre 库。

  • zlib
    zlib 库提供了很多种压缩和解压缩的方式,nginx 使用 zlib 对 http 包的内容进行 gzip,所以需要在 linux 上安装 zlib 库。

  • OpenSSL
    OpenSSL 是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及 SSL 协议,并提供丰富的应用程序供测试或其它目的使用。nginx 不仅支持 http 协议,还支持 https(即在 ssl 协议上传输 http),所以需要在 linux安装 openssl 库。

上传解压

3. 通过rz 上传nginx文件并且tar -zxvf解压

4. 当面目录下输入以下文字 会生成makeFile文件

1
2
3
4
5
6
7
8
9
10
11
12
./configure \
--prefix=/usr/local/nginx \
--pid-path=/var/run/nginx/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-http_gzip_static_module \
--http-client-body-temp-path=/var/temp/nginx/client \
--http-proxy-temp-path=/var/temp/nginx/proxy \
--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \
--http-uwsgi-temp-path=/var/temp/nginx/uwsgi \
--http-scgi-temp-path=/var/temp/nginx/scgi

5. 执行make指令编译 执行make install指令下载


Nginx启动

启动步骤

1. mkdir /var/temp/nginx/client -p 创建子目录

2. 进入到Nginx目录下的sbin目录 然后执行nginx即可

3.打开nginx之后浏览器打开(直接输入linux里面的ip地址)

4.通过 ps aux|grep nginx 查看进程

其他操作指令(目录站在nginx/sbin里面)

1
2
3
4
5
6
7
1. 启动Nginx   ./nginx

2. 查看进程 ps aux|grep nginx

3. 关闭Nginx ./nginx -s stop // ./nginx -s quit

4. 重启Nginx 1.先关闭后启动 2.刷新配置文件 ./nginx -s reload

静态资源部署

更改nginx/conf/nginx.conf配置文件

通过EditPlus5去进行设置ftp

1. 打开文件-FTP-设置FTP服务器-然后输入信息

2. 根据左上角目录去找左下角对应的目录文件然后右边更改

3. 每次更新之后弹窗选择确定就可以提交更新

4. 更改后的信息解析:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

worker_processes 1;

events {
worker_connections 1024;
}

http {
include mime.types;
default_type application/octet-stream;

sendfile on;

keepalive_timeout 65;

server {
listen 80;
server_name localhost;


location / {
root index;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}

}

准备好index文件复制到nginx目录下

1.使用FileZilla软件也可以使用ftp上传

2.更改nginx.conf配置里面的root

3. 重启nginx之后(./nginx -s reload)浏览器打开就自动跳转到了index页面


虚拟主机-端口绑定

配置文件解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

worker_processes 1;

events {
worker_connections 1024;
}

http {
include mime.types;
default_type application/octet-stream;

sendfile on;

keepalive_timeout 65;

server {
listen 81; # 默认端口号码
server_name localhost; # 写的是域名或者ip地址配置


location / {
root index; # 默认访问资源的目录
index index.html index.htm; # 默认访问资源名称
}

error_page 500 502 503 504 /50x.html; # 错误页面
location = /50x.html {
root html;
}
}

server {
listen 82;
server_name localhost;

location / {
root regist;
index regist.html;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}

}

往linux再上传需要的静态网页文件

1.还是跟之前一样通过filezilla软件上传到nginx文件下面

2.通过浏览器(记得输入不同的端口号)即可

总结

1
2
其实就是刚才的静态资源配置多配置一个server{} 然后要多有一个端口(我一个是81/一个是82)
然后就可以通过IP地址+不同的端口就可以进行访问

配置文件内部需要增加一个server{}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

server {
listen 82;
server_name localhost;

location / {
root regist;
index regist.html;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}

}

虚拟主机 域名绑定

举例

1.按上面81和82端口的例子:去hosts文件加一个域名绑定

2.我们就可以通过www.ceshi.com然后加上端口访问

更改server里的server_name

我们就可以通过www.ceshi.com然后加上端口访问


反向代理

正向代理(针对客户端)

需求:学生通过主机去找网络连接(VPN)

反向代理(针对服务器端)

需求:通过网络去找部署在linux上的tomcat服务器
    1. 直接访问:tomcat并发低(负载大)
    2. 反向代理:搭建tomcat集群,出现反向代理服务器。由服务器分发到tomcat去,还可以增加在给tomcat时候防火墙提高安全性

反向代理准备

1.将需要的项目打包成war上传(rz)到tomcat的webapps目录下

2.执行tomcat/bin里面的startup.sh 能够通过浏览器打开即可

配置反向代理

1.修改Nginx配置(server{}之前写)

1
2
3
	upstream tomcat-travel{
server 192.168.209.128:8080; # tomcat浏览器的地址配给nginx
}

2.修改nginx.conf配置

1
2
3

1. 将server{}里面的root index注释掉
2. 在下面加 proxy_pass http://tomcat-travel; # tomcat-tarvel可以随便起

3.访问

1
2
3
1. 浏览器输入:server里面的server_name(一般是localhost 但是也可以通过绑定域名(hosts文件改))
2. 然后他这个网络internet会去找nginx代理主机(proxy_pass)
3. 代理主机就去找upstream里面的tomcat

总结

1. 之前的演示:将静态网页直接放在nginx文件夹下 我们通过配置server{}端口和域名然后直接从浏览器访问到了tomcat
2. 反向代理:
    2.1 准备:
        项目打包成war文件放在tomcat/webapps里面 然后通过在nginx配置文件加upstream和更改掉访问的root index 从而加proxy_pass达到功能
    2.2 访问:
        现在就是浏览器写server里面的域名 -->  因为nginx里面配备了proxy_pass所以会到nginx --> http://后面的会去找upstream里面的tomcat -->  从而反向回来反馈到浏览器。
3. 总结:
     因为域名输入后他不知道到底是nginx还是tomcat给的回应,所以后面的两个相当于封装起来提供了安全性

访问时候的分析:


负载均衡

我们搭建很多的tomcat形成tomcat集群(使得nginx寻找的几率相等)

1.需要很多linux机器上拥有tomcat(演示时候是一台linux放三个tomcat)

2.(将tomcat文件复制两份然后依次进去更改其他两个的端口)

3.启动每个linux的tomcat(启动三个tomcat服务器)

4.然后每个linux上的nginx配置反向代理(更改nginx配置文件内部upstream加server(因为端口不一样))

5.通过访问器访问就会不同几率的访问不同的tomcat(配置文件里面可以改浏览器title名称来区别)


Linux部署

Linux部署

修改项目

druid.properties中将url后面加characterEncoding=utf-8

还需要将本地的数据库转成sql文件导入到linux中的数据库中

更改绝对路径为相对路径(localhost:8080)

java里面maven使用插件package打包成war文件

将war包上传到linux的目录下 启动tomcat

通过windows浏览器: localhost:8080/项目名

总结

  其实就是将项目打包成war包然后放在linux里面通过tomcat启动,我们就可以通过windows去启动。

,