2021第三周mybatis框架总结

java-SSM框架之mybatis框架总结

一.项目

1.数据库准备

CREATE table blog(
	id VARCHAR(50) not NULL COMMENT '博客id',
	title VARCHAR(199) not null COMMENT '博客标题',
	author varchar(30) not null COMMENT '博客作者',
	createTime datetime not NULL COMMENT '创建时间',
	views int(30) not null COMMENT '浏览量'
) ENGINE=INNODB DEFAULT CHARSET=utf8

SHOW tables;

SELECT * from blog;

use mybatis;

CREATE table teacher(
	id int(10) not NULL,
	`name` varchar(30) DEFAULT NULL,
	PRIMARY key(id)
)ENGINE=INNODB DEFAULT charset=utf8;

insert into teacher(id,name) values(1,'秦老师');

CREATE table student(
	id int(10) not NULL,
	`name` VARCHAR(30) DEFAULT NULL,
	tid int(10) DEFAULT NULL,
	PRIMARY key(id),
	KEY fktid (tid),
	CONSTRAINT fktid FOREIGN key(tid) REFERENCES teacher (id)
)ENGINE=INNODB DEFAULT charset=utf8;

insert into student(id,name,tid) values
(1,'小明',1),
(2,'小王',1),
(3,'小李',1),
(4,'小廖',1),
(5,'小周',1)

2.idea环境搭建

在这里插入图片描述

父模块下prom.xml导入jar包,通过继承后面创建的子项目都拥有这些jar包

工程目录

在这里插入图片描述

父porm.xml和子porm.xml要点示例

//父porm.xml有子模块的架构
<modules>
    <module>mybatis-01</module>
    <module>mybatis-03</module>
    <module>mybatis-04</module>
    <module>mybatis-1more</module>
    <module>mybatis-project</module>
</modules>
//子porm.xml有父模块的标记
<parent>
    <artifactId>Mybatis-Study</artifactId>
    <groupId>org.example</groupId>
    <version>1.0-SNAPSHOT</version>
</parent>
//解决资源文件无法被导出到target
<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>
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>
//读取数据库属性配置文件db.properties
    <properties resource="db.properties"/>
//设置日志和数据表字段与实体类的驼峰和下划线互转的配置
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
        <setting name="mapUnderscoreToCamelCase" value="true" />
    </settings>
//属性配置之别名优化 不能给mapper(dao层)起别名 (针对resultType)
    <typeAliases>
    	<typeAlias type="com.huang.pojo.User" alias="user"/>
        <package name="com.huang.pojo"/>   //默认user即可指代改实体类
    </typeAliases>
//配置运行的环境
    <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>
//Mapper接口对应的xml文件必须要在此处注册,有三种写法
//我们通常使用class,但前提是Mapper接口和对应的xml文件在一个包下,且名字一样
//如果使用resource,则是用/分割的xml文件
    <mappers>
        <mapper class="com.huang.dao.StudentMapper"/>
        <mapper class="com.huang.dao.TeacherMapper"/>
        <mapper resource="com/huang/dao/TeacherMapper.xml"/>
    </mappers>
</configuration>
MybatisUtils工具类获取sqlSession对象
package com.huang.utils;

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 {
    public static SqlSessionFactory sqlSessionFactory;
    static {
        try {
            InputStream inputStream = Resources.getResourceAsStream("mybatis.config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //此处设置布尔值true,增删改就无需sqlSession.commit()提交事务了
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession(true);
    }
}
数据库属性配置文件db.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/${需要连接的数据库名如:mybatis}?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8
username=${数据库用户名}
password=${数据库密码}
Mapper接口示例
package com.huang.dao;
import com.huang.pojo.Student;
import java.util.List;

public interface StudentMapper {
//    多对一(学生对老师)的处理---按照查询嵌套处理
    List<Student> getStudent();
//    多对一(学生对老师)的处理---按照结果嵌套处理
    List<Student> getStudent2();
}

Mapper接口对应的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为相对路径下的Mapper接口
<mapper namespace="com.huang.dao.StudentMapper">
    //此处编写sql语句,示例
    <select id="getStudent" resultMap="StudentTeacher">
        select * from mybatis.student;
    </select>
</mapper>
补充lombok插件的配置

1.安装lombok插件
2.在子porm.xml中配置依赖

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.10</version>
    </dependency>
</dependencies>

3.使用注解@Data即可,见实体类使用

完成了以上环境搭建,我们可以开始测试了

1.测试目录

在这里插入图片描述

2.测试类示例

//    测试环境搭建成功
@Test
public void test1(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
    List<Teacher> teacherList = mapper.getTeacher();
    for (Teacher teacher : teacherList) {
        System.out.println(teacher);
    }
    sqlSession.close();
}

3.多对一的处理

实体类pojo

package com.huang.pojo;
import lombok.Data;
@Data
public class Teacher {
    private int id;
    private String name;
}
package com.huang.pojo;
import lombok.Data;
@Data
public class Student {
    private int id;
    private String name;
//    外键关联的老师对象
    private Teacher teacher;
}

1.按照查询嵌套处理

<select id="getStudent" resultMap="StudentTeacher">
    select * from mybatis.student;
</select>
<resultMap id="StudentTeacher" type="Student">
    <result property="id" column="id"/>
    <result property="name" column="name"/>
    //注意一下固定写法
    <association property="teacher" column="tid" javaType="teacher" select="getSTeacher"/>
</resultMap>
// #{tid}中tid可以为任何内容
<select id="getSTeacher" resultType="Teacher">
    select * from mybatis.teacher where id = #{tid};
</select>

2.按照结果嵌套处理

<select id="getStudent2" resultMap="Student2Teacher2">
    select s.id sid,s.name sname,t.name tname from mybatis.student s,mybatis.teacher t where s.tid = t.id;
</select>
<resultMap id="Student2Teacher2" type="student">
    <result property="id" column="sid"/>
    <result property="name" column="sname"/>
    <association property="teacher" javaType="teacher">
        <result property="name" column="tname"/>
    </association>
</resultMap>

4.多对一的处理(以下对应的mapper和xml文件没有给出)

实体类pojo

package com.huang.pojo;
import lombok.Data;
@Data
public class Teacher {
    private int id;
    private String name;
    private List<Student> students;
}
package com.huang.pojo;
import lombok.Data;
@Data
public class Student {
    private int id;
    private String name;
    private int tid;
}

1.按照查询嵌套处理

<select id="getTeacher2" resultMap="TeacherStudent2">
    select * from mybatis.teacher where id = #{id};
</select>
<resultMap id="TeacherStudent2" type="Teacher"
    <collection property="students" column="id" javaType="ArrayList" ofType="Student" select="getStudentByTeacherId"/>
</resultMap>
// #{id}中id可以为任何内容
<select id="getStudentByTeacherId" resultType="Student">
    select * from mybatis.student where tid = #{id};
</select>

2.按照结果嵌套处理

<select id="getTeacher" resultMap="TeacherStudent">
   select s.id sid,s.name sname,t.name tname,t.id tid
   from student s,teacher t
   where s.tid = t.id and t.id = #{id};
</select>
<resultMap id="TeacherStudent" type="Teacher">
    <result property="id" column="tid"/>
    <result property="name" column="tname"/>
    <collection property="students" ofType="Student">
        <result property="id" column="sid"/>
        <result property="name" column="sname"/>
        <result property="tid" column="tid"/>
    </collection >
</resultMap>

优先考虑使用按照结果嵌套处理的方法

5.动态sql

1.if语句
<select id="getStudent" resultType="student"> 
    SELECT * FROM mybatis.student
<if test="name!=null">
    AND name = #{name}
</if>   
</select>
2.where标签
<select id="getStudent" resultType="student" parameterType="map">
    SELECT * from mybatis.student
    //where会自动添加或者删除and,choose和when满足一个就不会继续往后,
    //类似switch,case/break
<where>
    <choose>
        <when test="name!= null">
        	AND name = #{name}
        </when>
        <when test="tid != null">
        	AND tid =#{tid }
        </when>
        <otherwise>
        	AND  id= "2"
        </otherwise>
    </choose>
</where>
</select>
3.set标签
<update id="updateEmprById2" parameterType="emp">
    UPDATE mybatis.student
    //set会自动添加或者删除,保证sql语句的合法性
    <set>
        <if test="name!=null"> name=#{name},</if>
        <if test="tid!=null"> tid=#{tid},</if>
    </set>
    where id = #{id}
</update>

6.补充一些点

一.mybatis实现分页方式1

//1.接口
List<User> getUserListByLimit(Map<String,Integer> map);

//2.mapper.xml配置
//配合使用结果集映射,解决字段名不一致的问题
<resultMap id="UserMap" type="user">
    <result property="password" column="pwd"/>
</resultMap>
<select id="getUserListByLimit" resultMap="UserMap">
    select * from mybatis.user limit #{startIndex},#{pageSize};
</select>

//3.测试类
@Test
public void testLimit(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserDao userdao = sqlSession.getMapper(UserDao.class);
    Logger logger = Logger.getLogger(UserDaoTest.class);
    logger.info("info:用分页来查询数据");
    HashMap<String, Integer> map = new HashMap<>();
    map.put("startIndex",0);
    map.put("pageSize",2);
    List<User> userList = userdao.getUserListByLimit(map);
    for (User user : userList) {
        System.out.println(user);
    }
    sqlSession.close();
}
二.mybatis实现分页方式2
//1.接口
List<User> getUserListByRowBounds();

//2.mapper.xml配置
//配合使用结果集映射
<resultMap id="UserMap" type="user">
    <result property="password" column="pwd"/>
</resultMap>
<select id="getUserListByRowBounds" resultMap="UserMap">
//此处要查询全部
    select * from mybatis.user;
</select>

//3.测试类
@Test
public void testRowBounds(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();

//        RowBounds实现
    RowBounds rowBounds = new RowBounds(0, 1);
    logger.info("info:使用RowBounds来进行分页");
//        Java代码层面实现分页 这里是sqlSession执行sql语言的第二种方式,(不推荐)
    List<User> userList = sqlSession.selectList("com.huang.dao.UserDao.getUserListByRowBounds", null, rowBounds);
    for (User user : userList) {
        System.out.println(user);
    }
    sqlSession.close();
} 
三.模糊查询
//Mapper接口
List<User> getUserListByNameLike(String name);
//模糊查询
<select id="getUserListByNameLike" resultType="user">
    select * from mybatis.user where name like concat("%",#{name},"%");
</select>
//测试类
@Test
public void testLike(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserDao userDao = sqlSession.getMapper(UserDao.class);
    //测试模糊查询
    //方式一:List<User> userList = userDao.getUserListByNameLike("%王%");
    List<User> userList = userDao.getUserListByNameLike("王");
    for (User user : userList) {
        System.out.println(user);
    }
    sqlSession.close();
}
四.map参数
//Mapper接口
List<User> getUserListById2(Map<String,Object> map);
//使用map可以自定义参数名
<select id="getUserListById2" resultType="user" parameterType="map">
    select * from mybatis.user where id = #{selfDefinedField};
</select>
//测试类
@Test
public void test0(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserDao userDao = sqlSession.getMapper(UserDao.class);
    HashMap<String, Object> map = new HashMap<String, Object>();
    map.put("selfDefinedField",5);
    List<User> userList = userDao.getUserListById2(map);
    for (User user : userList) {
        System.out.println(user);
    }
    sqlSession.close();
}
五.注解
//增加一个用户 注解适用于简单的业务逻辑
@Insert("insert into user(id,name,pwd) values(#{id},#{name},#{password})")
int insertUser(User user);
六.Log4j日志
1.导入jar包
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
2.在resource下新建log4j.properties配置文件
# priority  :debug<info<warn<error
#you cannot specify every priority with different file for log4j
log4j.rootLogger=debug,stdout,info,debug,warn,error 

#console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender 
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 
log4j.appender.stdout.layout.ConversionPattern= [%d{yyyy-MM-dd HH:mm:ss a}]:%p %l%m%n
#info log
log4j.logger.info=info
log4j.appender.info=org.apache.log4j.DailyRollingFileAppender 
log4j.appender.info.DatePattern='_'yyyy-MM-dd'.log'
log4j.appender.info.File=./src/log/info.log
log4j.appender.info.Append=true
log4j.appender.info.Threshold=INFO
log4j.appender.info.layout=org.apache.log4j.PatternLayout 
log4j.appender.info.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss a} [Thread: %t][ Class:%c >> Method: %l ]%n%p:%m%n
#debug log
log4j.logger.debug=debug
log4j.appender.debug=org.apache.log4j.DailyRollingFileAppender 
log4j.appender.debug.DatePattern='_'yyyy-MM-dd'.log'
log4j.appender.debug.File=./src/log/debug.log
log4j.appender.debug.Append=true
log4j.appender.debug.Threshold=DEBUG
log4j.appender.debug.layout=org.apache.log4j.PatternLayout 
log4j.appender.debug.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss a} [Thread: %t][ Class:%c >> Method: %l ]%n%p:%m%n
#warn log
log4j.logger.warn=warn
log4j.appender.warn=org.apache.log4j.DailyRollingFileAppender 
log4j.appender.warn.DatePattern='_'yyyy-MM-dd'.log'
log4j.appender.warn.File=./src/log/warn.log
log4j.appender.warn.Append=true
log4j.appender.warn.Threshold=WARN
log4j.appender.warn.layout=org.apache.log4j.PatternLayout 
log4j.appender.warn.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss a} [Thread: %t][ Class:%c >> Method: %l ]%n%p:%m%n
#error
log4j.logger.error=error
log4j.appender.error = org.apache.log4j.DailyRollingFileAppender
log4j.appender.error.DatePattern='_'yyyy-MM-dd'.log'
log4j.appender.error.File = ./src/log/error.log 
log4j.appender.error.Append = true
log4j.appender.error.Threshold = ERROR 
log4j.appender.error.layout = org.apache.log4j.PatternLayout
log4j.appender.error.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss a} [Thread: %t][ Class:%c >> Method: %l ]%n%p:%m%n
3.在mybatis.config.xml核心配置文件中配置
<settings>
    <setting name="logImpl" value="LOG4J"/>
    //解决驼峰转数据库中的_
    <setting name="mapUnderscoreToCamelCase" value="true"/> 
</settings>
4.在测试类中测试
static Logger logger = Logger.getLogger(类对象【Student.class)
logger.info("info:进入了信息输出");
logger.debug("debug:进入了debug阶段");
logger.error("error:进入了error阶段");


@Test
public void test1(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserDao userdao = sqlSession.getMapper(UserDao.class);
    List<User> userlist = userdao.getUserListById(1);
    logger.info("info:进入了信息输出");
    for (User user : userlist) {
        System.out.println(user);
    }
    sqlSession.close();
}

@Test
public void test2(){
    logger.info("info:进入了信息输出");
}
5.最后会在log4j.properties指定的位置生成日志文件

在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值