java ee使用_JavaEE Mybatis使用

本文详细介绍了Mybatis框架的使用,从SqlMapConfig.xml的全局配置到SqlMap的结构,再到数据库表的导入与数据操作。通过创建Java工程,配置SqlMapConfig.xml和user.xml,展示了如何进行用户信息的查询、插入、删除和更新操作,强调了#{}与${}的区别以及事务管理的重要性。此外,还对比了Mybatis与Hibernate的适用场景。
摘要由CSDN通过智能技术生成

下载地址

解压之后的内容:

8fc176b2e13b

图1.png

Mybatis框架结构:

8fc176b2e13b

图2.png

简要概述:

SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句,此文件需要在SqlMapConfig.xml中加载。

通过mybatis环境等配置信息构造SqlSessionFactory(即会话工厂)。

由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。

mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。

MappedStatement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个MappedStatement对象,sql的id即是MappedStatement的id。

MappedStatement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过MappedStatement在执行sql前将输入的java对象映射至sql中,输入参数映射就是JDBC编程中对preparedStatement设置参数。

MappedStatement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过MappedStatement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于JDBC编程中对结果的解析处理过程。

2. 导入数据库表

1). 使用Navicat工具,在root上右键选择新建数据库

8fc176b2e13b

图3.png

2). 新建数据库->确定

8fc176b2e13b

图4.png

3). 打开数据库mybatis->在mybatis/表处单击右键选择运行SQL文件...

8fc176b2e13b

图5.png

4). 选择桌面的sql文件->点击开始

8fc176b2e13b

图6.png

mybatis.sql文件内容

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------

-- Table structure for `orders`

-- ----------------------------

DROP TABLE IF EXISTS `orders`;

CREATE TABLE `orders` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`user_id` int(11) NOT NULL COMMENT '下单用户id',

`number` varchar(32) NOT NULL COMMENT '订单号',

`createtime` datetime NOT NULL COMMENT '创建订单时间',

`note` varchar(100) DEFAULT NULL COMMENT '备注',

PRIMARY KEY (`id`),

KEY `FK_orders_1` (`user_id`),

CONSTRAINT `FK_orders_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION

) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

-- ----------------------------

-- Records of orders

-- ----------------------------

INSERT INTO `orders` VALUES ('3', '1', '1000010', '2015-02-04 13:22:35', null);

INSERT INTO `orders` VALUES ('4', '1', '1000011', '2015-02-03 13:22:41', null);

INSERT INTO `orders` VALUES ('5', '10', '1000012', '2015-02-12 16:13:23', null);

-- ----------------------------

-- Table structure for `user`

-- ----------------------------

DROP TABLE IF EXISTS `user`;

CREATE TABLE `user` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`username` varchar(32) NOT NULL COMMENT '用户名称',

`birthday` date DEFAULT NULL COMMENT '生日',

`sex` char(1) DEFAULT NULL COMMENT '性别',

`address` varchar(256) DEFAULT NULL COMMENT '地址',

PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;

-- ----------------------------

-- Records of user

-- ----------------------------

INSERT INTO `user` VALUES ('1', '王五', null, '2', null);

INSERT INTO `user` VALUES ('10', '张三', '2014-07-10', '1', '北京市');

INSERT INTO `user` VALUES ('16', '张小明', null, '1', '河南郑州');

INSERT INTO `user` VALUES ('22', '陈小明', null, '1', '河南郑州');

INSERT INTO `user` VALUES ('24', '张三丰', null, '1', '河南郑州');

INSERT INTO `user` VALUES ('25', '陈小明', null, '1', '河南郑州');

INSERT INTO `user` VALUES ('26', '王五', null, null, null);

5). 导入成功后,刷新表,数据如下:

8fc176b2e13b

图7.png

3. 测试

1). 创建新的Java工程,并导入Mybatis使用的java包,注意要导入对应的数据库驱动包(这里导入的是mysql-connector-java-5.1.42-bin.jar)

8fc176b2e13b

图7.png

2). 在工程目录下创建一个源码包config,并在config包下创建sqlmap包、log4j.properties和SqlMapConfig.xml文件。

8fc176b2e13b

图8.png

log4j.properties文件内容

# Global logging configuration

log4j.rootLogger=DEBUG, stdout

# Console output...

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

SqlMapConfig.xml文件内容

SqlMapConfig.xml是mybatis的核心配置文件,以上文件的配置内容为数据源、事务管理。

注意:等后面mybatis和Spring两个框架整合之后,environments的配置将被废除.

3). 创建一个po类--User

po类作为mybatis进行sql映射使用,po类通常与数据库表对应,User.java文件的内容如下:

public class User {

// id

private int id;

// 用户名

private String username;

// 性别

private String sex;

// 用户名

private Date birthday;

// 地址

private String address;

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getUsername() {

return username;

}

public void setUsername(String username) {

this.username = username;

}

public String getSex() {

return sex;

}

public void setSex(String sex) {

this.sex = sex;

}

public Date getBirthday() {

return birthday;

}

public void setBirthday(Date birthday) {

this.birthday = birthday;

}

public String getAddress() {

return address;

}

public void setAddress(String address) {

this.address = address;

}

@Override

public String toString() {

return "User [id=" + id + ", username=" + username + ", sex=" + sex + ", birthday=" + birthday + ", address="

+ address + "]";

}

}

4). 在classpath下的sqlmap目录下创建sql映射文件user.xml

user.xml内容如下:

namespace:即命名空间,其用于隔离sql语句(即不同sql映射文件中的两个相同id的sql语句如何来区分)

5). 加载映射文件

mybatis框架需要加载映射文件,将user.xml添加在SqlMapConfig.xml中.

在SqlMapConfig.xml配置文件中添加配置信息:

6). 入门程序测试——根据id查询用户信息

I. user.xml映射文件中添加如下配置:

select * from user where id = #{id};

II. 编写MybatisTest类

public class MybatisTest {

@Test

public void testGetUserById() throws IOException {

// 1. 创建SqlSessionFactoryBuilder对象

SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();

// 2. 加载配置文件

InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");

// 3. 创建SqlSessionFactory对象

SqlSessionFactory factory = builder.build(inputStream);

// 4. 创建SqlSession对象

SqlSession sqlSession = factory.openSession();

// 5. 使用SqlSession对象执行查询,得到User对象

// 第一个参数: 执行查询的StatementId,即配置文件user.xml中的id, 第二参数传入id对应的值

User user = sqlSession.selectOne("getUserById", 10);

// 6. 打印结果

System.out.println(user);

// 7. 释放资源

sqlSession.close();

}

}

III. 执行测试代码, 打印结果:

8fc176b2e13b

图9.png

IV. 优化代码

一般来讲工厂对象一般在实际开发是单例的,并不需要频繁地创建

public class MybatisTest {

private SqlSessionFactory factory;

@Before

public void init() throws IOException {

// 1. 创建SqlSessionFactoryBuilder对象

SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();

// 2. 加载配置文件

InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");

// 3. 创建SqlSessionFactory对象

factory = builder.build(inputStream);

}

@Test

public void testGetUserById() {

// 4. 创建SqlSession对象

SqlSession sqlSession = factory.openSession();

// 5. 使用SqlSession对象执行查询,得到User对象

// 第一个参数: 执行查询的StatementId,即配置文件user.xml中的id, 第二参数传入id对应的值

User user = sqlSession.selectOne("getUserById", 10);

// 6. 打印结果

System.out.println(user);

// 7. 释放资源

sqlSession.close();

}

}

7). 根据用户名称模糊查询用户信息列表

I. user.xml文件添加

select * from user where username like #{username}

II. 编写测试方法

public class MybatisTest {

private SqlSessionFactory factory;

@Before

public void init() throws IOException {

// 1. 创建SqlSessionFactoryBuilder对象

SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();

// 2. 加载配置文件

InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");

// 3. 创建SqlSessionFactory对象

factory = builder.build(inputStream);

}

@Test

public void testGetUserByName() {

SqlSession session = factory.openSession();

List list = session.selectList("getUserByName", "%张%");

for (User user : list) {

System.out.println(user.toString());

}

session.close();

}

}

III. 执行测试方法,打印结果:

8fc176b2e13b

图10.png

IV. 另一个中不建议使用的占位符方式

select * from user where username like '%${value}%'

测试代码:

public class MybatisTest {

private SqlSessionFactory factory;

@Before

public void init() throws IOException {

// 1. 创建SqlSessionFactoryBuilder对象

SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();

// 2. 加载配置文件

InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");

// 3. 创建SqlSessionFactory对象

factory = builder.build(inputStream);

}

@Test

public void testGetUserByName1() {

SqlSession session = factory.openSession();

List list = session.selectList("getUserByName1", "张");

for (User user : list) {

System.out.println(user.toString());

}

session.close();

}

}

8fc176b2e13b

图11.png

不推荐使用:原因容易引起SQL注入。

总结

---{}和${}

1). #{}:表示一个占位符号,可以很好地去避免sql注入。其原理是将占位符位置的整个参数和sql语句两部分提交给数据库,数据库去执行sql语句,去表中匹配所有的记录是否和整个参数是否一致。

#{}要获取输入参数的值:

如果输入参数是简单数据类型,则#{}中可以写value或其它名称。

如果输入参数是pojo对象类型,则#{}可通过OGNL方式去获取,表达式就是属性.属性.属性....方式。

2). ${}表示一个sql拼接符号,其原理是在向数据库发出sql之前去拼接好sql再提交给数据库执行。

${}要获取输入参数的值:

如果输入参数是简单数据类型,则${}中只能写value。

如果输入参数是pojo对象类型,则${}可通过OGNL方式去获取,表达式就是属性.属性.属性....方式。

一般情况下建议使用#{},特殊情况下必须要用${},比如:

1>. 动态拼接sql中动态组成排序字段,要通过${}将排序字段传入sql中。

2>. 动态拼接sql中动态组成表名,要通过${}将表名传入sql中。

---parameterType和resultType

parameterType:指定输入参数类型,mybatis通过ognl从输入对象中获取参数值拼接在sql中。

resultType:指定输出结果类型,mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象。

---selectOne()和selectList()方法

selectOne查询一条记录,如果使用selectOne查询多条记录则抛出异常.

selectList可以查询一条或多条记录。

4. 其他操作

1). 插入数据

I. user.xml添加配置

insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})

如果输入参数是pojo,那么#{}中的名称就是pojo类中的属性(用到了对象图导航的思想)

II. 编写测试代码

public class MybatisTest {

private SqlSessionFactory factory;

@Before

public void init() throws IOException {

// 1. 创建SqlSessionFactoryBuilder对象

SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();

// 2. 加载配置文件

InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");

// 3. 创建SqlSessionFactory对象

factory = builder.build(inputStream);

}

@Test

public void testAddUser() {

// 创建Session对象

SqlSession session = factory.openSession();

// 创建对象

User user = new User();

user.setUsername("mazaiting");

user.setBirthday(new Date());

user.setSex("男");

user.setAddress("科学院");

// 插入数据

session.insert("addUser", user);

// 关闭Session

session.close();

}

}

III. 执行测试代码,打印结果:

可以看出虽然执行了sql语句,但是事务并没有提交,而是回滚了。

8fc176b2e13b

图12.png

IV. 因此,应将测试代码修改为

public class MybatisTest {

private SqlSessionFactory factory;

@Before

public void init() throws IOException {

// 1. 创建SqlSessionFactoryBuilder对象

SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();

// 2. 加载配置文件

InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");

// 3. 创建SqlSessionFactory对象

factory = builder.build(inputStream);

}

@Test

public void testAddUser() {

// 创建Session对象

SqlSession session = factory.openSession();

// 创建对象

User user = new User();

user.setUsername("mazaiting");

user.setBirthday(new Date());

user.setSex("男");

user.setAddress("科学院");

// 插入数据

session.insert("addUser", user);

// 提交事务

session.commit();

// 关闭Session

session.close();

}

}

V. 执行单元测试,打印结果:

8fc176b2e13b

图13.png

2). 自增主键返回

LAST_INSERT_ID():返回auto_increment自增列新记录id值。该函数是在当前事务下取到你最后生成的id值,而我们应知道查询操作是没有开启事务的,增删改操作是需要开启事务的。

I. 在user.xml中添加配置

select LAST_INSERT_ID()

insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})

keyProperty:返回的主键存储在pojo中的哪个属性(即其对应pojo的主键属性)。获取主键,实际上是将主键取出来之后封装到了pojo的主键属性当中。

resultType:返回的主键是什么类型(即其对应pojo的主键的数据类型)。

order:selectKey的执行顺序,是相对于insert语句来说的,由于mysql的自增原理,执行完insert语句之后才将主键生成,所以这里selectKey的执行顺序为AFTER。

II. 添加测试代码

public class MybatisTest {

private SqlSessionFactory factory;

@Before

public void init() throws IOException {

// 1. 创建SqlSessionFactoryBuilder对象

SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();

// 2. 加载配置文件

InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");

// 3. 创建SqlSessionFactory对象

factory = builder.build(inputStream);

}

@Test

public void testAddUser1() {

// 创建Session对象

SqlSession session = factory.openSession();

// 创建对象

User user = new User();

user.setUsername("mazaiting");

user.setBirthday(new Date());

user.setSex("男");

user.setAddress("科学院");

// 插入数据

session.insert("addUser1", user);

System.out.println("插入的id:" + user.getId());

// 提交事务

session.commit();

// 关闭Session

session.close();

}

}

III. 执行测试代码,打印结果:

8fc176b2e13b

图14.png

3). 删除用户

I. user.xml中添加删除语句

delete from user where id = #{id}

II. 测试代码

public class MybatisTest {

private SqlSessionFactory factory;

@Before

public void init() throws IOException {

// 1. 创建SqlSessionFactoryBuilder对象

SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();

// 2. 加载配置文件

InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");

// 3. 创建SqlSessionFactory对象

factory = builder.build(inputStream);

}

@Test

public void testDeleteUser() {

// 创建会话

SqlSession session = factory.openSession();

// 删除数据

session.delete("deleteUser", 29);

// 提交事务

session.commit();

// 关闭会话

session.close();

}

}

III. 打印结果:

8fc176b2e13b

图15.png

4). 更新数据

I. user.xml添加配置

update user set username = #{username} where id = #{id}

II. 测试代码

public class MybatisTest {

private SqlSessionFactory factory;

@Before

public void init() throws IOException {

// 1. 创建SqlSessionFactoryBuilder对象

SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();

// 2. 加载配置文件

InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");

// 3. 创建SqlSessionFactory对象

factory = builder.build(inputStream);

}

public void testUpdateUser(){

// 创建会话

SqlSession session = factory.openSession();

User user = new User();

user.setId(10);

user.setUsername("张某某");

// 更新数据

session.update("updateUser", user);

// 提交事务

session.commit();

// 关闭会话

session.close();

}

}

III. 打印结果:

8fc176b2e13b

图16.png

5. Mybatis与Hibernate不同

MyBatis学习成本低,入门门槛低。MyBatis需要程序员自己写sql,对sql修改和优化就比较灵活。MyBatis是不完全的ORM框架,MyBatis需要程序员编写sql,但是MyBatis也存在映射(输入映射、输出映射)适用场景:需求变化较快的项目开发,比如互联网项目、电商。

Hibernate学习成本高,入门门槛高,Hibernate是ORM框架,不需要程序员编写sql,自动根据对象映射生成sql。适用场景:需求固定的中小型项目,如OA系统、ERP系统。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值