mybatis
1、第一个mybatis程序
1.1、搭建环境
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
1.2、创建一个模块
创建配置文件(在resource文件下添加mybatis-config.xml,db.properties文件)
- db.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT%2B8&userSSL=true&userUnicode=true&characterEncoding=UTF-8
username=root
password=root
- mybatis-config.xml
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--核心配置文件-->
<configuration>
<!-- 引入外部配置文件-->
<properties resource="db.properties"/>
<!--设置日志-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--设置别名-->
<typeAliases>
<package name="com.kuang.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>
<mappers>
<mapper resource="com/kuang/dao/UserMapper.xml"/>
</mappers>
</configuration>
xml中URL需要转义
jdbc:mysql://localhost:3306/mybatis?erverTimezone=GMT%2B8&userSSL=true&
userUnicode=true&characterEncoding=UTF-8
编写mybatis工具类(由SqlSessionFactory获取SqlSession实例)
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static{
try {
//获取SqlSessionFactory对象
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
//由SqlSessionFactory获取SqlSession实例
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
1.3、编写代码
-
实体类
package com.kuang.pojo; public class User { private int id; private String name; private String pwd; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } public User() { } public User(int id, String name, String pwd) { this.id = id; this.name = name; this.pwd = pwd; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", pwd='" + pwd + '\'' + '}'; } }
-
Dao接口
public interface UserDao { List<User> getUserList(); }
-
接口实现类
<?xml version="1.0" encoding="UTF8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--namespace=绑定一个对应的Dao/Mapper接口--> <mapper namespace="com.kuang.dao.UserDao"> <select id="getUserList" resultType="com.kuang.pojo.User"> select * from mybatis.user </select> </mapper>
1.4、测试
资源过滤问题解决
<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>
数据库连接失败
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT%2B8&userSSL=true&
UTF-8问题
将xml文件UTF-8改为UTF8
2、CRUD
增删改注意提交事务
2.1、namespace
namespace中的包名要和Dao/Mapper接口的包名一致!
2.2、select
- id:就是对应的namespace中的方法名;
- resultType:Sql语句执行的返回值;
- parameterType:参数类型
-
编写接口
List<User> getUserList();
-
编写对应的mapper中的sql语句
<select id="getUserList" resultType="com.kuang.pojo.User"> select * from mybatis.user</select>
-
测试
@Test public void test(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); UserDao userDao = sqlSession.getMapper(UserDao.class); List<User> userList = userDao.getUserList(); for (User user : userList) { System.out.println(user); }// 关闭sqlSession sqlSession.close(); }
2.3、Insert
<insert id="addUser" parameterType="com.kuang.pojo.User"> insert into mybatis.user (id,name,pwd) value (#{id},#{name},#{pwd});</insert>
2.4、update
<update id="updateUser" parameterType="com.kuang.pojo.User"> update mybatis.user set name = #{name},pwd=#{pwd} where id=#{id};</update>
2.5、delete
<delete id="deleteUser" parameterType="int"> delete from mybatis.user where id =#{id};</delete>
2.6、万能的Map
假设,我们的实体类,或者数据库中的表,字段或者参数过多,应当考虑使用Map!
int addUser2(Map<String,Object> map);
<insert id="addUser2" parameterType="com.kuang.pojo.User"> insert into mybatis.user (id,name,pwd) value (#{userid},#{username},#{password});</insert>
@Testpublic void addUser2(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); UserDao mapper = sqlSession.getMapper(UserDao.class); Map<String, Object> map = new HashMap<>(); map.put("userid",7); map.put("username","xiaohua"); map.put("password","15544"); mapper.addUser2(map); sqlSession.commit(); sqlSession.close();}
2.7、模糊查询
-
Java代码执行的时候,传递通配符% %
List<User> userList = mapper.getUserLike("%李%")
-
在sql拼接中使用通配符
select * from mybatis.user where name like "%"#{value}"%"
3、配置解析
- MyBatis 的配置文件(mybatis-config.xml)包含了会深深影响 MyBatis 行为的设置和属性信息。
- configuration(配置) - [properties(属性)] - [settings(设置)] - [typeAliases(类型别名)] - [typeHandlers(类型处理器)] - [objectFactory(对象工厂)] - [plugins(插件)] - environments(环境配置) - environment(环境变量) - transactionManager(事务管理器) - dataSource(数据源) - [databaseIdProvider(数据库厂商标识)] - [mappers(映射器)
Mybatis 默认transactionManager(事务管理器):JDBC , dataSource(数据源):POOLED
3.1 类型别名(typeAliases)
类型别名可为 Java 类型设置一个缩写名字。
<typeAliases> <typeAlias type="com.kuang.pojo.User" alias="user"/> </typeAliases>
也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,默认会使用首字母小写的类名作为别名
<typeAliases> <package name="com.kuang.pojo"/></typeAliases>
也可通过在实体类上添加注解自定义别名
@Alias("user")
3.2、映射器
MapperRegistry:注册绑定我们的Mapper文件
方式一【推荐使用】
<mappers> <mapper resource="com/kuang/dao/UserMapper.xml"/></mappers>
方式二:使用class文件注册绑定
<mappers> <mapper class="com.kuang.dao.UserMapper"/></mappers>
方式三:使用扫描包进行绑定
<mappers> <package name="com.kuang.dao"/></mappers>
方式2、3的注意点:
- 接口和他的Mapper配置文件必须同名
- 接口和他的Mapper配置文件必须在同一包下
3.3、生命周期和作用域
不同作用域和生命周期类别是至关重要的,因为错误的使用会导致非常严重的并发问题。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vS55G0Od-1633312136266)(E:\docs\笔记\图片\Mybatis.png)]
SqlSessionFactoryBuilder:
- 一旦创建了 SqlSessionFactory,就不再需要它了 。
- 局部变量
SqlSessionFactory:
- 就是数据库连接池。
- 一旦被创建就应该在应用的运行期间一直存在 ,没有任何理由丢弃它或重新创建另一个实例 。
- 因此 SqlSessionFactory 的最佳作用域是应用作用域。
- 最简单的就是使用单例模式或者静态单例模式。
SqlSession:
- 每个线程都应该有它自己的 SqlSession 实例。
- 连接到连接池的请求!
- SqlSession 的实例不是线程安全的,因此是不能被共享的 ,所以它的最佳的作用域是请求或方法作用域。
- 用完之后赶紧关闭,否则资源被占用。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pj2V24yn-1633312136279)(E:\docs\笔记\图片\sqlsession.png)]
这里面的每个Mapper,就代表一个具体的业务!
3、属性名与字段名不一致
User
package com.hou.pogo;public class User { private int id; private String name; private String password;}
问题:
User{id=2, name=‘wang’, password=‘null’}
解决方法:
- 起别名
<select id="getUserById" resultType="User" parameterType="int"> select id,name,pwd as password from mybatis.user where id = #{id}</select>
- resultMap 结果集映射
<?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.hou.dao.UserMapper"> <select id="getUserById" resultMap="UserMap" parameterType="int"> select * from mybatis.user where id = #{id} </select> <!--结果集映射--> <resultMap id="UserMap" type="User"> <!--colunm 数据库中的字段,property实体中的属性--> <result column="id" property="id"></result> <result column="name" property="name"></result> <result column="pwd" property="password"></result> </resultMap></mapper>
4、日志
4.1、日志工厂
logImpl:指定 MyBatis 所用日志的具体实现,未指定时将自动查找。包括:
- SLF4J
- LOG4J [掌握]
- LOG4J2
- JDK_LOGGING
- COMMONS_LOGGING
- STDOUT_LOGGING [掌握]
- NO_LOGGING
STDOUT_LOGGING 标志日志输出
4.2、 Log4j使用
- 导包
<dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version></dependency>
- 新建log4j.properties文件
### set log levels ###log4j.rootLogger = DEBUG,console,file### 输出到控制台 ###log4j.appender.console = org.apache.log4j.ConsoleAppenderlog4j.appender.console.Target = System.outlog4j.appender.console.Threshold = DEBUGlog4j.appender.console.layout = org.apache.log4j.PatternLayoutlog4j.appender.console.layout.ConversionPattern = [%c]-%m%n### 输出到日志文件 ###log4j.appender.file=org.apache.log4j.RollingFileAppenderlog4j.appender.file.File=./log/hou.loglog4j.appender.file.MaxFileSize=10mb log4j.appender.file.Threshold=DEBUG log4j.appender.file.layout=org.apache.log4j.PatternLayoutlog4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n# 日志输出级别log4j.logger.org.mybatis=DEBUGlog4j.logger.java.sql=DEBUGlog4j.logger.java.sql.Statement=DEBUGlog4j.logger.java.sql.ResultSet=DEBUGlog4j.logger.java.sql.PreparedStatement=DEBUG
- 配置实现
<settings> <setting name="logImpl" value="LOG4J"/></settings>
- Log4j使用
package com.hou.dao;import com.hou.pojo.User;import com.hou.utils.MybatisUtils;import org.apache.ibatis.session.SqlSession;import org.apache.log4j.Logger;import org.junit.Test;public class UserDaoTest { static Logger logger = Logger.getLogger(UserDaoTest.class); @Test public void test(){ // 获得sqlsession对象 SqlSession sqlSession = MybatisUtils.getSqlSession(); try{ // 1.执行 getmapper UserMapper userDao = sqlSession.getMapper(UserMapper.class); logger.info("测试"); User user = userDao.getUserById(2); System.out.println(user); }catch(Exception e){ e.printStackTrace(); }finally{ //关闭 sqlSession.close(); } } @Test public void testLog4j(){ logger.info("info:进入了testlog4j"); logger.debug("debug:进入了testlog4j"); logger.error("error:进入了testlog4j"); }}
简单使用
-
导包
import org.apache.log4j.Logger;
-
日志对象
static Logger logger = Logger.getLogger(UserDaoTest.class);
-
日志级别
logger.info("info:进入了testlog4j"); logger.debug("debug:进入了testlog4j"); logger.error("error:进入了testlog4j");
5. 分页
5.1、Limit 分页
SELECT * from user limit startIndex,pageSize;SELECT * from user limit 0,2;public interface UserMapper { List<User> getUserByLimit(Map<String, Integer> map);}
xml
<select id="getUserByLimit" parameterType="map" resultType="User" resultMap="UserMap"> select * from mybatis.user limit #{startIndex},#{pageSize} </select>
test类
@Testpublic void getByLimit(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); Map<String, Integer> map = new HashMap<String, Integer>(); map.put("startIndex", 1); map.put("pageSize", 2); List<User> userList = mapper.getUserByLimit(map); for(User user:userList){ System.out.println(user); } sqlSession.close();}
2. RowBounds分页
@Test
@Testpublic void getUserByRow(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); //RowBounds实现 RowBounds rowBounds = new RowBounds(1, 2); //通过java代码层面 List<User> userList = sqlSession.selectList ("com.hou.dao.UserMapper.getUserByRowBounds", null,rowBounds); for (User user : userList) { System.out.println(user); } sqlSession.close();}
3. 分页插件
- pageHelper
6、Mybatis详细执行流程:
- Resource获取全局配置文件
- 实例化SqlsessionFactoryBuilder
- 解析配置文件流XMLCondigBuilder
- Configration所有的配置信息
- SqlSessionFactory实例化
- trasactional事务管理
- 创建executor执行器
- 创建SqlSession
- 实现CRUD
- 查看是否执行成功
- 提交事务
- 关闭
7、 Lombok
@Data:无参构造,get,set,toString,hashCode
@AllArgsConstructor :有参构造
@NoArgsConstructor:无参构造