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