cuterabbitbaby 2020-05-29
什么是mybatis
MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Ordinary Java Objects,普通的 Java对象)映射成数据库中的记录。

Mybatis的功能架构分为三层

看完上面一定要去官网:MyBatis官网https://mybatis.org/mybatis-3/zh/index.html
MyBatis搭建坏境
1.创建一个普通的maven项目
2.如同官网说的一样去添加MyBatis的maven依赖,项目入手看官网!

3XML 配置文件中配置对 MyBatis 系统的核心设置,(官网有)
如创建一个xml在resources(资源文件)下如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> <typeAliases> <package name="com.yj.pojo"></package> </typeAliases> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis1?serverTimezone=UTC"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <mappers> <mapper resource="com/yj/dao/UserMapper.xml"/> </mappers></configuration>
如果下面过程遇到问题,大部分都是因为mybatis用的maven,maven的约定大于配置设置,maven默认的静态资源放在resources下面但是我们想用在java下
所以经常遇到静态资源过滤问题所以再pom中添加
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>===============================
String resource = "org/mybatis/example/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
try (SqlSession session = sqlSessionFactory.openSession()) {
BlogMapper mapper = session.getMapper(BlogMapper.class);
Blog blog = mapper.selectBlog(101);
}不过有了上面的基础那我们就可以写一个工具类,感觉类似于JDBC的Tool
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 java.io.IOException;
import java.io.InputStream;
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
//获取SqlSession连接
public static SqlSession getSession(){
return sqlSessionFactory.openSession(); //openSesison就是返回一个SqlSession
}
}有了这个就可以编写实体类,接口这些了
来一个举例
创建实体类
public class User {
private int id; //id
private String name; //姓名
private String pwd; //密码
//构造,有参,无参
//set/get
//toString()
}
编写Mapper接口类
import com.yang.pojo.User;
import java.util.List;
public interface UserMapper {
List<User> selectUser();
}在以前我们的JDBC是不是还要写如何数据库与实体类的操作等对吧,
比如在有一个USerDao接口就需要实现类UserDaoImpl(名字不同而已),然后去一一实现UserMapper里面接口方法,
大概这样

但是myBatis不需要,直接不需要创建实现接口的类,不再需要impl这就是Mybatis的优势方便,所以上图的不再需要
相对于用注解或者xml代替了以前的实现类
在UserMapper实体类下建立一个UserMapper.xml(其实也可以建立在resources下,并且建立相同的包名下)
路径方式一

路径方式二

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.yang.dao.UserMapper">
<select id="selectUser" resultType="com.kuang.pojo.User">
select * from user
</select>
</mapper>或者直接在接口注解
public interface UserMapper {
@Select("SELECT * FROM mybatis.user")
List<User> selectUser();
}然后测试一下
public class MyTest {
@Test
public void selectUser() {
SqlSession session = MybatisUtils.getSession(); //借助前面的工具类,返回SqlSession
//方法一:
//List<User> users = session.selectList("com.yang.mapper.UserMapper.selectUser");
//方法二:推荐
UserMapper mapper = session.getMapper(UserMapper.class); //类名
List<User> users = mapper.selectUser();
for (User user: users){
System.out.println(user);
}
session.close();
}
}xml中需要注意的
第一:namespace是包下面的类名
第二: SQL语句前的选择器分别是识别的id,返回的类型,传进的参数类型parameterType等
属性字段和数据库字段一样的话类型处理器帮你处理
但是不一样就要起别名,

或者resultmap

然后参考官方文档发现
一致的名字可以省略
然后最后说一下万能map
在传参或者返回时有时不是我们的类或者int string等简单类型需要用map中间调节一下

看一个以前的综合案例,里面也有map的使用
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等于绑定一个对应的dao/mapper接口-->
<mapper namespace="com.yj.dao.UserMapper">
<select id="getUserList" resultType="user">
select * from mybatis1.user;
</select>
<update id="updateUser" parameterType="user" >
update mybatis1.user set name=#{name},pwd=#{pwd} where id=#{id};
</update>
<select id="likeUser" resultType="user">
select * from mybatis1.user where name like #{value};
</select>
<select id="getUserById" parameterType="int" resultType="user">
select * from mybatis1.user where id=#{int};
</select>
<insert id="addUser" parameterType="user">
insert into mybatis1.user (id,name,pwd) values (#{id},#{name},#{pwd});
</insert>
<!--有了map就可以不用对应了,随便写-->
<insert id="addUserByMap" parameterType="map">
insert into mybatis1.user (id,name,pwd) values (#{userid},#{username},#{userpwd});
</insert>
<select id="getUserByMap" parameterType="map" resultType="user">
select * from mybatis1.user where name=#{mapname};
</select>
</mapper>test
package com.yj.dao;
import com.yj.pojo.User;
import com.yj.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class UserMapperTest {
@Test
public void testgetUserList(){
//获取sqlsession对象
SqlSession sqlSession = MyBatisUtils.getqlSession();
//执行sql, 方式一 getmapper
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = userMapper.getUserList();
for (User u : userList)
{
System.out.println(u);
}
//关闭sqlSession
sqlSession.close();
}
@Test
public void testUpdate()
{
SqlSession sqlSession = MyBatisUtils.getqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
userMapper.updateUser(new User(1,"w","n"));
sqlSession.commit();
sqlSession.close();
}
@Test
public void testgrtUserById()
{
SqlSession sqlSession = MyBatisUtils.getqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.getUserById(1);
System.out.println(user);
}
@Test
public void testaddUser()
{
SqlSession sqlSession = MyBatisUtils.getqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
userMapper.addUser(new User(4,"新增","测试"));
sqlSession.commit();
sqlSession.close();
}
@Test
public void testlikeUser(){
SqlSession sqlSession = MyBatisUtils.getqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> userlist = userMapper.likeUser("%李%");
for(User user : userlist)
{
System.out.println(user);
}
}
@Test
public void testaddUserByMap()
{
SqlSession sqlSession = MyBatisUtils.getqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//
//map是接口,不能用new出对象
//hashmap是继承map接口的实现类,可以new出对象
Map<String ,Object> map = new HashMap<String, Object>();
map.put("userid",10);
map.put("username","map666");
map.put("userpwd","map666");
userMapper.addUserByMap(map);
sqlSession.commit();
sqlSession.close();
}
@Test
public void testgetUserByMap()
{
SqlSession sqlSession = MyBatisUtils.getqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//
//map是接口,不能用new出对象
//hashmap是继承map接口的实现类,可以new出对象
Map<String ,Object> map = new HashMap<String, Object>();
map.put("mapname","map666");
User user = userMapper.getUserByMap(map);
System.out.println(user);
sqlSession.commit();
sqlSession.close();
}
}当多表时sql不是难点 ,难点是resultmap或resulttype不知道返回什么对吧,或者参数不知道写什么。
<select id="getStudent2" resultMap="student-teacher2">
select s.id sid,s.name sname,t.name tname
from student s,teacher t
where s.tid=t.id;
</select>
<!-- 查询写完了 用了一点别名,然后就是找里面的关系就完了-->
<resultMap id="student-teacher2" type="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<association property="teacher" javaType="Teacher">
<result property="name" column="tname"/>
</association>
</resultMap>使用Limit实现分页
#语法SELECT * FROM table LIMIT stratIndex,pageSizeSELECT * FROM table LIMIT 5,10; // 检索记录行 6-15 #为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为 -1: SELECT * FROM table LIMIT 95,-1; // 检索记录行 96-last. #如果只给定一个参数,它表示返回最大的记录行数目: SELECT * FROM table LIMIT 5; //检索前 5 个记录行 #换句话说,LIMIT n 等价于 LIMIT 0,n。
步骤:
1、修改Mapper文件
<select id="selectUser" parameterType="map" resultType="user"> select * from user limit #{startIndex},#{pageSize}</select>2、Mapper接口,参数为map
//选择全部用户实现分页List<User> selectUser(Map<String,Integer> map);
3、在测试类中传入参数测试
推断:起始位置 = (当前页面 - 1 ) * 页面大小
//分页查询 , 两个参数startIndex , pageSize@Testpublic void testSelectUser() { SqlSession session = MybatisUtils.getSession(); UserMapper mapper = session.getMapper(UserMapper.class); int currentPage = 1; //第几页 int pageSize = 2; //每页显示几个 Map<String,Integer> map = new HashMap<String,Integer>(); map.put("startIndex",(currentPage-1)*pageSize); map.put("pageSize",pageSize); List<User> users = mapper.selectUser(map); for (User user: users){ System.out.println(user); } session.close();}