简介:
MyBatis:是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
Java web中常见的框架有哪些?
在常见的mvc体系架构中,之前我们是使用servlet做前端的控制器,使用dao做后端的数据持久层,view做显示。在前端的 控制器接收到请求之后,需要调用dao来做完整的业务。
在这个过程中出现了一些框架来代替servlet的工作:
Struts Struts2 Springmvc
也出现了一些框架代替dao做持久层的工作:
Hibernate MyBatis(ibatis)
层与层之间的“装配工作” 我们用Spring来实现
Jdbc 的一些缺点:
- 重复的连接获取和释放
- 硬编码 --自己写原生的代码
- 传入sql语句的所有的所需参数
- 重复的增删改查
- 返回的数据处理
效率不是很好,耗时较长,所以就用了MyBatis,Hibernate做持久层的框架
Mybatis能帮我们做什么?
- 封装数据库的连接池,简化了数据库的连接和获取和释放
- 绝大多数的参数的配置化,使用xml文件完成参数配置,
- 结合pojo与数据库表,字段之间的映射来操作crud
- 结果集自动识别,自动装配,简化封装,自己将结果集封装成pojo类
【POJO(Plain Ordinary Java Object)简单的Java对象,实际就是普通JavaBeans,是为了避免和EJB混淆所创造的简称。】
MyBatis的安装:
第一种方式:将Mybatis的相关jar包从互联网上下载到自己的电脑上,项目lib文件夹中导入jar包,build path搞定。
缺点:由于相关的jar包的数量非常的多,不同的jar包对应不同的功能,所以在选择jar包的时候要注意它的一些区别,就可能出现这一类的jar包的版本问题,出现项目启动报错等。
第二种方式:用Maven来管理项目(推荐)
前面已经讲解了Maven的web项目的搭建,这里就不再赘述了,下面开始搭建MyBatis。
MyBatis的配置及简单应用(Maven):
根据之前的Maven文章来搭建的项目目录结构为这样
1.在pom.xml中<dependencies></dependencies>内添加依赖(https://mvnrepository.com/ Maven中央仓库中可以搜索到所需要包的依赖。)
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<dependency>
<groupId>apache-log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
</dependency>
</dependencies>
2.接着右键项目名来创建一个Source Folder 名为src\main\resources 用来放配置文件
依次创建配置文件
db.propeties数据源
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db_demo?useSSL=true&CharacterEncoding=utf-8
jdbc.user=root
jdbc.password=123456
这里注意:如果mysql-connector-java连接为8.x.x的话,驱动和连接地址要修改为,url里时区一定要加其它选择性的加。
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/testconn?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Hongkong
mybatis-config.xml MyBatis的配置文件:
<?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>
<properties resource="db.properties"></properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClass}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/zhu/mapper/UserMapper.xml"/><!--加入mapper映射 -->
</mappers>
</configuration>
log4j.properties 日志:
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
3.在src\main\java 下创建一个UserMapper.xml 包名为com.zhu.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.zhu.mapper.UserMapper">
<insert id="insertUser">
insert into t_user(name,password) values("张三","123456")
</insert>
</mapper>
4. test方法 注意3个对象 sqlSessionBuilder sqlSessionFactory SqLSession
在src\test\java 下创建一个测试类TestUserMapper 包名 com.zhu.test
package com.zhu.test;
import java.io.IOException;
import java.io.InputStream;
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 org.junit.Test;
public class TestUserMapper {
@Test
public void insertUser() throws IOException{
//加载连接信息Mybatis-config.xml
InputStream input = Resources.getResourceAsStream("mybatis-config.xml");
//得到sqlsessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(input);
//开启session
SqlSession session = factory.openSession();
//调用insert方法
int insert = session.insert("com.zhu.mapper.UserMapper.insertUser");
session.commit();
session.close();
}
}
简单的应用到此结束。
逐渐深入:
Mapper中参数占位符
<insert id="addUser" parameterType="com.zhu.pojo.User"
useGeneratedKeys="true" keyColumn="add_id" keyProperty="addid">
insert into t_user
(user_id,name,password) values(#{user_id},#{name},#{password});
</insert>
其中 parameterType="com.zhu.pojo.User"为方法传入参数类型
useGeneratedKeys="true"为主键自增长回显
keyColumn="add_id" 主键在数据库中的名字
keyProperty="addid" 主键在User实体类中对应的名字
调用时
session.insert("com.zhu.mapper.UserMapper.addUser", user);//user是自己设置的参数对象
这里只用了 #{} 形式的占位,还有一种占位是 ${}形式的占位。
区别:
1.参数为普通类型时只能用#{},里面的内容可随便写
2.对象类型可以使用#{}也可以使用${}但是不能随便写,只能写属性名
3.#{}为真正的占位,${}是字符串的拼接
当属性名和数据库的字段名不匹配的时候,那么返回null
解决办法1.as关键字来取别名
解决办法2,提供结果集映射
<resultMap type="User" id="selectMap">
<!--id列所为主键列,可以换成result 但是result不能换成id -->
<id column="add_id" property="addid"/>
<result column="user_name" property="username"/>
</resultMap>
<select id="selectUser" resultMap="selectMap" parameterType="long">
select * from t_user where add_id=#{add_id}
</select>
其中resultMap为返回结果类型
<resultMap>标签中的id与<select>标签中的resultMap要一致
column为表中字段名 property为pojo类中相应字段名
注:查询时事务可以不用提交
可以看到我在<resultMap>中type里直接写的User没有加包名就可以用而且大小写忽略,怎么做的?
其实很简单 只要在mybatis-config.xml中添加如下配置即可:
<!--配置别名 -->
<typeAliases>
<!--package会直接扫描包下的类名 -->
<package name="com.zhu.pojo"h/>
</typeAliases>
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MyBatis的另一种代码编写方式:
创建一个接口来定义方法,这其中有两种写法
- 在UserMapper.xml中不写sql语句,用注解来写sql
- 在UserMapper.xml中写sql语句,且标签id对应方法名
package com.zhu.mapper;
public interface UserMapper {
//@这一块也是mybatis动态代理生成的注解
//对于这种写法,可以用,但是不建议使用,
//因为简单的sql时,很好用,但是复杂的sql就不好用了
@Select("select * from t_user")
List<AjiaUser> GetAll();
@Select("select * from t_user where id=#{id}")
AjiaUser getId(long id);
//---------------------------------------------------
//批量添加
void addBatch(List<User> list );
//批量的删除
void deleteBatch(List<Long> list);
}
Usermapper.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">
<mapper namespace="com.zhu.mapper.UserMapper">
<!--id和接口的方法名对应 -->
<insert id="addBatch" parameterType="list" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
insert into t_user(user_name,password)
values
<!--
collection:要循环的集合
item:循环出的每个元素
separator:循环出的结果之间的分隔符
-->
<foreach collection="list" item="u" separator=",">
(#{u.username},#{u.password})
</foreach>
</insert>
<delete id="deleteBatch" parameterType="list">
<!-- delete from t_user where id in (
<foreach collection="list" item="id" separator=",">
#{id}
</foreach>
) -->
delete from t_user where id in
<!--
open:循环内容最前面的符号
close:循环内容最后面的符号
-->
<foreach collection="list" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>
</mapper>
测试l类:
UserMapperTest.java:
public class UserMapperTest {
@Test
public void selectAll() throws IOException{
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = factory.openSession();
//mybatis动态代理生成的一个类---不建议去看
UserMapper mapper = session.getMapper(UserMapper.class);
System.out.println(mapper);
List<AjiaUser> getAll = mapper.GetAll();
for (User user : getAll) {
System.out.println(user);
}
session.close();
}
@Test
public void selectOne() throws IOException{
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = factory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
System.out.println(mapper);
User user = mapper.getId(14l);
System.out.println(user);
session.close();
}
@Test
public void addBatch() throws IOException{
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = factory.openSession();
//mybatis动态代理生成的一个类
UserMapper mapper = session.getMapper(UserMapper.class);
System.out.println(mapper);
ArrayList<User> list = new ArrayList<>();
list.add(new User("王一", "123456"));
list.add(new User("王二", "888888"));
mapper.addBatch(list);
session.commit();
session.close();
}
@Test
public void deleteBatch() throws IOException{
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = factory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
ArrayList<Long> list = new ArrayList<>();
list.add(88l);
list.add(89l);
mapper.deleteBatch(list);
session.commit();
session.close();
}
}
编写映射文件注意事项:
到此,MyBatis的简单应用已经基本完成,而且还涉及了批量操作。
下一篇我们来说说MyBatis的多对一,一对多(一对一)
非常感谢!