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>
//屬性配置之別名優化
    <typeAliases>
        <package name="com.com.huang.pojo"/>
    </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文件在一個包下,且名字一樣
    <mappers>
        <mapper class="com.com.huang.dao.StudentMapper"/>
        <mapper class="com.com.huang.dao.TeacherMapper"/>
    </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 * 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指定的位置生成日誌文件

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章