mybatis自学历程(一)
第一个mybatis程序
- IDE:myeclipse2017
- jar包:mybatis3.5.2,mybatis依赖包,mysql8.0.17驱动包
注:mybatis包和所需的依赖包,可到http://www.mybatis.cn/下载,mybatis官方文档(可选中文)
1.项目结构图
注:本示例参考于C语言中文网,如对本示例有疑问可查看此网站,看是否能解决问题
2.建库建表
CREATE DATABASE test;
USE test;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`uid` INT UNSIGNED AUTO_INCREMENT,
`uname` varchar(20) DEFAULT NULL,
`usex` varchar(10) DEFAULT NULL,
PRIMARY KEY (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
3.导jar包
4.创建日志文件
MyBatis 默认使用 log4j 输出日志信息,如果开发者需要查看控制台输出的 SQL 语句,那么需要在 classpath 路径下配置其日志文件。在 myBatis应用的 src 目录下创建 log4j.properties 文件,其内容如下:
# Global logging configuration
log4j.rootLogger=ERROR,stdout
# MyBatis logging configuration...
log4j.logger.com.mybatis=DEBUG
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
5.创建持久化类
在 src 目录下创建一个名为 com.mybatis.po 的包,在该包中创建持久化类 MyUser,注意在类中声明的属性与数据表 user 的字段一致。
package com.mybatis.po; public class MyUser {
private Integer uid; // 主键
private String uname;
private String usex;
public Integer getUid() {
return uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getUsex() {
return usex;
}
public void setUsex(String usex) {
this.usex = usex;
} @Override
public String toString() {
return "MyUser [uid=" + uid + ", uname=" + uname + ", usex=" + usex + "]";
} }
6.创建映射文件
在 src 目录下创建一个名为 com.mybatis.mapper 的包,在该包中创建映射文件 UserMapper.xml
<?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.mybatis.mapper.UserMapper">
<!-- 根据uid查询一个用户信息 -->
<select id="selectUserById" parameterType="Integer"
resultType="com.mybatis.po.MyUser">
select * from user where uid = #{uid}
</select>
<!-- 查询所有用户信息 -->
<select id="selectAllUser" resultType="com.mybatis.po.MyUser">
select * from user
</select>
<!-- 添加一个用户,#{uname}为 com.mybatis.po.MyUser 的属性值 -->
<insert id="addUser" parameterType="com.mybatis.po.MyUser">
insert into user (uname,usex)
values(#{uname},#{usex})
</insert>
<!--修改一个用户 -->
<update id="updateUser" parameterType="com.mybatis.po.MyUser">
update user set uname =
#{uname},usex = #{usex} where uid = #{uid}
</update>
<!-- 删除一个用户 -->
<delete id="deleteUser" parameterType="Integer">
delete from user where uid
= #{uid}
</delete>
</mapper>
UserMapper.xml相当于实现类,只不过用xml实现,并添加需要的方法,namespace的值不固定,通过namespace.id 调用相应的增删改查
7.创建mybatis的配置文件
在 src 目录下创建 MyBatis 的核心配置文件 mybatis-config.xml,在该文件中配置了数据库环境和映射文件的位置,具体内容如下:
<?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>
<settings>
<setting name="logImpl" value="LOG4J" />
</settings>
<!-- 配置mybatis运行环境 -->
<environments default="development">
<environment id="development">
<!-- 使用JDBC的事务管理 -->
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<!-- MySQL数据库驱动 -->
<property name="driver" value="com.mysql.cj.jdbc.Driver" />
<!-- 连接数据库的URL -->
<property name="url"
value="jdbc:mysql://localhost:3306/test?serverTimezone=UTC" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
<!-- 将mapper文件加入到配置文件中 -->
<mappers>
<mapper resource="com/mybatis/mapper/UserMapper.xml" />
</mappers>
</configuration>
8.创建测试类
在 src 目录下创建一个名为 com.mybatis.test 的包,在该包中创建 MyBatisTest 测试类
package com.mybatis.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 com.mybatis.po.MyUser; public class MyBatisTest {
public static void main(String[] args) {
try {
// 读取配置文件 mybatis-config.xml
InputStream config = Resources
.getResourceAsStream("mybatis-config.xml");
// 根据配置文件构建SqlSessionFactory
SqlSessionFactory ssf = new SqlSessionFactoryBuilder()
.build(config);
// 通过 SqlSessionFactory 创建 SqlSession
SqlSession ss = ssf.openSession();
// SqlSession执行映射文件中定义的SQL,并返回映射结果
/*
* com.mybatis.mapper.UserMapper.selectUserById 为 UserMapper.xml
* 中的命名空间+select 的 id
*/
// 查询一个用户
MyUser mu = ss.selectOne(
"com.mybatis.mapper.UserMapper.selectUserById", 1);
System.out.println(mu);
// 添加一个用户
MyUser addmu = new MyUser();
addmu.setUname("陈恒");
addmu.setUsex("男");
ss.insert("com.mybatis.mapper.UserMapper.addUser", addmu);
// 修改一个用户
MyUser updatemu = new MyUser();
updatemu.setUid(1);
updatemu.setUname("张三");
updatemu.setUsex("女");
ss.update("com.mybatis.mapper.UserMapper.updateUser", updatemu);
// 删除一个用户
ss.delete("com.mybatis.mapper.UserMapper.deleteUser", 3);
// 查询所有用户
List<MyUser> listMu = ss
.selectList("com.mybatis.mapper.UserMapper.selectAllUser");
for (MyUser myUser : listMu) {
System.out.println(myUser);
}
// 提交事务
ss.commit();
// 关闭 SqlSession
ss.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
测试结果如下图
全局配置文件简说(mybatis-config.xml)
事务管理器(transactionManager)
type=”[JDBC|MANAGED]”
JDBC:使用JDBC原生事务管理方式
MANAGED:把事务转交给其他容器
数据源(dataSource)
type=”[UNPOOLED|POOLED|JNDI]”
POOLED:使用数据库连接池
UNPOOLED:不使用使用数据库连接池,和直接使用JDBC一样
JNDI:java命名目录接口技术
3种查询方式
1.selectList()返回值受List<resultType>属性控制,适用于查询结果都需要遍历的需求
2.selectOne()返回值object,适用于返回结果只是变量或一行数据时
3.selectMap()返回值Map,适用于需要在查询结果中通过某列的值取到这行数据的需要
查询全部
新建表并插入数据,新建项目
jar包跟上个项目一样
package com.mybatis.po; public class People {
private Integer id;
private String name;
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 Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "id=" + id + ", name=" + name + ", age=" + age;
} }
People.java
<?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.mybatis.mapper.PeopleMapper">
<select id="selectAll" resultType="com.mybatis.po.People">
select * from people
</select>
</mapper>
PeopleMapper.xml
<?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>
<settings>
<setting name="logImpl" value="LOG4J" />
</settings>
<!-- 配置mybatis运行环境 -->
<environments default="development">
<environment id="development">
<!-- 使用JDBC的事务管理 -->
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<!-- MySQL数据库驱动 -->
<property name="driver" value="com.mysql.cj.jdbc.Driver" />
<!-- 连接数据库的URL -->
<property name="url"
value="jdbc:mysql://localhost:3306/test?serverTimezone=UTC" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
<!-- 将mapper文件加入到配置文件中 -->
<mappers>
<mapper resource="com/mybatis/mapper/PeopleMapper.xml" />
</mappers>
</configuration>
mybatis.xml
package com.mybatis.service; import java.io.IOException;
import java.util.List; import com.mybatis.po.People; public interface PeopleService {
/**
* 显示全部
*/
List<People> show () throws IOException;
}
PeopleService.java
package com.mybatis.service.impl; 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 org.apache.ibatis.session.defaults.DefaultSqlSessionFactory; import com.mybatis.po.People;
import com.mybatis.service.PeopleService; /**
* 在数据访问层处理异常和在控制器中处理异常,service中抛出异常
* @author Administrator
*
*/
public class PeopleServiceImpl implements PeopleService { @Override
public List<People> show() throws IOException {
InputStream is= Resources.getResourceAsStream("mybatis.xml");
//前面是工厂,实例化工厂对象是使用的构建者设计模式,名称标志是:后面有builder
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(is);
SqlSession session=factory.openSession();
List<People> list= session.selectList("com.mybatis.mapper.PeopleMapper.selectAll");
session.close(); return list;
} }
PeopleServiceImpl.java
package com.mybatis.service; import java.io.IOException;
import java.util.List; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import com.mybatis.po.People;
import com.mybatis.service.impl.PeopleServiceImpl; //大部分注解都有默认属性,如果注解中只给默认属性赋值,就可以省略属性名
//否则在注解中格式为(属性名=属性值)
//如果一个属性是数组类型格式:属性名={值,值},如果该数组只有一个,可以省略大括号
//如果类不是基本数据类型或String而是一个类类型,语法:属性名=@类型
//注解中@表示引用类型
@WebServlet("/abc/d/show")
public class ShowService 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);
//相对路径
//只要路径中以/开头的都叫全路径,从项目根目录(webRoot)出发找到其他资源的过程
//只要不以/开头的都是相对路径,相对路径是从当前资源出发找到其他资源的过程
//如果请求转发/表示webRoot目录
//如果是重定向,静态资源(<img src=""/>, <a href="">,<script src=""/> css ) 引用时,其中/表示的是Tomcat分webapps文件夹根目录
//服务器根目录
req.getRequestDispatcher("/index.jsp").forward(req, resp);
} }
ShowService
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<title>显示全部</title>
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head> <body>
<div class="table-responsive">
<table class="table table-hover">
<caption>人员信息表</caption>
<thead>
<tr>
<th>编号</th>
<th>姓名</th>
<th>年龄</th>
</tr>
</thead>
<c:forEach items="${list }" var ="peo">
<tbody>
<tr>
<td>${peo.id }</td>
<td>${peo.name }</td>
<td>${peo.age }</td>
</tr>
</tbody>
</c:forEach>
</table>
</div>
</body>
</html>
index.jsp
注:查询全部的项目中有相对路径和绝对路径的解释,还有注解的用法的解释
在Mapper.xml中获取参数
parameterType控制参数类型
#{} 获取参数内容
使用索引,从0开始 #{0}表示第一个参数,也可以使用 #{param1}
如果只有一个参数(基本数据类型或String),对 #{} 里面内容没有要求,只要写内容即可,例 #{abc}
如果参数是对象,则 #{属性名}
如果参数是map,则 #{key},key为map的key,使用map传值,是为传多个参数
#{} 和 ${} 的区别
#{} 在sql语句中使用 ? 占位符
${} 在sql语句拼接,不使用 ?,默认找${内容} 内容的get/set方法,如果写数字,就是一个数字,如mybatis01项目中,UserMapper.xml 中的resultType="com.mybatis.po.MyUser",${id},则找MyUser.id值
mybatis中实现mysql简单分页
在mysql数据库People表中添加多条数据
use test; INSERT INTO people VALUES(Default,"张三2",22);
INSERT INTO people VALUES(Default,"张三3",22);
INSERT INTO people VALUES(Default,"张三4",22);
INSERT INTO people VALUES(Default,"张三5",22);
INSERT INTO people VALUES(Default,"张三6",22);
insert
在mybatis02项目中的PeopleMapper.xml,添加select
<?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.mybatis.mapper.PeopleMapper">
<select id="selectAll" resultType="com.mybatis.po.People">
select * from people
</select> <select id="page" resultType="com.mybatis.po.People" parameterType="map">
SELECT * from people LIMIT #{pageStart},#{pageSize}
</select>
</mapper>
PeopleMapper.xml
编写测试类test.java
package com.mybatis.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 com.mybatis.po.People; public class test {
public static void main(String[] args) throws IOException {
InputStream is=Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(is);
SqlSession ss=factory.openSession(); //页码显示的条胡
int pageSize=3;
//第几页
int pageNumber=1; //map传多个参数
Map<String, Object> map=new HashMap<String, Object>();
map.put("pageSize", pageSize);
map.put("pageStart", pageSize*(pageNumber-1)); List<People> lists=ss.selectList("com.mybatis.mapper.PeopleMapper.page",map);
System.out.println(lists); ss.close();
}
}
test.java
typeAliases别名
1.系统内置别名:把类型全小写
2.给某个类起别名,例mybatis02项目中的mybatis.xml,添加typeAliases标签,注意<typeAliases>标签位置,可以鼠标放在configration上,有提示标签位置,
修改PeopleMapper.xml中select的resultType为peo
3.直接给某个包下所有类起别名,别名为类名,区分大小写
在typeAliases标签中添加package标签,name值为包名
修改select标签中的resultType的值为People
mybatis实现新增和事务讲解
1.概念复习
1.1 功能:从应用程序角度出发,软件具有哪些功能
1.2 业务:完成功能时的逻辑,对应service中的一个方法
1.3 事务:从数据库角度出发,完成业务时需要执行的sql集合,统一一个事务
1.3.1 事务回滚:如果在一个事务中sql执行事务,希望回归到事务的原点,保证数据库数据的完整性()
2.在mybatis中默认是关闭JDBC的自动提交功能
2.1 每个sqlsession默认都是不自动提交功能
2.2 session.commit() 提交事务
2.3 设置openSession(true) 自动提交事务
3.mybatis底层是对JDBC的封装
3.1 JDBC中executeUpdate()执行新增,删除,修改的sql返回值为int,表示受影响的行数
3.2 mybatis中<insert>,<update>,<delete>标签是没有resultType属性,默认都是int,原因是3.1
4.事务对象
4.1 在openSesion()时mybatis会在创建sqlsession的同时创建一个Transaction(事务对象),同时autoCommit都为false
4.2 如果出现异常,应该session..rollback()回滚事务
回滚事务测试:
mybatis02项目中修改PeopleMapper.xml代码,添加insert
<?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.mybatis.mapper.PeopleMapper">
<select id="selectAll" resultType="com.mybatis.po.People">
select * from people
</select> <select id="page" resultType="People" parameterType="map">
SELECT * from people LIMIT #{pageStart},#{pageSize}
</select> <insert id="insPeople" parameterType="People">
insert into people values(default,#{name},#{age})
</insert>
</mapper>
PeopleMapper.xml
package com.mybatis.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 com.mybatis.po.People; public class test {
public static void main(String[] args) throws IOException {
InputStream is = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
SqlSession ss = factory.openSession(); // 页码显示的条胡
// int pageSize=3;
// 第几页
// int pageNumber=1; // map传多个参数
// Map<String, Object> map=new HashMap<String, Object>();
// map.put("pageSize", pageSize);
// map.put("pageStart", pageSize*(pageNumber-1)); // List<People>
// lists=ss.selectList("com.mybatis.mapper.PeopleMapper.page",map);
// System.out.println(lists); People people = new People();
people.setName("小柒");
people.setAge(19); People people2 = new People();
people.setName("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
people.setAge(20); try {
ss.insert("com.mybatis.mapper.PeopleMapper.insPeople", people); ss.insert("com.mybatis.mapper.PeopleMapper.insPeople", people2);
} catch (Exception e) {
System.out.println("people2的name长度过长,所以回滚事务,导致people也新增失败");
ss.rollback();
} // 提交事务
ss.commit();
// 关闭session
ss.close();
}
}
test.java
结果如下:
分页
项目结构图:
导入jar包,在src下新建文件log4j.properties
# Global logging configuration
log4j.rootLogger=ERROR,stdout,R
# MyBatis logging configuration...
log4j.logger.com.mybatis=DEBUG
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
log4j.appender.R.File=D\:\\temp\\logs\\qc.log
log4j.appender.R.layout=org.apache.log4j.PatternLayout
1log4j.appender.R.layout.ConversionPattern=%5p [%t] - %m%n
log4j.properties
复制mybatis02中mybatis.xml,基本无改变
<?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>
<settings>
<setting name="logImpl" value="LOG4J" />
</settings>
<typeAliases>
<!-- <typeAlias type="com.mybatis.po.People" alias="peo"/> -->
<package name="com.mybatis.po"/>
</typeAliases>
<!-- 配置mybatis运行环境 -->
<environments default="development">
<environment id="development">
<!-- 使用JDBC的事务管理 -->
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<!-- MySQL数据库驱动 -->
<property name="driver" value="com.mysql.cj.jdbc.Driver" />
<!-- 连接数据库的URL -->
<property name="url"
value="jdbc:mysql://localhost:3306/test?serverTimezone=UTC" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
<!-- 将mapper文件加入到配置文件中 -->
<mappers>
<mapper resource="com/mybatis/mapper/PeopleMapper.xml" />
</mappers>
</configuration>
mybatis.xml
com.mybatis.po包
package com.mybatis.po; public class People {
private Integer id;
private String name;
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 Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "id=" + id + ", name=" + name + ", age=" + age;
} }
People.java
package com.mybatis.po; 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;
} }
PageInfo.java
com.mybatis.mapper包
<?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.mybatis.mapper.PeopleMapper">
<!-- 查询分页sql语句 -->
<select id="selByPage" resultType="People" parameterType="map">
SELECT * FROM people LIMIT #{pageStart},#{pageSize}
</select> <!-- 查询数据总条数 -->
<select id="selCount" resultType="long">
select COUNT(1) from people
</select>
</mapper>
People.xml
com.mybatis.service包
package com.mybatis.service; import java.io.IOException; import com.mybatis.po.PageInfo; public interface PeopleService {
/**
* 分页显示
* @param pageSize
* @param pageNumber
* @return
* @throws IOException
*/
PageInfo showPage(int pageSize,int pageNumber) throws IOException;
}
PeopleService.java
com.mybatis.service.impl包
package com.mybatis.service.impl; import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
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 com.mybatis.po.PageInfo;
import com.mybatis.service.PeopleService; public class PeopleServiceImpl implements PeopleService { @Override
public PageInfo showPage(int pageSize, int pageNumber) throws IOException {
InputStream is= Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(is);
SqlSession session=factory.openSession();
Map<String, Object> map=new HashMap<>();
map.put("pageStart", pageSize*(pageNumber-1));
map.put("pageSize", pageSize); PageInfo pi=new PageInfo();
pi.setPageSize(pageSize);
pi.setPageNumber(pageNumber);
pi.setList(session.selectList("com.mybatis.mapper.PeopleMapper.selByPage",map));
long count=session.selectOne("com.mybatis.mapper.PeopleMapper.selCount"); pi.setTotal(count%pageSize==0?count/pageSize:count/pageSize+1);
return pi;
} }
PeopleServiceImpl.java
com.mybatis.servlet包
package com.mybatis.servlet; import java.io.IOException; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import com.mybatis.po.PageInfo;
import com.mybatis.service.PeopleService;
import com.mybatis.service.impl.PeopleServiceImpl; @WebServlet("/page")
public class ShowPageServlet extends HttpServlet {
private PeopleService peopleService= new 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);
req.setAttribute("PageInfo", pi);
req.getRequestDispatcher("index.jsp").forward(req, resp);
} }
ShowPageServlet.java
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>分页</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>
<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>
index.jsp
people表数据
运行结果如下:
转账,日志及分页案例
新建项目mybatis04,项目图结构如下
导入jar包
<?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>
<settings>
<setting name="logImpl" value="LOG4J" />
</settings>
<typeAliases>
<!-- <typeAlias type="com.mybatis.po.People" alias="peo"/> -->
<package name="com.mybatis.po" />
</typeAliases>
<!-- 配置mybatis运行环境 -->
<environments default="development">
<environment id="development">
<!-- 使用JDBC的事务管理 -->
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<!-- MySQL数据库驱动 -->
<property name="driver" value="com.mysql.cj.jdbc.Driver" />
<!-- 连接数据库的URL -->
<property name="url"
value="jdbc:mysql://localhost:3306/test?serverTimezone=UTC" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
<!-- 将mapper文件加入到配置文件中 -->
<mappers>
<mapper resource="com/mybatis/mapper/AccountMapper.xml" />
<mapper resource="com/mybatis/mapper/LogMapper.xml" />
</mappers>
</configuration>
mybatis.xml
# Global logging configuration
log4j.rootLogger=Info,stdout,R
# MyBatis logging configuration...
log4j.logger.com.mybatis=DEBUG
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
log4j.appender.R.File=D\:\\logs\\log.log
log4j.appender.R.layout=org.apache.log4j.PatternLayout
1log4j.appender.R.layout.ConversionPattern=%m %n
log4j.properties
com.mybatis.po包
package com.mybatis.po; public class Account {
private int id;
private String accNo;
private int password;
private String name;
private double balance;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAccNo() {
return accNo;
}
public void setAccNo(String accNo) {
this.accNo = accNo;
}
public int getPassword() {
return password;
}
public void setPassword(int password) {
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
} }
Account.java
package com.mybatis.po; public class Log {
private int id;
private String accIn;
private String accOut;
private double money;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAccIn() {
return accIn;
}
public void setAccIn(String accIn) {
this.accIn = accIn;
}
public String getAccOut() {
return accOut;
}
public void setAccOut(String accOut) {
this.accOut = accOut;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
} }
Log.java
package com.mybatis.po; 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;
} }
PageInfo.java
com.mybatis.mapper
<?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.mybatis.mapper.AccountMapper">
<!-- 根据账号和密码查询信息 -->
<select id="selByAccnoPwd" resultType="Account" parameterType="Account">
SELECT * from account where accno=#{accNo} and password =#{password}
</select> <!-- 根据账号和姓名查询信息 -->
<select id="selByAccnoName" resultType="Account" parameterType="Account">
SELECT * from account where accno=#{accNo} and name =#{name}
</select> <!-- 转账 -->
<update id="updBalanceByAccno" parameterType="Account">
UPDATE account set balance=balance+#{balance} where accno=#{accNo}
</update>
</mapper>
AccountMapper.xml
<?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.mybatis.mapper.LogMapper">
<!-- 插入转账记录 -->
<insert id="insLog" parameterType="Log">
insert into log values(default,#{accOut},#{accIn},#{money})
</insert>
<!-- 转账日志表分页数据 -->
<select id="selByPage" parameterType="map" resultType="Log">
select * from log limit #{pageStart},#{pageSize}
</select>
<!-- 日志表的总条数 -->
<select id="selCount" resultType="long">
select count(1) from log
</select>
</mapper>
LogMapper.xml
com.mybatis.service
package com.mybatis.service; import java.io.IOException; import com.mybatis.po.Account; public interface AccountService {
/**
* 账号和密码不匹配码
*/
int ACCOUNT_PASSWORD_NOT_MATCH=1; /**
* 余额不足
*/
int ACCOUNT_BALANCE_NOT_ENOUGH=2; /**
* 账户姓名不匹配
*/
int ACCOUNT_NAME_MATCH=3; /**
* 异常,转账失败
*/
int ERROR=4; /**
* 转账成功
*/
int SUCCESS=5; /**
* 转账
* @param accIn 收账账号
* @param accOut 转账账号
* @return
*/
int transfer(Account accIn,Account accOut) throws IOException;
}
AccountService.java
package com.mybatis.service; import java.io.IOException; import com.mybatis.po.PageInfo; public interface LogService {
/**
* 分页显示
* @param pageSize
* @param pageNumber
* @return
*/
PageInfo showPage(int pageSize,int pageNumber) throws IOException;
}
LogService.java
com.mybatis.service.impl
package com.mybatis.service.impl; import java.io.IOException;
import java.io.InputStream;
import java.util.Date; 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.apache.log4j.Logger; import com.mybatis.po.Account;
import com.mybatis.po.Log;
import com.mybatis.service.AccountService; public class AccountServiceImpl implements AccountService { @Override
public int transfer(Account accIn, Account accOut) throws IOException {
InputStream is=Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(is);
SqlSession session=factory.openSession(); //先判断账号和密码是否配备
Account accOutSelect=session.selectOne("com.mybatis.mapper.AccountMapper.selByAccnoPwd",accOut);
if (accOutSelect!=null) {
//判断余额是否大于或等于取款金额
if(accOutSelect.getBalance()>=accOut.getBalance()){
Account accInSelect=session.selectOne("com.mybatis.mapper.AccountMapper.selByAccnoName",accIn);
//判断账号和姓名是否正确
if(accInSelect!=null){
//设置收款账号的收入金额
accIn.setBalance(accOut.getBalance());
//设置转账账号的转出金额
accOut.setBalance(-accOut.getBalance());
int index=session.update("com.mybatis.mapper.AccountMapper.updBalanceByAccno",accOut);
index+=session.update("com.mybatis.mapper.AccountMapper.updBalanceByAccno",accIn);
if(index==2){
//数据库日志表记录
Log log=new Log();
log.setAccIn(accIn.getAccNo());
log.setAccOut(accOut.getAccNo());
log.setMoney(accIn.getBalance());
session.insert("com.mybatis.mapper.LogMapper.insLog",log);
//日志文件记录
Logger logger=Logger.getLogger(AccountServiceImpl.class);
logger.info(log.getAccOut()+"给"+log.getAccIn()+"在"+new Date().toLocaleString()+"转了"+log.getMoney()); session.commit();
session.close();
return SUCCESS;
}else {
session.rollback();
session.close();
return ERROR;
}
}else {
//账号姓名不匹配
session.close();
return ACCOUNT_NAME_MATCH;
}
}else {
//余额不足
session.close();
return ACCOUNT_BALANCE_NOT_ENOUGH;
}
}else {
//账号密码不匹配
session.close();
return ACCOUNT_PASSWORD_NOT_MATCH;
}
} }
AccountServiceImpl.java
package com.mybatis.service.impl; 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 com.mybatis.po.Log;
import com.mybatis.po.PageInfo;
import com.mybatis.service.LogService; public class LogServiceImpl implements LogService { @Override
public PageInfo showPage(int pageSize, int pageNumber) throws IOException {
InputStream is= Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(is);
SqlSession session=factory.openSession(); Map<String, Object> param=new HashMap<String, Object>();
param.put("pageStart", pageSize*(pageNumber-1));
param.put("pageSize", pageSize);
List<Log> list=session.selectList("com.mybatis.mapper.LogMapper.selByPage",param);
long count=session.selectOne("com.mybatis.mapper.LogMapper.selCount"); PageInfo pi=new PageInfo();
pi.setList(list);
pi.setPageNumber(pageNumber);
pi.setPageSize(pageSize);
pi.setTotal(count%pageSize==0?count/pageSize:count/pageSize+1);
return pi;
} }
LogServiceImpl.java
com.mybatis.servlet
package com.mybatis.servlet; import java.io.IOException; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import com.mybatis.service.LogService;
import com.mybatis.service.impl.LogServiceImpl; @WebServlet("/show")
public class ShowServlet extends HttpServlet {
private LogService LogService=new LogServiceImpl(); @Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//判断是否是第一次打开,如果是,则显示第一页
int pageSize=2;
String pageSizeStr=req.getParameter("pageSize");
if(pageSizeStr!=null&&!pageSizeStr.equals("")){
pageSize=Integer.parseInt(pageSizeStr);
} int pageNumber=1;
String pageNumberStr=req.getParameter("pageNumber");
if(pageNumberStr!=null&&!pageNumberStr.equals("")){
pageNumber=Integer.parseInt(pageNumberStr);
} req.setAttribute("pageInfo", LogService.showPage(pageSize, pageNumber));
req.getRequestDispatcher("log.jsp").forward(req, resp);
} }
ShowServlet.java
package com.mybatis.servlet; import java.io.IOException; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import com.mybatis.po.Account;
import com.mybatis.service.AccountService;
import com.mybatis.service.impl.AccountServiceImpl; @WebServlet("/transfer")
public class TransferServlet extends HttpServlet {
private AccountService accService=new AccountServiceImpl(); @Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
Account accOut=new Account();
accOut.setAccNo(req.getParameter("accOutNo"));
accOut.setPassword(Integer.parseInt(req.getParameter("accOutPwd")));
accOut.setBalance(Double.parseDouble(req.getParameter("accOutBalance"))); Account accIn=new Account();
accIn.setAccNo(req.getParameter("accInAccNo"));
accIn.setName(req.getParameter("accInName"));
int index=accService.transfer(accIn, accOut);
if(index==AccountService.SUCCESS){
resp.sendRedirect("/mybatis04/show");
}else {
HttpSession session=req.getSession();
session.setAttribute("code", index);
resp.sendRedirect("/mybatis04/error.jsp");
}
} }
TransferServlet.java
WebRoot
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'error.jsp' starting page</title> </head> <body>
对不起操作失败:<br/>
错误原因:
${ sessionScope.code }
</body>
</html>
error.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head> <title>转账记录</title>
</head> <body>
<table border=1>
<tr>
<th>转账账号</th>
<th>收账账号</th>
<th>转账金额</th>
</tr>
<c:forEach items="${pageInfo.list }" var="log">
<tr>
<td>${log.accOut }</td>
<td>${log.accIn }</td>
<td>${log.money }</td>
</tr>
</c:forEach>
</table>
<a href="show?pageSize=${pageInfo.pageSize }&pageNumber=${pageInfo.pageNumber -1 } " <c:if test="${pageInfo.pageNumber<=1 }" > onclick="javascript:return false" </c:if>>上一页</a>
<a href="show?pageSize=${pageInfo.pageSize }&pageNumber=${pageInfo.pageNumber +1 } " <c:if test="${pageInfo.pageNumber>=pageInfo.total }"> onclick="javascript:return false" </c:if>>下一页</a>
</body>
</html>
log.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>转账</title>
</head> <body>
<form action="transfer" method="post">
转账账户:<input type="text" name="accOutNo"/><br/>
密码:<input type="password" name="accOutPwd" /><br/>
金额:<input type="text" name="accOutBalance" /><br/> 收款账户:<input type="text" name="accInAccNo"/><br/>
收款人姓名:<input type="text" name="accInName"/><br/>
<input type="submit" value="转账">
</form>
</body>
</html>
index.jsp
mybatis自学历程(一)的更多相关文章
- mybatis自学历程(二)
传递多个参数 1.在mybatis.xml下<mappers>下使用<package> <mappers> <package name="com.m ...
- 分享一下我的Python自学历程,分享下我自己学习方法
其实关于编程这事儿没有接触的那么早,大一的时候没什么关注点,有一门课是vb,一天天的,就抄抄作业啥的就完事儿了.当时也觉的自己不是学编程的料,想着以后估摸也不会干开发相关的工作. 我的自学历程 阴差阳 ...
- Himi浅谈游戏开发de自学历程!(仅供参考)
李华明Himi原创,转载务必在明显处注明: 转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/himistudy/382.html ☞ 点击订阅 ☜ 本博客 ...
- mybatis 自学笔记
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.本页作为自学整理资料,信息来源网络,侵权速联,但大部份经过自己测试.使用说明:本人测试用编辑软件eclipse_st ...
- Mybatis 学习历程
MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架. MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装. MyBatis可以使用简单的XML或注 ...
- spring自学历程
spring几大核心功能 1.IOC/DI(控制反转/依赖注入) IOC是什么?IOC完成的事情是原先程序员主动通过new实例化对象的事情,转交给spring负责 IOC最大的作用是:解耦,程序员不需 ...
- GPU编程自学7 —— 常量内存与事件
深度学习的兴起,使得多线程以及GPU编程逐渐成为算法工程师无法规避的问题.这里主要记录自己的GPU自学历程. 目录 <GPU编程自学1 -- 引言> <GPU编程自学2 -- CUD ...
- GPU编程自学6 —— 函数与变量类型限定符
深度学习的兴起,使得多线程以及GPU编程逐渐成为算法工程师无法规避的问题.这里主要记录自己的GPU自学历程. 目录 <GPU编程自学1 -- 引言> <GPU编程自学2 -- CUD ...
- GPU编程自学5 —— 线程协作
深度学习的兴起,使得多线程以及GPU编程逐渐成为算法工程师无法规避的问题.这里主要记录自己的GPU自学历程. 目录 <GPU编程自学1 -- 引言> <GPU编程自学2 -- CUD ...
随机推荐
- QT简介及下载
| 版权声明:本文为博主原创文章,未经博主允许不得转载. Qt是一个1991年由奇趣科技开发的跨平台C++图形用户界面应用程序开发框架.它既可以开发GUI程序,也可用于开发非GUI 程序,比如控制 ...
- jquery 的几种写法和常见问题
为了理解页面初始化事件的编写和执行方式,特此记录下页面加载事件的语句方式: //最简单的加载事件语句 $(function(){ alert("这个提示框最先弹出")//这个用的最 ...
- v8引擎的优化
1.编译优化 V8采用JIT即使编译技术. 例如JAVA是先编译成字节码,再由JVM编译成机器码,V8则没有中间的字节码,直接由源码生成语法树,然后编译成机器码. 2.隐藏类 当定义一个构造函数,使用 ...
- 函数体中return下面的代码不执行,但是需要预解析
//函数体中return下面的代码不执行,但是需要预解析 function fn(){ console.log(num);//undefined return function(){ }; var n ...
- 2019牛客暑期多校训练营(第九场)A.The power of Fibonacci
题意:给出n和m,f(n)是斐波那契额数列的第n项,要求计算ans=f(1)^m+f(2)^m+....f(n)^m.即斐波那契额数列前n项的m次幂和. 解法:这题好像有两种解法:一种是循环节+CRT ...
- 2019 ICPC Universidad Nacional de Colombia Programming Contest C D J
C. Common Subsequence 题意:给出长度为n两个串,求两个串的最长公共子序列len,如果len>=0.99*n,两个串就是亲兄弟否则不是. 解法:朴素的求LCS的时间复杂度是O ...
- python5数据存储
1 txt文件存储 正常调用文件python文件操作 https://www.cnblogs.com/x2x3/p/9979919.html 2 json文件存储 在JavaScript语言中,一切都 ...
- 调整Winfrom控件WebBrowser的默认浏览器内核版本
一.问题解析: 今天在调试程序的时候,需要使用C#的客户端远程登录一个Web页面,用到了WebBrowser控件.但是却发现了一件很神奇的事情:当前浏览器使用的内核,可以通过访问下面这个网站获取:ht ...
- 数组(R语言)
myarray = <- array (vector, dimensions, dimnames) 例如,生成一个2*3*4的数组: dim1 <- c("A1",&q ...
- ofbiz webservice 例解
1.定义controller.xml文件,controller文件:ofbiz当前项目的所有请求的入口,通过对应request-map:将所有的请求uri对应到指定的处理函数上. <reques ...