Mybatis学习
Mybatis学习
简介
详见百度百科,搜Mybatis3
概述
持久层
数据持久化:持久化就是将程序的数据在持久状态和瞬时状态转化的过程
从例子入手
准备
先建立一个简单的库和表->建立依赖->xml配置文件->建立mybaitsSessionFactory
<artifactId>mybatis</artifactId>
<artifactId>mysql-connector-java</artifactId>
<artifactId>junit</artifactId>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
public class MybatisDao {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
//既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。SqlSession
// 提供了在数据库执行 SQL 命令所需的所有方法。你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
实现类(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>
</configuration>
<!--绑定一个mapper接口 -->
<mapper namespace="com.dao.UserDao">
<select id="getUserList" resultType="com.pojo.User">
select * from mybatis.user
</select>
</mapper>
添加xml实现类到mybatis-config.xml的mapper register
<mappers>
<mapper resource="com/dao/impl/UserMapper.xml"/>
</mappers>
maven的一个坑-> 扫描子路径的配置文件
<build>
<resources>
<resource>
<directory>src/main/resource</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
// 1.建立mybatis-config.xml -> mybatisDao
// 2.建立pojo和dao
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private int id;
private String name;
private String pwd;
}
public interface UserDao {
List<User> getUserList();
}
// 3.配置UserMapper.xml 并将其注册到mybatis-config.xml
// 4.确认xml可以被maven识别
// 5.编写测试类进行测试
public class UserDaoTest {
@Test
public void test(){
SqlSession sqlSession = MybatisDao.getSqlSession();
// 方式一,执行sql
UserDao mapper = sqlSession.getMapper(UserDao.class);
List<User> userList = mapper.getUserList();
for (User user : userList) {
System.out.println(user);
}
sqlSession.close();
}
}
CRUD
增删改需要提交事务
- CRUD必须与tag准确对应
- resource绑定mapper必须使用path/path,而对应的namespace必须使用
*.*的形式
User getUserById(int id);
int addUser(User user);
int updateUser(User user);
int deleteUser(int id);
@Test
public void getUserByIdTest(){
SqlSession sqlSession = MybatisDao.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
User userById = mapper.getUserById(1);
System.out.println(userById);
sqlSession.close();
}
// 增删改必须要提交事务
@Test
public void addUser(){
SqlSession sqlSession = MybatisDao.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
int i = mapper.addUser(new User(5, "hello", "2222"));
if(i>0){
System.out.println("insert success");
}
sqlSession.commit();
sqlSession.close();
}
@Test
public void updateUser(){
SqlSession sqlSession = MybatisDao.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
mapper.updateUser(new User(5,"4444","1233321"));
sqlSession.commit();
sqlSession.close();
}
@Test
public void deleteUser(){
SqlSession sqlSession = MybatisDao.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
mapper.deleteUser(5);
sqlSession.commit();
sqlSession.close();
}
<select id="getUserById" parameterType="int" resultType="com.pojo.User">
select * from mybatis.user where id = #{id}
</select>
<insert id="addUser" parameterType="com.pojo.User">
insert into mybatis.user (id, name, pwd) VALUES (#{id},#{name},#{pwd})
</insert>
<update id="updateUser" parameterType="com.pojo.User">
update mybatis.user set name=#{name},pwd=#{pwd} where id=#{id}
</update>
<delete id="deleteUser" parameterType="int">
delete from mybatis.user where id=#{id}
</delete>
使用Map进行部分字段的CRUD
可以使用map来使用部分字段来进行CRUD
<insert id="insertUserMap" parameterType="map">
insert into mybatis.user (id,name, pwd) VALUES (#{userid},#{username},#{password})
</insert>
int insertUserMap(Map<String,Object>map);
@Test
public void insertUser(){
SqlSession sqlSession = MybatisDao.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
Map<String,Object>map = new HashMap<String,Object>();
map.put("username","map_user");
map.put("userid",4);
map.put("password","2233");
mapper.insertUserMap(map);
sqlSession.commit();
sqlSession.close();
}
配置解析
环境配置environments
Mybatis默认事务管理器JDBC,连接池:POOLED
properties属性
用properties引用标签-> 建立db.properties
<!--这里导入properties资源,顺序不能变 -->
<properties resource="db.properties" />
<environments default="development">
<!--default可以指定运行环境 -->
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!-- 这里可以使用${}来引用properties的key-->
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
typeAliases类型别名
<typeAliases>
<typeAlias type="com.pojo.User" alias="User"/>
<!--扫描包的实体类,默认别名为类名 @Alias("xxx")可以使用注解自定义别名 -->
<package name="com.pojo"/>
</typeAliases>
<!-- <select id="getUserList" resultType="User">-->
plugin等详见官方文档 mybatis官方文档
mappers映射器
方式一
<mappers>
<mapper resource="com/dao/impl/UserMapper.xml"/>
</mappers>
方式二:使用class属性 绑定注册:接口和mapper文件必须在同一个包下且名称相同
方式三:使用扫描包进行注册:接口和mapper文件必须在同一个包下且名称相同
生命周期和作用域
SqlSessionFactoryBuilder:一旦创建了SqlSessionFactory就不再需要了
SqlSessionFactory:想象为数据库连接池,一旦创建在运行期间一致存在,可以使用单例模式
SqlSession:连接到连接池的一个请求,用完即关闭
mapper:一个业务,由Session创建
解决属性名和字段名不对应的问题
resultMap结果集映射
<resultMap id="UserMap" type="User">
<result column="pwd" property="password"/>
</resultMap>
<select id="getUserList" resultMap="UserMap">
Mybatis日志实现
日志工厂
内置实现日志,无需使用其余任何代码,注入依赖即可(在mybatis-config.xml)文件里配置
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
log4j
开始使用log4j
-
添加依赖,直接添加log4j依赖即可
-
在resources文件夹下添加
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/kuang.log 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.sql=DEBUG log4j.logger.java.sql.Statement=DEBUG log4j.logger.java.sql.ResultSet=DEBUG log4j.logger.java.sql.PreparedStatement=DEBUG -
配置log4j的实现
注意:中文会乱码
<settings> <setting name="logImpl" value="LOG4J"/> </settings> -
简单使用
// 获取logger的对象,并通过反射绑定当前类 static Logger logger = Logger.getLogger(UserDaoTest.class); @Test public void testLog(){ logger.info("开始进行日志测试"); logger.debug("开始进行日志测试"); logger.error("开始进行日志测试"); }
Mybatis分页
分页语法
select * from user limit startIndex,pageSize;
使用Limit分页
-
实现接口
List<User> getUserByLimit(Map<String,Integer> map); -
xml mapper映射
<resultMap id="UserMap" type="User"> <result column="pwd" property="password"/> </resultMap> <select id="getUserByLimit" parameterType="map" resultMap="UserMap"> select *from mybatis.user limit #{startIndex},#{pageSize} </select> -
测试类测试
@Test public void testGetUserByLimit(){ SqlSession sqlSession = MybatisDao.getSqlSession(); UserDao mapper = sqlSession.getMapper(UserDao.class); HashMap<String, Integer> map = new HashMap<String, Integer>(); map.put("startIndex",0); map.put("pageSize",2); List<User> userByLimit = mapper.getUserByLimit(map); for (User user : userByLimit) { System.out.println(user); } sqlSession.close(); }
使用面向对象分页
略
注解开发
简单使用
<mappers>
<!--此处对应接口地址 -->
<mapper class="com.dao.impl.UserMapper"/>
</mappers>
public interface UserMapper {
// 使用mybatis注解接口
// 底层使用反射实现
@Select("select * from user")
List<User> getUsers();
}
CRUD
// 方法存在多个参数,每个参数必须加入Param注解
// 基本类型或String,引用类型不需要加入Param注解。sql中引用的即为注解的value值
@Select("select * from user where id=#{id}")
User getUserById(@Param("id") int id);
@Insert("insert into user(id,name,pwd) values (#{id},#{name},#{password})")
void addUser(User user);
@Update("update user set name=#{name},pwd=#{password} where id=#{id}")
int updateUser(User user);
@Delete("delete from user where id=#{id}")
int deleteUser(@Param("id") int id);
Mybatis流程简析与复杂实现
- 获取resources加载全局配置文件
- 实例化
sqlSessionFactoryBuilder构造器 - 解析xml配置文件流
- Configuration所有的配置信息
- SqlSessionFactory实例化
- transaction事务->executor执行器
- 创建sqlSession,实现CRUD
- 查看是否执行成功->提交事务,关闭事务
多对一处理
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');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('2', '小红', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('3', '小张', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('4', '小李', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('5', '小王', '1');
-
建立pojo实体类,建立对应的mapper接口类
-
复杂关联需要用xml实现,因此将xml文件放置在resources文件夹下,进行mapper配置和namespace配置
<mappers> <!-- <mapper class="com.dao.TeacherMapper"/>--> <!-- <mapper class="com.dao.StudentMapper"/>--> <mapper resource="com/StudentMapper.xml"/> <mapper resource="com/TeacherMapper.xml"/> </mappers> -
实体类起别名,建立实体属性映射
<typeAliases> <typeAlias type="com.pojo.Student" alias="Student"/> <typeAlias type="com.pojo.Teacher" alias="Teacher"/> </typeAliases> -
一个简单的getById验证配置正确性
-
进行多对一的关系映射
<select id="getStudent" resultType="Student" resultMap="StuToTeacher"> select * from mybatis.student; </select> <resultMap id="StuToTeacher" type="Student"> <result property="id" column="id"/> <result property="name" column="name"/> <!--复杂属性 association 对象 ; collection 集合 这里的property数据库的字段属性,column实体类(可以是被查询的字段属性),javaType表示映射的实体类,select表示需要执行外键映射的查询的目标 --> <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/> </resultMap> <select id="getTeacher" resultType="Teacher"> select * from mybatis.teacher where id=#{id}; </select > <!--查询方式2 --> <select id="getStudent2" resultType=""> select s.id sid, s.name sname, t.name tname from mybatis.teacher t, mybatis.student s; </select> <resultMap id="StudentTeacher" type="Student"> <result property="id" column="sid"/> <result property="name" column="sname"/> <association property="teacher" javaType="Teacher"> <result property="name" column="tname"/> </association> </resultMap>
一对多处理
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--核心配置文件-->
<mapper namespace="com.dao.TeacherMapper">
<!-- 嵌套查询-->
<select id="getTeacher" resultMap="TeacherStudent">
select s.name sname, t.name tname, t.id tid
from mybatis.teacher t,
mybatis.student s
where s.tid = t.id and t.id=#{tid};
</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>
<!--关联查询 -->
<select id="getTeacher2" resultMap="TeacherStudent2">
select * from mybatis.teacher where id=#{tid};
</select>
<resultMap id="TeacherStudent2" type="Teacher">
<collection property="students" javaType="ArrayList" ofType="Student" select="getStudentByTeacherId" column="id"/>
</resultMap>
<select id="getStudentByTeacherId" resultType="Student">
select * from mybatis.student where tid=#{tid};
</select>
</mapper>

浙公网安备 33010602011771号