一、Mybatis 概述
- Mybatis 是一个使用java编写的持久层框架。它封装了 JDBC ,使开发者只需要关注 sql 语句,而无需关注注册驱动、创建连接、创建 Statement 等繁杂的过程。
- 采用了 ORM 思想 实现了结果集的封装
- ORM(Object Relational Mapping)对象关系映射。简单地说,就是把数据库表和实体类及实体类的属性对应起来,让我们可以通过操作实体类来操作数据库表。
二、Mybatis 实现CUD
2.1 项目结构
2.2 导入jar包
mybatis-3.5.4.jar
mysql-connector-java-8.0.19.jar
可选:lombok-1.12.2.jar
2.3 编写mybatis-config.xml配置文件
在src目录下创建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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>
根据自身需求修改后:
<?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:约束文件,声明指定了一些标签,那么在引入了dtd文件的xml就只能够使用这些声明和的标签
不能随意乱写
-->
<configuration>
<!-- 引入分页插件 -->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
</plugin>
</plugins>
<!-- 环境:可以配置多个环境
default用于指定当前mybatis操作哪个数据库
-->
<environments default="development">
<environment id="development">
<!-- 事务管理器:
type="JDBC":使用JDBC的事务管理器管理事务
-->
<transactionManager type="JDBC"/>
<!-- 配置数据源参数:
type:POOLED 连接池:创建、管理数据库连接 connection对象
举例:c3p0、dbcp、druid、hikari...
POOLED 表示使用连接池 mybatis自带的
-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/woniumall?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- 加载映射文件
mybatis中将编写SQL语句的文件的叫做mapper文件
-->
<mappers>
<!-- 加载mapper文件:读取mapper文件中的内容 sql,存放在内存中
快速注释:Ctrl+shift+/
反注释:Ctrl+shift+\
-->
<!-- <mapper resource="org/mybatis/example/UserMapper.xml"/> -->
<mapper resource="com/woniuxy/mapper/UserMapper.xml"/>
<mapper resource="com/woniuxy/mapper/GoodsMapper.xml"/>
</mappers>
</configuration>
2.4 创建User实体类
package com.woniuxy.entity;
import java.util.Date;
import lombok.Data;
@Data
public class User {
private int id; // id
private String account; // 账号
private String password; // 密码
private String email; // 邮箱
private String avatar; // 头像
private int score; // 积分
private Date regtime; // 注册时间
private String status; // 状态
}
由于导入了lombok.jar,可以使用@Data代替set,get,toString
2.5 编写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">
<!-- namespace:命名空间,作用与包名一样,区分相同id的SQL -->
<mapper namespace="abc">
<!-- id为SQL的唯一标识,同一命名空间下不能有id相同的SQL
resultType:将查询出来的数据封装成什么类型的对象
-->
<select id="findAll" resultType="com.woniuxy.entity.User">
select * from mall_user
</select>
<!-- 增 -->
<insert id="add">
insert into mall_user
values (default,#{account},#{password},#{email},
#{avatar},#{score},#{regtime},#{status})
</insert>
<!-- 删
如果参数是基本数据类型、包装类、string类型,获取参数时名字可以随意取
但是建议与要操作的字段名字保持一致
-->
<delete id="delById">
delete from mall_user where id = #{id};
</delete>
<!-- 改 -->
<update id="changePwd">
update mall_user set password = #{password} where account = #{account}
</update>
</mapper>
2.6 创建CUD测试类,测试增、删、改功能
package com.woniuxy.test;
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;
public class CUDTest {
public static void main(String[] args) throws IOException {
// 自动到src下寻找配置文件
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
// 创建工厂
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
// 创建Sqlsession实例
// Sql会话
SqlSession session = factory.openSession();
// insert 新用户注册
// User user = new User();
// user.setAccount("sunqi");
// user.setPassword("123456");
// user.setEmail("55555@qq.com/");
// user.setRegtime(new Date());
// user.setStatus("0"); // 0表示新注册,未激活
// 执行SQL
// 添加user
// session.insert("abc.add", user);
// delete 根据id删除user
// session.delete("abc.delById", 4);
// update 修改密码,以账号作为条件 修改密码
// User user = new User();
// user.setAccount("zhangsan");
// user.setPassword("666");
// session.update("abc.changePwd", user);
// map传参,此时Mapper的SQL中,#{ }中的值是Map的Key值
Map<String, Object> params = new HashMap<>();
params.put("account", "zhangsan");
params.put("password", "9999999");
session.update("abc.changePwd", params);
// mybatis 关闭了自动提交,需要手动提交
session.commit();
session.close();
}
}
三、日志
3.1 导入jar包
logback-classic-1.2.3.jar
logback-core-1.2.3.jar
slf4j-api-1.7.30.jar
**
3.2 编写logback.xml配置文件
<configuration>
<!-- 将日志输出到指定位置
ConsoleAppender 控制台
-->
<appender name="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%logger{35} - %msg %n</pattern>
</encoder>
</appender>
<!-- 全局设置记录日志的级别 -->
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
<!-- 指定日志输出级别 additivity=false 避免日志重复打印-->
<logger name="com.woniuxy.mapper" level="debug" additivity="false">
<appender-ref ref="STDOUT" />
</logger>
<!-- 过滤无用的日志 -->
<logger name="org.apache.ibatis.io" level="info">
<appender-ref ref="STDOUT" />
</logger>
</configuration>
四、分页插件
3.1 导入jar包
pagehelper-5.1.11.jar
jsqlparser-2.0.jar
**
3.2 配置拦截器
在mybatis-config.xml中,在
<!-- 引入分页插件 -->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
</plugin>
</plugins>
五、Mybatis实现查询
5.1 创建Goods实体类
package com.woniuxy.entity;
import java.math.BigDecimal;
import java.util.Date;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain=true) // 开启链式表达
public class Goods {
private int id; //主键id
private String name; //商品名
private String goodsno; //商品编号
private String author; //作者
private String publisher; //出版社
private String pubtime; //发布时间
private int categoryid; //类别id
private String description; //详情
private String image; //商品图片
private int stock; //库存
private BigDecimal marketprice; //原价
private BigDecimal salesprice; //销售价
private BigDecimal score; //评分
private int remarknums; //评论数
private Date uptime; //上架日期
private int salenums; //销量
private String newest; //新品
private String hot; //热卖商品
private String status; //商品状态
}
注:@Accessors(chain=true)
作用:方便在属性过多的实体类中单独设置属性参数
举例:
package com.woniuxy.test;
import com.woniuxy.entity.Goods;
public class LombokTest {
public static void main(String[] args) {
// 链式表达
Goods goods = new Goods().setAuthor("张三").setHot("yes");
goods.setId(1).setStatus("1");
}
}
5.2 编写GoodsMapper.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="goods">
<!-- 查询所有商品 -->
<select id="findAll" resultType="com.woniuxy.entity.Goods">
select * from mall_goods
</select>
<!-- 通过商品id查询商品信息 -->
<select id="findById" resultType="com.woniuxy.entity.Goods">
select * from mall_goods where id = #{id}
</select>
<!-- 模糊查询 -->
<select id="findByNameLike" resultType="com.woniuxy.entity.Goods">
select * from mall_goods where name like #{name}
</select>
<!-- 分页查询 -->
<select id="findByPage" resultType="com.woniuxy.entity.Goods">
select * from mall_goods limit #{index},#{size}
</select>
</mapper>
5.3 创建GoodsTest测试类,测试各类查询
package com.woniuxy.test;
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.woniuxy.entity.Goods;
public class GoodsTest {
public static void main(String[] args) throws IOException {
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = factory.openSession();
// 根据id查询商品信息
// Goods goods = session.selectOne("goods.findById", 2);
// System.out.println(goods);
// 根据name模糊查询商品信息
// List<Goods> goods = session.selectList("goods.findByNameLike", "%IT%");
// for (Goods goods2 : goods) {
// System.out.println(goods2);
// }
// 分页查询
int page = 5;
int size = 10;
Map<String, Object> params = new HashMap<String, Object>();
params.put("index", (page - 1) * size);
params.put("size", size);
List<Goods> goods = session.selectList("goods.findByPage", params);
for (Goods goods2 : goods) {
System.out.println(goods2);
}
session.close();
}
}
5.4 利用分页插件进行分页查询
在四中已配置好分页插件,创建PageTest测试类与接收分页数据的PageUtil工具类
PageTest:
package com.woniuxy.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.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.woniuxy.entity.Goods;
import com.woniuxy.utils.PageUtil;
public class PageTest {
public static void main(String[] args) throws IOException {
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = factory.openSession();
// 设置分页的参数
// 参数1:页码
// 参数2:每页大小
PageHelper.startPage(10, 5);
// 查询数据 利用查询所有商品的SQL实现分页查询
List<Goods> goods = session.selectList("goods.findAll");
for (Goods goods2 : goods) {
System.out.println(goods2);
}
// 获取分页信息
PageInfo<Goods> info = new PageInfo<Goods>(goods);
// 当前页数
System.out.println(info.getPageNum());
// 总页数
System.out.println(info.getPages());
// 总条数
System.out.println(info.getTotal());
// 上一页页数
System.out.println(info.getPrePage());
// 下一页页数
System.out.println(info.getNextPage());
// 将数据封装到PageUtil中,用来向浏览器返回数据
PageUtil pageUtil = new PageUtil();
pageUtil.setCurrentPage(info.getPageNum());
pageUtil.setGoods(goods);
pageUtil.setPageSize(info.getPageSize());
pageUtil.setTotla(info.getTotal());
pageUtil.setTotalPages(info.getPages());
System.out.println(pageUtil);
session.close();
}
}
PageUtil:
package com.woniuxy.utils;
import java.util.List;
import com.woniuxy.entity.Goods;
import lombok.Data;
@Data
public class PageUtil {
private int currentPage; // 当前页码
private int pageSize; // 每一页多大
private Long totla; // 总条数
private int totalPages; // 总页数
private List<Goods> goods; // 当前页数据
}
注:有了分页插件后,设置好分页参数,只需要使用全查询,即可实现分页查询
**
六、mybatis执行逻辑顺序
1、首先通过输入流读取mybatis.xml与mapper.xml文件中的配置信息
2、创建session,一个session就是一次会话
3、通过selectList方法中的参数找到对应的sql语句,同时创建一个statement去查询数据库
4、查询时会得到一个ResultSet,mybatis框架根据反射自动的将得到的数据封装成pojo类对象
5、如果是selectList方法,则会自动将这些对象封装成List对象并返回