Mybatis详解--实战上手看这篇就够了

比眉伴天荒 2022-12-26 13:29 254阅读 0赞

专注于IT技术知识梳理,书写前沿技术文章!更多技术在这里慢慢探索吧,请关注杰哥 公众号!

!\[在这里插入图片描述\](https://img-blog.csdnimg.cn/2020111620380146.png\#pic\_center

  如文章对你有帮助,    “ 评论”和 转发+关注(一键三连)是对我最大的支持!







Mybatis简介

简介

  MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
在这里插入图片描述

本文讲使用Idea集成开发环境利用Maven构建Mybatis项目,Idea可以下载Mybatis plugin,然后可更好的使用mybatis。

Mybatis整体架构:
在这里插入图片描述







Mybatis入门

Mybatis环境搭建及Demo

1.使用IDEA创建maven工程
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2.在pom.xml添加依赖
  添加依赖包:mybatis包、数据库驱动包(我使用的是mysql)、日志包(我使用的是log4j)

  1. <dependencies>
  2. <!-- 添加junit -->
  3. <dependency>
  4. <groupId>junit</groupId>
  5. <artifactId>junit</artifactId>
  6. <version>4.11</version>
  7. <scope>test</scope>
  8. </dependency>
  9. <!-- 添加log4j -->
  10. <dependency>
  11. <groupId>log4j</groupId>
  12. <artifactId>log4j</artifactId>
  13. <version>1.2.16</version>
  14. </dependency>
  15. <!-- 添加mybatis -->
  16. <dependency>
  17. <groupId>org.mybatis</groupId>
  18. <artifactId>mybatis</artifactId>
  19. <version>3.2.6</version>
  20. </dependency>
  21. <!-- 添加mysql驱动 -->
  22. <dependency>
  23. <groupId>mysql</groupId>
  24. <artifactId>mysql-connector-java</artifactId>
  25. <version>5.1.12</version>
  26. </dependency>
  27. </dependencies>

3.准备数据
在这里插入图片描述
4.User实体类

  1. public class User {
  2. int id;
  3. String name;
  4. String password;
  5. /*省略get/set*/
  6. }

5.与实体类相对应的实体类映射文件(UserMapper.xml)

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <!-- mapper:根标签,namespace:命名空间,随便写,一般保证命名空间唯一 -->
  6. <mapper namespace="MyMapper">
  7. <!-- statement,内容:sql语句。id:唯一标识,随便写,在同一个命名空间下保持唯一
  8. resultType:sql语句查询结果集的封装类型,user即为数据库中的表
  9. -->
  10. <select id="selectUser" parameterType="int" resultType="com.beixi.entity.User">
  11. select * from user where id = #{
  12. id}
  13. </select>
  14. </mapper>

6.全局配置文件(mybatis-config.xml)

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE configuration
  3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-config.dtd">
  5. <!-- 根标签 -->
  6. <configuration>
  7. <!-- 环境,可以配置多个,default:指定采用哪个环境 -->
  8. <environments default="test">
  9. <!-- id:唯一标识 -->
  10. <environment id="test">
  11. <!-- 事务管理器,JDBC类型的事务管理器 -->
  12. <transactionManager type="JDBC" />
  13. <!-- 数据源,池类型的数据源 -->
  14. <dataSource type="POOLED">
  15. <property name="driver" value="com.mysql.jdbc.Driver" />
  16. <property name="url" value="jdbc:mysql://127.0.0.1:3306/test?characterEncoding=UTF-8" />
  17. <property name="username" value="root" />
  18. <property name="password" value="root" />
  19. </dataSource>
  20. </environment>
  21. </environments>
  22. <mappers>
  23. <mapper resource="mappers/UserMapper.xml" />
  24. </mappers>
  25. </configuration>

7.测试类

  1. public class UserTest {
  2. public static void main(String[] args) throws Exception {
  3. // 指定全局配置文件
  4. String resource = "mybatis-config.xml";
  5. // 读取配置文件
  6. InputStream inputStream = Resources.getResourceAsStream(resource);
  7. // 构建sqlSessionFactory
  8. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  9. // 获取sqlSession
  10. SqlSession sqlSession = sqlSessionFactory.openSession();
  11. try {
  12. // 操作CRUD,第一个参数:指定statement,规则:命名空间+“.”+statementId
  13. // 第二个参数:指定传入sql的参数:这里是用户id
  14. User user = sqlSession.selectOne("MyMapper.selectUser", 1);
  15. System.out.println(user);
  16. } finally {
  17. sqlSession.close();
  18. }
  19. }
  20. }

8.目录结构
在这里插入图片描述
9.添加日志分析log4j.properties

  1. log4j.rootLogger=DEBUG,A1
  2. log4j.logger.org.apache=DEBUG
  3. log4j.appender.A1=org.apache.log4j.ConsoleAppender
  4. log4j.appender.A1.layout=org.apache.log4j.PatternLayout
  5. log4j.appender.A1.layout.ConversionPattern=%-d{
  6. yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c]-[%p] %m%n

再次运行程序会打印日志:
在这里插入图片描述







完整的CRUD操作

完整的CRUD操作

1.创建UserDao持久层

  1. public class UserDao {
  2. /*持久化对象*/
  3. public SqlSession sqlSession;
  4. public UserDao(SqlSession sqlSession) {
  5. this.sqlSession = sqlSession;
  6. }
  7. /*根据id查询用户信息*/
  8. public User queryUserById(String id) {
  9. return this.sqlSession.selectOne("UserDao.queryUserById", id);
  10. }
  11. /*查询所有用户信息*/
  12. public List<User> queryUserAll() {
  13. return this.sqlSession.selectList("UserDao.queryUserAll");
  14. }
  15. /*新增*/
  16. public void insertUser(User user) {
  17. this.sqlSession.insert("UserDao.insertUser", user);
  18. }
  19. /*更新*/
  20. public void updateUser(User user) {
  21. this.sqlSession.update("UserDao.updateUser", user);
  22. }
  23. /*删除*/
  24. public void deleteUser(int id) {
  25. this.sqlSession.delete("UserDao.deleteUser", id);
  26. }
  27. }

2.修改UserMapper.xml

  1. <mapper namespace="UserDao">
  2. <!-- statement,内容:sql语句。id:唯一标识,随便写,在同一个命名空间下保持唯一
  3. resultType:sql语句查询结果集的封装类型,user即为数据库中的表
  4. -->
  5. <!--<select id="queryUserById" resultType="com.beixi.entity.User">-->
  6. <!--select * from user where id = #{
  7. id}-->
  8. <!--</select>-->
  9. <!--使用别名-->
  10. <select id="queryUserById" parameterType="int" resultType="com.beixi.entity.User">
  11. select * from user where id = #{
  12. id};
  13. </select>
  14. <select id="queryUserAll" resultType="com.beixi.entity.User">
  15. select * from user;
  16. </select>
  17. <!--插入数据-->
  18. <insert id="insertUser" parameterType="com.beixi.entity.User">
  19. INSERT INTO user (
  20. name,
  21. password
  22. )
  23. VALUES
  24. (
  25. #{
  26. name},
  27. #{
  28. password}
  29. );
  30. </insert>
  31. <update id="updateUser" parameterType="com.beixi.entity.User">
  32. UPDATE user
  33. <trim prefix="set" suffixOverrides=",">
  34. <if test="name!=null">name = #{
  35. name},</if>
  36. <if test="password!=null">password = #{
  37. password},</if>
  38. </trim>
  39. WHERE
  40. (id = #{
  41. id});
  42. </update>
  43. <delete id="deleteUser">
  44. delete from user where id=#{
  45. id}
  46. </delete>
  47. </mapper>

3.编写UserDao的测试用例

  1. public class UserDaoTest {
  2. public UserDao userDao;
  3. public SqlSession sqlSession;
  4. @Before
  5. public void setUp() throws Exception {
  6. // mybatis-config.xml
  7. String resource = "mybatis-config.xml";
  8. // 读取配置文件
  9. InputStream is = Resources.getResourceAsStream(resource);
  10. // 构建SqlSessionFactory
  11. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
  12. // 获取sqlSession
  13. sqlSession = sqlSessionFactory.openSession();
  14. this.userDao = new UserDao(sqlSession);
  15. }
  16. @Test
  17. public void queryUserById() throws Exception {
  18. System.out.println(this.userDao.queryUserById(1));
  19. }
  20. @Test
  21. public void queryUserAll() throws Exception {
  22. List<User> userList = this.userDao.queryUserAll();
  23. for (User user : userList) {
  24. System.out.println(user);
  25. }
  26. }
  27. @Test
  28. public void insertUser() throws Exception {
  29. User user = new User();
  30. user.setName("贝西奇谈");
  31. user.setPassword("123456");
  32. this.userDao.insertUser(user);
  33. this.sqlSession.commit();//提交事务
  34. }
  35. @Test
  36. public void updateUser() throws Exception {
  37. User user = new User();
  38. user.setName("杰哥");
  39. user.setPassword("654321");
  40. user.setId(89);
  41. this.userDao.updateUser(user);
  42. this.sqlSession.commit();
  43. }
  44. @Test
  45. public void deleteUser() throws Exception {
  46. this.userDao.deleteUser(89);
  47. this.sqlSession.commit();
  48. }
  49. }

模糊查询

  1. <select id="selectLike" parameterType="string" resultType="User">
  2. select * from user where name like concat("%",#{
  3. name},"%")
  4. </select>
  5. /*模糊查询*/
  6. @Test
  7. public void selectLike(){
  8. List<User> list = sqlSession.selectList("selectLike","zhang");
  9. for (int i = 0; i < list.size(); i++) {
  10. User user = list.get(i);
  11. System.out.println(user);
  12. }
  13. }






解决数据库字段名和实体类属性名不一致的问题

解决数据库字段名和实体类属性名不一致的问题

原因:数据库的字段名是name,POJO中的属性名字是userName
两端不一致,造成mybatis无法填充对应的字段信息。修改方法:resultMap。
在这里插入图片描述







typeAliases

typeAliases

类型别名是为 Java 类型命名的一个短的名字。它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余。

  1. <typeAliases>
  2. <typeAlias type="com.beixi.entity.User" alias="User"/>
  3. </typeAliases>

缺点:每个pojo类都要去配置。
解决方案:使用扫描包,扫描指定包下的所有类,扫描之后的别名就是类名(不区分大小写),建议使用的时候和类名一致。

  1. <typeAliases>
  2. <!--type:实体类的全路径。alias:别名,通常首字母大写-->
  3. <!--<typeAlias type="com.beixi.entity.User" alias="User"/>-->
  4. <package name="com.beixi.entity.User"/>
  5. </typeAliases>

Mybatis已经为普通的 Java 类型内建了许多相应的类型别名。它们都是大小写不敏感的.
在这里插入图片描述










回到顶部
高级查询

多对一的关联映射

(1)数据
在这里插入图片描述
(2)映射文件
多方出发:

  1. <resultMap type="Emp" id="empMap">
  2. <id column="id" property="id" />
  3. <result column="ename" property="name"/>
  4. <result column="eage" property="age"/>
  5. <result column="esex" property="sex"/>
  6. <!-- 关联一的一端 -->
  7. <association property="dept" column="deptno" javaType="Dept" >
  8. <id column="dno" property="dno"/>
  9. <result column="dname" property="name"/>
  10. </association>
  11. </resultMap>
  12. <select id="selectEmpOne" parameterType="int" resultMap="empMap">
  13. select * from emp e,dept d where e.deptno=d.dno and e.id = #{
  14. id}
  15. </select>
  16. 测试:
  17. /*查询单条*/
  18. @Test
  19. public void selectEmpOne(){
  20. //第一个参数是调用的sql 第二个是传入的参数
  21. Emp emp =(Emp) sqlSession.selectOne("selectEmpOne", 7);
  22. System.out.println(emp);
  23. }

一的一方出发:

  1. <!-- 一对多方向 -->
  2. <resultMap type="Dept" id="deptMap">
  3. <id column="dno" property="dno"/>
  4. <result column="dname" property="name"/>
  5. <!-- 配置多的一方 -->
  6. <collection property="emps" column="deptno" javaType="Emp">
  7. <id column="id" property="id" />
  8. <result column="ename" property="name"/>
  9. <result column="eage" property="age"/>
  10. <result column="esex" property="sex"/>
  11. </collection>
  12. </resultMap>
  13. <select id="selectEmpByDeptOne" parameterType="int" resultMap="deptMap">
  14. select * from emp e,dept d where e.deptno=d.dno and d.dno = #{
  15. dno}
  16. </select>
  17. @Test
  18. public void selectEmpByDeptOne(){
  19. //第一个参数是调用的sql 第二个是传入的参数
  20. Dept dept =(Dept) sqlSession.selectOne("selectEmpByDeptOne", 10);
  21. System.out.println(dept);
  22. Set<Emp> emps = dept.getEmps();
  23. for(Emp emp:emps){
  24. System.out.println(emp);
  25. }
  26. }

专注于IT技术知识梳理,书写前沿技术文章!更多技术在这里慢慢探索吧,请关注杰哥 公众号!

!\[在这里插入图片描述\](https://img-blog.csdnimg.cn/2020111620380146.png\#pic\_center

  如文章对你有帮助,    “ 评论”和 转发+关注(一键三连)是对我最大的支持!

发表评论

表情:
评论列表 (有 0 条评论,254人围观)

还没有评论,来说两句吧...

相关阅读