如何获得Mybatis?
maven仓库
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.2version>
dependency>
Github:https://github.com/mybatis/mybatis-3/releases
中文文档:https://mybatis.org/mybatis-3/zh/getting-started.html
数据持久化
持久化就是将程序的数据在持久状态和瞬时状态转化的过程
内存:断电即失
数据库(JDBC),I/O文件持久化
生活:冷藏、罐头
Dao层、Service层、Controller层
思路:
1.创建父工程 引入mysql mybatis Junit 依赖
2.maven子工程 编写mybatis核心配置文件 mybatis-config.xml 连接数据库
3.untils层 pojo层 dao层
4.编写mybatis工具类 编写实体类
5.编写Mapper接口 以及对应UseMapper.xml配置文件
6.Junit测试
建立mysql数据库
CREATE DATABASE MYBATIS;
USE MYBATIS;
CREATE TABLE user(
id INT(20) NOT NULL PRIMARY KEY,
name VARCHAR(30) DEFAULT NULL,
pwd VARCHAR(30) DEFAULT NULL
)ENGINE = INNODB DEFAULT CHARSET = utf8;
INSERT INTO user(id, name, pwd) VALUES
(1, '孙孙孙', 2002),
(2, '铭铭铭', 1208),
(3, '孙不坚', 1234);
新建项目
1.新建一个普通的maven项目
2.删除src目录
3.导入maven依赖
将该工程当做父工程
<dependencies>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.47version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.3version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
<scope>testscope>
dependency>
dependencies>
4.创建子工程
<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?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="sm1208"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="com/sun/dao/UserMapper.xml"/>
mappers>
configuration>
package com.sun.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;
//sqlSessionFactory --> sqlSession
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory = null;
static {
try {
// 使用Mybatis 第一步:获取sqlSessionFactory对象
String resource = "mybatis-config.xml";
InputStream in = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
} catch (IOException e) {
e.printStackTrace();
}
}
// 有了SqlSessionFactory,顾名思义,我们就可以从中获得 SqlSession 的实例了
// SqlSession 完全包含了面向数据库执行 SQL 命令所需要的所有方法
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
package com.sun.pojo;
public class User {
private int id;
private String name;
private String pwd;
public User() {
}
public User(int id, String name, String pwd) {
this.id = id;
this.name = name;
this.pwd = 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;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", pwd='" + pwd + '\'' +
'}';
}
}
Mapper接口
package com.sun.dao;
import com.sun.pojo.User;
import java.util.List;
public interface UserMapper {
//查询所有的用户
List<User> getUserList();
}
接口实现类,由原来的UserDaoImp转变为一个Mapper配置文件,即UseMapper.xml
<mapper namespace="com.sun.dao.UserMapper">
<select id="getUserList" resultType="com.sun.pojo.User">
select * from mybatis.user;
select>
mapper>
junit 测试
package com.sun.dao;
import com.sun.pojo.User;
import com.sun.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class UserMapperTest {
@Test
public void test(){
// 第一步:获取SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
// 方式一:getMapper
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = userMapper.getUserList();
for (User user :
userList) {
System.out.println(user);
}
// 关闭 SqlSession
sqlSession.close();
}
}
<build>
<resources>
<resource>
<directory>src/main/resourcesdirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
includes>
<filtering>truefiltering>
resource>
<resource>
<directory>src/main/javadirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
includes>
<filtering>truefiltering>
resource>
resources>
build>
//引入依赖
注意点:org.apache.ibatis.binding.BindingException: Type interface com.xulong.dao.UserDao is not known to the MapperRegistry.
<mappers>
<mapper resource="com/sun/dao/UserMapper.xml"/>
mappers>
namespace中的包名要和 Dao/Mapper 接口的包名一致
在xml文件sql
编写接口 编写对应Mapper中的sql语句 编写测试
增 删 改 需要提交事务 !
//根据ID查询用户
User getUserByID(int id);
<select id="getUserByID" parameterType="int" resultType="com.sun.pojo.User">
select * from mybatis.user where id = #{id};
select>
@Test
public void getUserByID(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.getUserByID(1);
System.out.println(user);
sqlSession.close();
}
int addUser(User user);
<insert id="addUser" parameterType="com.sun.pojo.User">
insert into mybatis.user (id, name, pwd) values (#{id}, #{name}, #{pwd});
insert>
@Test
public void addUser(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User(4, "孙明明", "1324214");
int result = mapper.addUser(user);
if (result > 0){
System.out.println("插入成功!");
}
//提交事务
sqlSession.commit();
sqlSession.close();
}
//修改用户
int updateUser(User user);
<update id="updateUser" parameterType="com.sun.pojo.User">
update mybatis.user set name = #{name}, pwd = #{pwd} where id = #{id};
update>
@Test
public void updateUser(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User(5, "旺财", "14432434");
mapper.updateUser(user);
int result = mapper.updateUser(user);
if (result > 0){
System.out.println("修改成功!");
}
sqlSession.commit();
sqlSession.close();
}
//删除用户
int deleteUser(int id);
<delete id="deleteUser" parameterType="int">
delete from mybatis.user where id = #{id};
delete>
@Test
public void deleteUser(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.deleteUser(4);
sqlSession.commit();
sqlSession.close();
}
假设我们的实体类,数据库中的表、字段或者参数过多,我们应当考虑使用Map。
//万能的Map
int addUser1(Map<String, Object> map);
<insert id="addUser1" parameterType="Map">
insert into mybatis.user (id, name, pwd) values (#{userid}, #{username}, #{password});
insert>
@Test
public void addUser1(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Map<String, Object> map = new HashMap<>();
map.put("userid", 5);
map.put("username", "赵六");
map.put("password", "144324324");
mapper.addUser1(map);
sqlSession.close();
}
Map传递参数,直接在sql中取出key即可【parameterType=“Map”】
对象传递参数,直接在sql中取对象的属性即可【parameterType=“Object”】
只有一个基本类型参数的情况下,可以直接在sql中取到,不需要parameterType的设置
多个参数用Map,或者注解
mybatis-config.xml配置解析
xml里属性都是可外部配置且可动态替换的,我们可以通过properties属性来实现引用配置文件。
编写一个配置文件 db.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
username=root
password=sm1208
在核心配置文件中引入
直接引入外部文件
<properties resource="db.properties"> properties>
可以在其中增加一些属性配置
<properties resource="db.properties">
<property name="username" value="root"/>
<property name="password" value="sm1208"/>
properties>
类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。
第一种配置方式 ,User 可以用在任何使用 com.sun.pojo.User 的地方使用。
<typeAliases>
<typeAlias alias="User" type="com.sun.pojo.User"/>
typeAliases>
第二种配置方式,指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,例如:
扫描实体类pojo的包,它的默认别名就为这个类的类名User。
<typeAliases>
<package name="com.sun.pojo"/>
typeAliases>
在实体类比较少的情况,推荐使用第一种方式,如果实体类多的情况下,建议使用第二种方式,第一种可以DIY别名,第二种则不行,如果想实现第二种的DIY,在第二种配置方式的基础上还需要在实体类上增加注解:
import org.apache.ibatis.type.Alias;
@Alias("hello")
public class User {
}
MyBatis 可以配置成适应多种环境,尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。
环境可以随意命名,但务必保证默认的环境 ID 要匹配其中一个环境 ID。
MyBatis 的行为已经由上述元素配置完了,我们现在就要来定义 SQL 映射语句了。 但首先,我们需要告诉 MyBatis 到哪里去找到这些语句。 在自动查找资源方面,Java 并没有提供一个很好的解决方案,所以最好的办法是直接告诉 MyBatis 到哪里去找映射文件,**即映射器注册问题MapperRegistry:注册绑定我们的Mapper文件。**你可以使用相对于类路径的资源引用,或完全限定资源定位符(包括 file:///
形式的 URL),或类名和包名等。例如:
【推荐使用】
<mappers>
<mapper resource="com/sun/dao/UserMapper.xml"/>
mappers>
使用class文件进行绑定
<mappers>
<mapper class="com.sun.dao.UserMapper"/>
mappers>
使用扫描包进行注入绑定
<mappers>
<package name="com.sun.dao"/>
mappers>
大家之前都学习过面向对象编程,也学习过接口,但在真正的开发中,很多时候我们会选择面向接口编程。
根本原因:解耦,可拓展,提高复用,分层开发中,上层不用管具体的实现,大家都遵守共同的标准,使得开发变得容易,规范性更好。
在一个面向对象的系统中,系统的各种功能是由许许多多的不同对象协助完成的。在这种情况下,各个对象内部是如何实现自己的,对系统设计人员来讲就不那么重要了。
而各个对象之间的协作关系则成为系统设计的关键。小到不同类之间的通信,大道各模块之间的交互,在系统设计之初都是要着重考虑的,这也是系统设计的主要工作内容。面向接口编程就是按照这种思想来编程。
关于接口的理解
接口从更深层次的理解,应是定义(规范、约束)与实现(名实分离的原则)的分离。
接口的本身反映了系统设计人员对系统的抽象理解。
接口应有两种
一个体可能有多个抽象面,抽象体和抽象面是有区别的。
三个面向区别
注解在接口上实现
@Select("select * from user")
List<User> getUsers();
在核心配置文件中绑定接口
<mappers>
<mapper class="com.fj.dao.UserMapper"/>
mappers>
测试
@Test
public void test(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
//底层主要应用反射
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> users = mapper.getUsers();
for (User user : users){
System.out.println(user);
}
sqlSession.close();
}
本质:反射机制实现
底层:动态代理
Mybatis详细执行流程
我们可以在工具类创建的时候实现自动提交事务
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession(true);
}
编写接口,添加注解
@Select("select * from user")
List<User> getUsers();
// 方法中如果有多个参数,那么每一个参数前都必须加上@Param("")
@Select("select * from user where id = #{id}")
User getUserByID(@Param("id") int id);
// User getUserByID(@Param("id") int id, @Param("name") String name);
@Insert("insert into user (id, name, pwd) values (#{id}, #{name}, #{password})")
int 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-config.xml文件中】
<mappers>
<mapper class="com.sun.dao.UserMapper"/>
mappers>