mybatis java持久层框架 (对JDBC进行封装,并自动完成ORM操作)
ORM框架是对象关系映射,一个对象与表中的一行数据一一对应,把对象持久化到数据库中。
我将会一步一步详细的创建一个完整的mybatis
建项目 ---- 改POM ---- 写YML(或XML) ---- 写业务
1.新建maven项目
2.在POM中添加依赖(两个)
<!-- mybatis核心依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<!-- mybatis驱动依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
3.创建数据库
新建数据库bookshop并导入表(三个)
user表
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(20) NOT NULL,
`PASSWORD` varchar(32) NOT NULL,
`realname` varchar(20) DEFAULT NULL,
`email` varchar(50) NOT NULL,
`gender` varchar(50) NOT NULL,
`flag` int(11) DEFAULT NULL,
`role` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', 'admin', '888', '李明', 'liming@qq.com', '男', '1', '0');
INSERT INTO `user` VALUES ('2', 'jiangjiang', '123456', '犟犟', 'jiangjiang@163.com', '男', '1', '1');
INSERT INTO `user` VALUES ('3', 'yitao', '123456', '艺涛', 'shuliang@163.com', '女', '1', '1');
book表
DROP TABLE IF EXISTS `book`;
CREATE TABLE `book` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(50) NOT NULL,
`author` varchar(20) DEFAULT NULL,
`publicDate` datetime DEFAULT NULL,
`publisher` varchar(50) DEFAULT NULL,
`isbn` varchar(15) DEFAULT NULL,
`price` decimal(8,2) DEFAULT NULL,
`picture` varchar(50) DEFAULT NULL,
`cid` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `cid` (`cid`),
CONSTRAINT `book_ibfk_1` FOREIGN KEY (`cid`) REFERENCES `category` (`cid`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of book
-- ----------------------------
INSERT INTO `book` VALUES ('1', 'Java核心技术 卷I 基础知识', '霍斯特曼', '2019-12-01 00:00:00', '机械工业出版社', '9787111636663', '102.80', null, '10');
INSERT INTO `book` VALUES ('2', '高性能MySQL(第3版)', '特卡琴科', '2013-05-10 00:00:00', '电子工业出版社', '9787121198854', '122.90', null, '10');
INSERT INTO `book` VALUES ('3', 'Java从入门到精通(第5版)', '明日科技', '2019-03-01 00:00:00', '清华大学出版社', '9787302517597', '61.40', null, '10');
INSERT INTO `book` VALUES ('4', 'Java编程思想(第4版)', 'Bruce Eckel', '2007-06-01 00:00:00', '机械工业出版社', '9787111213826', '100.30', null, '10');
INSERT INTO `book` VALUES ('5', '深入理解Java虚拟机', '周志明', '2013-06-01 00:00:00', '机械工业出版社', '9787111421900', '62.40', null, '10');
INSERT INTO `book` VALUES ('6', '高等数学(第七版)(上册)', '同济大学数学系', '2014-07-01 00:00:00', '高等教育出版社', '9787040396638', '40.20', null, '11');
INSERT INTO `book` VALUES ('7', '管理学(第13版)', '斯蒂芬·P·罗宾斯', '2017-01-01 00:00:00', '中国人民大学出版社', '9787300234601', '66.50', null, '14');
INSERT INTO `book` VALUES ('8', '红楼梦原著版(上、下册)', '曹雪芹', '2013-01-01 00:00:00', '人民文学出版社', '9787020002207', '38.90', null, '12');
INSERT INTO `book` VALUES ('9', '水浒传(上下册)(全两册)', '施耐庵 ,罗贯中', '2004-09-01 00:00:00', '人民文学出版社', '9787020008742', '32.90', null, '12');
INSERT INTO `book` VALUES ('10', '西游记(共两册)', '吴承恩 ', '2007-05-01 00:00:00', '人民文学出版社', '9787020051564', '48.00', null, '12');
category表
DROP TABLE IF EXISTS `category`;
CREATE TABLE `category` (
`cid` int(11) NOT NULL,
`cname` varchar(30) NOT NULL,
PRIMARY KEY (`cid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of category
-- ----------------------------
INSERT INTO `category` VALUES ('10', '科技');
INSERT INTO `category` VALUES ('11', '教育');
INSERT INTO `category` VALUES ('12', '小说');
INSERT INTO `category` VALUES ('13', '文艺');
INSERT INTO `category` VALUES ('14', '经管');
INSERT INTO `category` VALUES ('15', '成功');
INSERT INTO `category` VALUES ('16', '生活');
4.创建mybatis配置文件(mybatis-config.xml)
xml文件内容格式
mybatis配置
JDBC环境配置
mysql数据库环境配置
事件管理
连接池
驱动
url
username
password
mapper注册
注册mapper文件所在位置
<?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">
<!--mybatis配置-->
<configuration>
<!-- JDBC环境配置,选中默认环境-->
<environments default="MySqlDB">
<!-- mysql数据库环境配置-->
<environment id="MySqlDB">
<!-- 事件管理-->
<transactionManager type="JDBC"></transactionManager>
<!-- 连接池信息-->
<dataSource type="org.apache.ibatis.datasource.pooled.PooledDataSourceFactory">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/bookshop?useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- mapper注册-->
<mappers>
<!-- 注册Mapper文件所在位置-->
<mapper resource="*Mapper.xml"></mapper>
</mappers>
</configuration>
5.创建对应表中字段的对象
user表
public class User implements Serializable {
private static final long serialVersionUID = 937774262561524430L;
private Integer id;
private String username;
private String password;
private String realname;
private String email;
private String gender;
private Integer flag;
private Integer role;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getRealname() {
return realname;
}
public void setRealname(String realname) {
this.realname = realname;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Integer getFlag() {
return flag;
}
public void setFlag(Integer flag) {
this.flag = flag;
}
public Integer getRole() {
return role;
}
public void setRole(Integer role) {
this.role = role;
}
@Override
public String toString() {
System.out.println( "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", realname='" + realname + '\'' +
", email='" + email + '\'' +
", gender='" + gender + '\'' +
", flag=" + flag +
", role=" + role +
'}'
);
return null;
}
}
book表
/**
* (Book)实体类
*
* @author makejava
* @since 2020-07-03 11:07:37
*/
public class Book implements Serializable {
private static final long serialVersionUID = -35101824717255137L;
private Integer id;
private String title;
private String author;
private Date publicdate;
private String publisher;
private String isbn;
private Double price;
private String picture;
private Integer cid;
private Category category;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public Date getPublicdate() {
return publicdate;
}
public void setPublicdate(Date publicdate) {
this.publicdate = publicdate;
}
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public String getPicture() {
return picture;
}
public void setPicture(String picture) {
this.picture = picture;
}
public Integer getCid() {
return cid;
}
public void setCid(Integer cid) {
this.cid = cid;
}
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
@Override
public String toString() {
return "Book{" +
"id=" + id +
", title='" + title + '\'' +
", author='" + author + '\'' +
", publicdate=" + publicdate +
", publisher='" + publisher + '\'' +
", isbn='" + isbn + '\'' +
", price=" + price +
", picture='" + picture + '\'' +
", cid=" + cid +
", category=" + category +
'}';
}
}
category表
public class Category implements Serializable {
private static final long serialVersionUID = -20079481033681756L;
private Integer cid;
private String cname;
public Integer getCid() {
return cid;
}
public void setCid(Integer cid) {
this.cid = cid;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
@Override
public String toString() {
return "Category{" +
"cid=" + cid +
", cname='" + cname + '\'' +
'}';
}
}
6.定义DAO层接口
6.1新建dao层接口
public interface UserMapper {
//返回数据库所有Book数据
public List<User> selectAllUser();
}
6.2传参
上面我们的方法是无参方法,如果我们想要传参分为两种情况,
一个参数如下
public List<User> selectAllUser(String name);
两个或两个以上的有四种方式:
6.2.1 采用Map传多参
Dao层 :
方法(Map 参数)
XML :
{key} 或 {key,dbcType=VARCHAR}
当mybatis不能自动识别传入对象类型时加入jdbcType=VARCHAR 不加也可以。
如下:
//dao层
public List<User> selectAllUser(Map name);
<!-- xml -->
<select id="selectIdUser" resultType="com.wjh.pojo.User">
SELECT * FROM user WHERE id = #{key}
</select>
6.2.2 param (param从1开始)
Dao层 :
方法(@param(“username”)String name,@param(“userpassword”)String password)
XML :
{username}或{username,dbcType=VARCHAR}
当mybatis不能自动识别传入对象类型时加入jdbcType=VARCHAR 不加也可以。
如下:
//dao层
public List<User> selectAllUser(@param("username")String name,@param("userpassword")String password);
<!-- xml -->
<select id="selectIdUser" resultType="com.wjh.pojo.User">
SELECT * FROM user WHERE name = #{username} AND password = #{userpassword}
<!--也可以
SELECT * FROM user WHERE name = #{param1} AND password = #{param2}
-->
</select>
6.2.3 args (arg从0开始)
Dao层
方法(String name,String password)
XML
{arg0} {arg1}
必须要在{}前面加上#和$ 区别为#会自动处理为字符串 $是原样放上, #会防止sql注入 $不会防止sql注入
如下:
//dao层
public List<User> selectAllUser(String name,String password);
<!-- xml -->
<select id="selectIdUser" resultType="com.wjh.pojo.User">
SELECT * FROM user WHERE name = #{arg0} AND password = #{arg1}
</select>
6.2.4 对象传参
Dao层
方法(User user)
XML
{对象函数}
如下:
//dao层
public List<User> selectAllUser(User user);
<!-- xml -->
<select id="selectIdUser" resultType="com.wjh.pojo.User">
SELECT * FROM user WHERE name = #{name} AND password = #{password}
</select>
7.写XML
新建Mapper.xml并编写Mapper.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">
<!--namepace = 所需实现接口全限定名-->
<mapper namespace="com.wjh.dao.UserDao">
<!-- id = 所需重写的接口抽象方法,resultType = 查询后所需返回的对象类型,parameterType=参数类型(只可以传一种类型)-->
<select id="selectIdUser" resultType="com.wjh.pojo.User">
-- #{arg0} = 方法的第一个参数
SELECT * FROM user WHERE id = #{arg0}
</select>
</mapper>
7.测试
新建一个Test测试类
7.1首先获取mybatis配置文件的流对象
通过Resources.getResourceAsStream(“文件位置/文件名”)
7.2构建sqlsession连接工厂
SqlSessionFactoryBuilder.build(获取到mtbatis配置文档的流对象)
SqlSessionFactory是MyBatis的关键对象,它是个单个数据库映射关系经过编译后的内存镜像.SqlSessionFactory对象的实例可以通过SqlSessionFactoryBuilder对象类获得,而 SqlSessionFactoryBuilder则可以从XML配置文件或一个预先定制的Configuration的实例构建出SqlSessionFactory的实例.每一个MyBatis的应用程序都以一个SqlSessionFactory对象的实例为核心.同时SqlSessionFactory也是线程安全的,SqlSessionFactory一旦被创建,
应该在应用执行期间都存在.在应用运行期间不要重复创建多次,建议使用单例模式.SqlSessionFactory是创建SqlSession的工厂.
7.3通过工厂获取连接 (SqlSession)
通过Resources.getResourceAsStream(“文件位置/文件名”)
7.4通过连接对象获取接口实现类对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
7.5执行方法
public class MybatisTest {
@Test
public void test1(){
try {
//1.获取读取mybatis配置文件的流对象
//Resources.getResourceAsStream加载资源
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
//2.构建sqlsession连接工厂 build编译 java -> class
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
/*
* SqlSessionFactory是MyBatis的关键对象,它是个单个数据库映射关系经过编译后的内存镜像.SqlSessionFactory对象的实例可以通过SqlSessionFactoryBuilder对象类获得,
* 而SqlSessionFactoryBuilder则可以从XML配置文件或一个预先定制的Configuration的实例构建出SqlSessionFactory的实例.
* 每一个MyBatis的应用程序都以一个SqlSessionFactory对象的实例为核心.同时SqlSessionFactory也是线程安全的,SqlSessionFactory一旦被创建,
* 应该在应用执行期间都存在.在应用运行期间不要重复创建多次,建议使用单例模式.SqlSessionFactory是创建SqlSession的工厂.
* */
//3.通过工厂获取连接
SqlSession sqlSession = sqlSessionFactory.openSession();
//4.通过连接对象获取接口实现类对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.selectIdUser(3,null,null,null);
user.toString();
// System.out.println(sqlSession.getMapper(BookMapper.class).selectAllBook().toString());
//5.调用接口中的方法
} catch (IOException e) {
e.printStackTrace();
}
}
}
mybatis其实都是通过JDK的动态代理来实现,getMapper返回的即一个代理对象,通常在写动态代理时,代理对象处理完成后还有调用被代理对象的对应方法,而像Mybatis这种面向接口的思想,没有被代理的对象,所以,Mybatis通过自己一系列操作后直接返回。
整体的步骤就是这样,希望我们能够共同努力!!!!