2020年9月10日19:29:16
一、什么是Mybatis
1.1、什么是mybatis
Mybatis是一款优秀的持久层框架他支持定制化SQL、储存过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。Mybatis可以使用简单的XML或注解来配置和映射原生类型、接口和java的POJO(Plain Old java Objects,普通老式java对象)为数据库中的记录。Mybatis本是apache的一个开源项目iBtis,2010年这个项目由Apache software foundation前移到了google code,并且改名为MaBatis。2013年11月迁移到GItHub。
1.2、持久化
数据持久化:就是将程序的数据在持久状态和瞬时转化的过程。
持久状态;比如数据库(JDBC),IO文件持久化。
瞬时状态:比如内存,断电即失。
生活中冷藏也是一种持久化。
为什么需要持久化?
避免断电丢失内存太贵
1.3、持久层
Dao层、Service层、Controller层
王朝的那个持久化工作的代码块层界线明显
1.4、为什么需要MyBatis?
帮助程序员将数据库存入到数据库中。
增加开发效率
传统JDBC代码太复杂了,简化代码,(框架)自动化管理。
易上手,易使用。(技术没有高低之分)
sql与代码分离,提高了维护性。使程序设计清晰、易维护、易测试。将业务逻辑与数据访问逻辑分离。灵活提供xml标签,支持编写动态SQL。
重要的是:使用的人多!
二、第一次使用MyBatis程序
思路:搭建环境–>导入MyBatis–>编写代码–>测试!
2.1、搭建环境
2.1.1、搭建数据
CREATE TABLE `user` (
`id` int(20) NOT NULL AUTO_INCREMENT,
`name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`pws` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
INSERT INTO `user` VALUES (1, '悟空', '123');
INSERT INTO `user` VALUES (2, '八戒', '321');
INSERT INTO `user` VALUES (3, '沙僧', '000');
2.1.2、新建项目
新建一个maven项目
获取mybatis
<dependency>
<groupId>org.mybatis
</groupId>
<artifactId>mybatis
</artifactId>
<version>3.5.2
</version>
</dependency>
删除sre文件
在mop.xml文件中导入maven依赖
<dependencies>
<dependency>
<groupId>mysql
</groupId>
<artifactId>mysql-connector-java
</artifactId>
<version>8.0.16
</version>
</dependency>
<dependency>
<groupId>org.mybatis
</groupId>
<artifactId>mybatis
</artifactId>
<version>3.5.2
</version>
</dependency>
<dependency>
<groupId>junit
</groupId>
<artifactId>junit
</artifactId>
<version>4.12
</version>
<scope>test
</scope>
</dependency>
</dependencies>
<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>
</project>
2.2、创建.xml配置文件
创建module。
配置mybatis-config.xml文件
易忘点:
驱动使在mysql包下的jdbc包里。useUnicode=true(安全连接)useUnicode=true(Unicode编码可以正常输出,作用:可以使用中文)characterEncoding=UTF-8(解决了读取数据库产生的数据乱码的问题,从数据库读数据和写数据时MySQL的默认编码非UTF8编码,需要设置字符集编码为utf8 )
<?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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai"/>
<property name="username" value="root"/>
<property name="password" value="123"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/lyx/mapper/StuMapper.xml"/>
</mappers>
</configuration>
编写MyBatis工具类
package main
.java
.com
.lyx
.dao
;
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
= "org/mybatis/example/mybatis-config.xml";
InputStream inputStream
= Resources
.getResourceAsStream(resource
);
SqlSessionFactory sqlSessionFactory
= new SqlSessionFactoryBuilder().build(inputStream
);
} catch (IOException e
) {
e
.printStackTrace();
}
}
public static SqlSession
getSqlSession(){
return sqlSessionFactory
.openSession();
}
}
2.3、编写代码
实体类
package main
.java
.com
.lyx
.pojo
;
public class user {
private int id
;
private String naem
;
private String pws
;
public user() {
}
public user(int id
, String naem
, String pws
) {
this.id
= id
;
this.naem
= naem
;
this.pws
= pws
;
}
public int getId() {
return id
;
}
public String
getNaem() {
return naem
;
}
public String
getPws() {
return pws
;
}
public void setId(int id
) {
this.id
= id
;
}
public void setNaem(String naem
) {
this.naem
= naem
;
}
public void setPws(String pws
) {
this.pws
= pws
;
}
@Override
public String
toString() {
return "user{" +
"id=" + id
+
", naem='" + naem
+ '\'' +
", pws='" + pws
+ '\'' +
'}';
}
}
dao层mapper接口
public interface User_dao {
List
<Stu> getStu();
List
<Stu> getStuId(int id
);
int addStu(Stu stu
);
int updateStu(Stu stu
);
int deleteStu(int id
);
int addMap(Map
<String,Object> map
);
}
接口实现
(在mapper中)由原来的的UserDaoimp转变为一个mapper配置文件
<?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.lyx.dao.User_dao">
<select id="getUserList" resultType="com.lyx.pojo.User">
select * from mybatis.user
</select>
<select id="getStu" resultType="com.lyx.pojo.Stu">
select * from stu
</select>
<select id="getStuId" parameterType="int" resultType="com.lyx.pojo.Stu">
select * from Stu where id=#{id}
</select>
<insert id="addStu" parameterType="com.lyx.pojo.Stu" >
insert into mybatis.Stu (id,name,age) values (#{id},#{name},#{age})
</insert>
<update id="updateStu" parameterType="com.lyx.pojo.Stu">
update mybatis.stu set name=#{name},age=#{age} where id=#{id}
</update>
<delete id="deleteStu" parameterType="int">
delete from mybatis.stu where id=#{id}
</delete>
<insert id="addMap" parameterType="map" >
insert into mybatis.stu (id,name,age) values (#{a},#{b},#{c})
</insert>
</mapper>
注意点:增删改需要提交事务(sqlSession.commit();)
2.4、测试
注意点:
测试类最好写在与被测试类的路径类似
package com
.lyx
;
import com
.lyx
.mapper
.StuMapper
;
import com
.lyx
.pojo
.Stu
;
import com
.lyx
.util
.StuUtil
;
import org
.apache
.ibatis
.session
.SqlSession
;
import org
.junit
.Test
;
import java
.util
.List
;
public class StuTest {
@Test
public void test(){
SqlSession sqlSession
= StuUtil
.getSqlSession();
StuMapper mapper
= sqlSession
.getMapper(StuMapper
.class);
List
<Stu> stu
= mapper
.getStu();
System
.out
.println(stu
);
}
@Test
public void TestId(){
SqlSession sqlSession
= mybatisUtil
.getSqlSession();
StuMapper mapper
= sqlSession
.getMapper(StuMapper
.class);
List
<Stu> stuId
= mapper
.getStuId(1);
System
.out
.println(stuId
);
sqlSession
.close();
}
}
总结:失败的原因只有一个那就是懒性
三、拓展
1、万能的Map
接口
int addMap(Map
<String,Object> map
);
接口xml文件
<insert id="addMap" parameterType="map" >
insert into mybatis.stu (id,name,age) values (#{a},#{b},#{c})
</insert>
测试
@Test
public void addMap(){
SqlSession sqlSession
= mybatisUtil
.getSqlSession();
StuMapper mapper
= sqlSession
.getMapper(StuMapper
.class);
Map
<String, Object> map
= new HashMap<String, Object>();
map
.put("a",5);
map
.put("b","Map测试!");
map
.put("c",333333);
mapper
.addMap(map
);
sqlSession
.commit();
sqlSession
.close();
}
##2、模糊查询
List
<Stu> getStuN(String name
);
<select id
="getStuN" resultType
="com.lyx.pojo.Stu">
select
* from mybatis
.stu where name like
"%"#
{name
}"%"
</select
>
@Test
public void getStuN(){
SqlSession sqlSession
= mybatisUtil
.getSqlSession();
StuMapper mapper
= sqlSession
.getMapper(StuMapper
.class);
List
<Stu> stuN
= mapper
.getStuN("李");
System
.out
.print(stuN
);
sqlSession
.close();
}
四、配置优化
4.1、属性
在resources中新建.properties文件
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&&characterEncoding=UTF-8&&serverTimezone=Asia/Shanghai
username=root
password=123
在mybatis-config。xml文件中导入
<properties resource="db.properties"/>
<properties resource="org/mybatis/example/config.properties">
<property name="username" value="dev_user"/>
<property name="password" value="F2Fa3!33TYyg"/>
</properties>
注意点:
①.properties文件和.xml数据库连接的url部分中的&&的解读方式不一样,在.xml文件中& ,在.properties文件应该被写成&&
②在xml文件中所有的标签都有其对应的位置。
③方式二优先执行外部映入文件中的内容。
4.2、别名
类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。
实体类别名 (mybatis的mapper层是是不能起别名的)
<typeAliases >
<typeAlias type="lyx.pojo.Stu" alias="Stu"/>
</typeAliases>
<select id="getStu" resultType="Stu">
select * from stu
</select>
包别名:指定一个包名,MyBatis 会在包名下面搜索需要的
<typeAliases>
<package name="com.lyx.mapper"/>
</typeAliases>
注意点:
在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名 。
接口不可以使用第一种方法。(namespace属性:在MyBatis中,Mapper中的namespace用于绑定Dao接口的,即面向接口编程。
它的好处在于当使用了namespace之后就可以不用写接口实现类,业务逻辑会直接通过这个绑定寻找到相对应的SQL语句进行对应的数据处理,不可以定义别名)
**两者区别:**第一种可以自定义别名,第二种不行(如果个别需要自定义可以使用注解起别名自定义别名),如果实体类多,建议使用第二种,反之第一种。
注解别名:在实体类中采用注解方式,起别名
import org
.apache
.ibatis
.type
.Alias
;
@Alias("zjbm")
public class Stu {}
注意:是导入org.apache.ibatis.type中的Alias
4.3、设置
https://mybatis.org/mybatis-3/zh/configuration.html#properties
4.4、映射器
作用:告诉 MyBatis 去哪里找映射文件 (寻找sql)
方式一:使用相对于类路径的资源引用
<mappers>
<mapper resource="com/lyx/mapper/StuMapper.xml"/>
</mappers>
方式二:使用映射器接口实现类的完全限定类名
<mamppers>
<mapper class="com.lyx.mapper.StuMapper"/>
</mamppers>
方式三:将包内的映射器接口实现全部注册为映射器
<mappers>
<package name="com.lyx.mapper"/>
</mappers>
后两者注意:实体类与映射文件必须在统一包内并且命名一致。
五、日志
5.1、日志工厂
如果一个数据库操作出现异常,日志是最好的排查错误的助手。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EdQVQ9zk-1604538561160)(E:\桌面\Markdown笔记\1604132888073.png)]
有效值:SLF4J、LOG4J 、 LOG4J2 、 JDK_LOGGING 、 COMMONS_LOGGING 、 STDOUT_LOGGING 、 NO_LOGGING (不同的有效值,实现方式不同,输出不同)
loglmpl没有默认值
在mybatis中具体使用哪种日志实现,在设置中指定。
STDOUT_LOGGING标准日志输出
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
5.2、LOG4J的使用
5.21、什么是LOG4J?
控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog、守护进程等控制每一条日志的输出格式定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过还可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。
5.22、基本使用
导入log4j的包
<dependency>
<groupId>log4j
</groupId>
<artifactId>log4j
</artifactId>
<version>1.2.17
</version>
</dependency>
创建log4j的.properties文件
#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和fiLe的定义在下面的代码
log4j.rootLogger=DEBUG,console,file
#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n
#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/log4j.txt
log4j.appender.file.MaxFilesize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n
#口志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.dql=DEBUG
log4j.logger.java.sq1.statement=DEBUG
log4j.logger.java.sq1.ResultSet=DEBUG
log4j.logger.java.sq1.PreparedStatement=DEBUG
配置log4j日志实现
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
5.23、Log4j简单使用
在要使用Log4j的类中,导入包:import org.apache.log4j.Logger;
创建日志对象,参数为当前类名
static Logger logger
= Logger
.getLogger(BookTypeMapperTest
.class);
日志级别
级别不同,输出的标签不同,方便筛选
logger
.info("info,进入了log4j");
logger
.debug("debug,进入了log4j");
logger
.error("error,进入了log4j");
日志文件记录内容:
[INFO][20-11-04][com.lyx.test.BookMapperTest]info进入!
[DEBUG][20-11-04][com.lyx.test.BookMapperTest]debug进入
[ERROR][20-11-04][com.lyx.test.BookMapperTest]error进入!
六、分页查询
分页的作用:减少数据处理量
6.2、使用Limit分页查询
语法:
select * from Emp limit staIndex,pageSize;
Limit两个属性:
staIndex:起止位置pageSize:查询数据的条数如果只传入一个属性,默认起始位置为0