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; } }
<?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>
<?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>
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; }
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; } }
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); } }
<%@ 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>
注:查询全部的项目中有相对路径和绝对路径的解释,还有注解的用法的解释
在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);
在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>
编写测试类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(); } }
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>
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(); } }
结果如下:
分页
项目结构图:
导入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
复制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>
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; } }
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; } }
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>
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; }
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; } }
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); } }
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>
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>
# 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
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; } }
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; } }
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; } }
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>
<?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>
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;
}
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; }
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; } } }
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; } }
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); } }
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"); } } }
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>
<%@ 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>
<%@ 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>