目录
- 总结jdbc出现的问题
- mybatis介绍
- mybatis入门程序
- 占位符#{}与字符串拼接符${}区别
- mybatis框架的原理
- 别名配置与映射文件加载方式
- mybatis与hibernate的比较
一、总结jdbc出现的问题
1、准备数据库,执行mysql语句。
-
-- ----------------------------
-
-- 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_order_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=
35
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);
2、创建工程
3、配置pom.xml文件,加入数据库依赖驱动
-
<project xmlns="http://maven.apache.org/POM/4.0.0"
-
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
-
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
<modelVersion>4.0.0
</modelVersion>
-
<groupId>com.liwei
</groupId>
-
<artifactId>mybatis01
</artifactId>
-
<version>0.0.1-SNAPSHOT
</version>
-
<properties>
-
<project.build.sourceEncoding>UTF-8
</project.build.sourceEncoding>
-
<!-- mysql版本 -->
-
<mysql.version>5.1.30
</mysql.version>
-
<!-- junit版本 -->
-
<junit.version>4.12
</junit.version>
-
</properties>
-
-
<dependencies>
-
<!-- mysql数据库依赖 -->
-
<dependency>
-
<groupId>mysql
</groupId>
-
<artifactId>mysql-connector-java
</artifactId>
-
<version>${mysql.version}
</version>
-
</dependency>
-
<!-- junit依赖 -->
-
<dependency>
-
<groupId>junit
</groupId>
-
<artifactId>junit
</artifactId>
-
<version>${junit.version}
</version>
-
<scope>test
</scope>
-
</dependency>
-
</dependencies>
-
-
</project>
4、编写代码
-
package com.liwei.jdbc;
-
-
import java.sql.Connection;
-
import java.sql.DriverManager;
-
import java.sql.PreparedStatement;
-
import java.sql.ResultSet;
-
-
/**
-
* @ClassName: JdbcTest
-
* @Description:jdbc问题总结
-
* @author: Li_Wei
-
* @date: 2018年6月27日 上午10:13:52
-
*/
-
public
class JdbcTest {
-
-
public static void main(String[] args) {
-
Connection con =
null;
-
PreparedStatement psmt =
null;
-
ResultSet set =
null;
-
try {
-
// 1.加载驱动
-
Class.forName(
"com.mysql.jdbc.Driver");
-
// 2.创建数据库的连接对象
-
con = DriverManager.getConnection(
"jdbc:mysql://127.0.0.1:3306/liwei",
"root",
"root");
-
// 3.定义sql语句
-
String sql =
"select * from user where id = ?";
-
// 4.创建statement对象
-
psmt = con.prepareStatement(sql);
-
// 5.设置参数
-
psmt.setInt(
1,
1);
-
// 6.执行
-
set = psmt.executeQuery();
-
// 7.处理结果集
-
while (set.next()) {
-
System.out.println(
"用户Id:" + set.getInt(
"id") +
",用户名称:" + set.getString(
"username"));
-
}
-
}
catch (Exception e) {
-
e.printStackTrace();
-
}
finally {
-
try {
-
//8.释放资源
-
if (set !=
null)set.close();
-
if (psmt !=
null)psmt.close();
-
if (con !=
null)con.close();
-
}
catch (Exception e) {
-
e.printStackTrace();
-
}
-
}
-
-
}
-
-
}
5、测试结果
6、总结jdbc开发出现的问题
- 频繁创建数据库连接对象、释放、容易造成系统资源浪费,影响系统性能。企业项目中可以使用连接池解决这个问题,但是使用Jdbc需要自己实现连接池。mybatis框架已经提供连接池。
- sql语句定义、参数设置、结果集处理存在硬编码。企业项目中sql语句变化的可能性较大,一旦发生变化,需要修改java代码,系统需要重新编译,重新发布。不好维护。
- 结果集处理存在重复代码,处理麻烦。如果可以映射成为java对象会比较方便。
二、mybatis介绍
mybatis是Apache软件基金会下的一个开源项目,前身是Ibatis框架。2010年这个项目由apache 软件基金会迁移到google code下,改名为mybatis。2013年11月又迁移到了github(https://github.com/mybatis/mybatis-3/releases)。
mybatis是一个持久层的框架,是对JDBC操作数据库的封装,使开发者只需要关注业务本身,不需要花费精力去处理加载驱动、创建数据库连接对象、创建statement语句对象、参数设置、结果集处理等一系列繁杂的过程代码。
mybatis通过xml或注解进行配置,将java对象与sql语句中的参数自动映射生成最终执行的sql语句,并将sql语句执行结果自动映射成java对象,返回给业务层(service)应用。
三、mybatis的入门程序
需求:实现用户表(user)增、删、改、查操作。
1、配置pom.xml文件
-
<project xmlns="http://maven.apache.org/POM/4.0.0"
-
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
-
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
<modelVersion>4.0.0
</modelVersion>
-
<groupId>com.liwei
</groupId>
-
<artifactId>mybatis01
</artifactId>
-
<version>0.0.1-SNAPSHOT
</version>
-
<properties>
-
<project.build.sourceEncoding>UTF-8
</project.build.sourceEncoding>
-
<!-- mysql版本 -->
-
<mysql.version>5.1.30
</mysql.version>
-
<!-- junit版本 -->
-
<junit.version>4.12
</junit.version>
-
<!-- mybatis版本号 -->
-
<mybatis.version>3.4.5
</mybatis.version>
-
<!-- log4j日志包版本 -->
-
<slf4j.version>1.7.7
</slf4j.version>
-
<log4j.version>1.2.17
</log4j.version>
-
</properties>
-
-
<dependencies>
-
<!-- mysql数据库依赖 -->
-
<dependency>
-
<groupId>mysql
</groupId>
-
<artifactId>mysql-connector-java
</artifactId>
-
<version>${mysql.version}
</version>
-
</dependency>
-
<!-- mybatis核心包 -->
-
<dependency>
-
<groupId>org.mybatis
</groupId>
-
<artifactId>mybatis
</artifactId>
-
<version>${mybatis.version}
</version>
-
</dependency>
-
<!-- log4j日志包 -->
-
<dependency>
-
<groupId>log4j
</groupId>
-
<artifactId>log4j
</artifactId>
-
<version>${log4j.version}
</version>
-
</dependency>
-
<dependency>
-
<groupId>org.slf4j
</groupId>
-
<artifactId>slf4j-api
</artifactId>
-
<version>${slf4j.version}
</version>
-
</dependency>
-
<dependency>
-
<groupId>org.slf4j
</groupId>
-
<artifactId>slf4j-log4j12
</artifactId>
-
<version>${slf4j.version}
</version>
-
</dependency>
-
-
<!-- junit依赖 -->
-
<dependency>
-
<groupId>junit
</groupId>
-
<artifactId>junit
</artifactId>
-
<version>${junit.version}
</version>
-
<scope>test
</scope>
-
</dependency>
-
</dependencies>
-
-
</project>
2、sqlMapConfig.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>
-
<!-- 运行环境配置 -->
-
<!--default属性:指定使用哪一个运行环境 -->
-
<environments default="development">
-
<!--id属性:唯一标识一个运行环境 -->
-
<environment id="development">
-
<!-- 事务管理器配置,type="JDBC":mybatis框架默认使用jdbc事务 -->
-
<transactionManager type="JDBC" />
-
<!--数据源配置,type="POOLED":mybatis框架提供的连接池 -->
-
<dataSource type="POOLED">
-
<property name="driver" value="com.mysql.jdbc.Driver" />
-
<property name="url" value="jdbc:mysql://127.0.0.1:3306/liwei" />
-
<property name="username" value="root" />
-
<property name="password" value="root" />
-
</dataSource>
-
</environment>
-
</environments>
-
<!-- 加载映射文件 -->
-
<mappers>
-
<mapper resource="mybatis/UserMapper.xml"/>
-
</mappers>
-
</configuration>
3、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
4、实体类User.java文件
-
package com.liwei.mybatis.domain;
-
-
import java.util.Date;
-
-
public
class User {
-
private Integer id;
// 主键id
-
private String username;
// 用户名称
-
private Date birthday;
// 生日
-
private String sex;
// 性别
-
private String address;
// 地址
-
-
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 Date getBirthday() {
-
return birthday;
-
}
-
public void setBirthday(Date birthday) {
-
this.birthday = birthday;
-
}
-
public String getSex() {
-
return sex;
-
}
-
public void setSex(String sex) {
-
this.sex = sex;
-
}
-
public String getAddress() {
-
return address;
-
}
-
public void setAddress(String address) {
-
this.address = address;
-
}
-
@Override
-
public String toString() {
-
return
"User [id=" + id +
", username=" + username +
", birthday=" + birthday +
", sex=" + sex +
", address="
-
+ address +
"]";
-
}
-
-
-
}
5、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="mybatis">
-
<!-- 新增用户 -->
-
<insert id="addUser" parameterType="com.liwei.mybatis.domain.User">
-
insert into user (id,username,birthday,sex,address)
-
values (#{id},#{username},#{birthday},#{sex},#{address})
-
</insert>
-
-
<!-- 根据用户id删除用户 -->
-
<delete id="deleteUser" parameterType="int">
-
delete from user where id = #{id}
-
</delete>
-
-
<!-- 根据用户id修改用户 -->
-
<update id="updateUserById" parameterType="com.liwei.mybatis.domain.User">
-
update user set username=#{username},sex=#{sex} where id=#{id}
-
</update>
-
-
<!-- 根据id查询 -->
-
<select id="queryUserById" parameterType="int" resultType="com.liwei.mybatis.domain.User">
-
select id,username,birthday,sex,address from user where id = #{id}
-
</select>
-
-
<!-- 方式一:根据用户名称模糊查询用户 -->
-
<select id="queryUserByName1" parameterType="string" resultType="com.liwei.mybatis.domain.User">
-
select id,username,birthday,sex,address from `user` where username like #{username}
-
</select>
-
-
<!-- 方式二:根据用户名称模糊查询用户 -->
-
<select id="queryUserByName2" parameterType="string" resultType="com.liwei.mybatis.domain.User">
-
select id,username,birthday,sex,address from `user` where username like '%${value}%'
-
</select>
-
-
</mapper>
6、MyBatisTest测试类
-
package com.liwei.mybatis.test;
-
-
import java.io.IOException;
-
import java.io.InputStream;
-
import java.util.Date;
-
import java.util.List;
-
-
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;
-
-
import com.liwei.mybatis.domain.User;
-
-
public
class MyBatisTest {
-
/**
-
* @Title: getSqlSessionFactory
-
* @Description: 将增、删、改、查公共使用的部分提出来
-
* @param: @return
-
* @param: @throws
-
* IOException
-
* @return: SqlSession
-
* @throws @author
-
* Li_Wei
-
*/
-
public SqlSessionFactory getSqlSessionFactory() throws IOException {
-
// 1.加载核心配置文件
-
InputStream inputStream = Resources.getResourceAsStream(
"sqlMapConfig.xml");
-
// 2.读取配置文件的内容
-
SqlSessionFactoryBuilder builder =
new SqlSessionFactoryBuilder();
-
SqlSessionFactory sqlSessionFactory = builder.build(inputStream);
-
-
return sqlSessionFactory;
-
}
-
-
/**
-
* @Title: addUser
-
* @Description: 新增用户
-
* @param:
-
* @return: void
-
* @throws IOException
-
* @throws @author
-
* Li_Wei
-
*/
-
@Test
-
public void addUser() throws IOException {
-
// 3.使用sqlSessionFactory对象,创建SqlSession对象,开启自动提交事务
-
SqlSession sqlSession =
this.getSqlSessionFactory().openSession(
true);
-
// 调用方法执行
-
User user =
new User();
-
user.setId(
4);
-
user.setUsername(
"林诗音");
-
user.setBirthday(
new Date());
-
user.setSex(
"女");
-
user.setAddress(
"来自大明朝");
-
sqlSession.insert(
"mybatis.addUser", user);
-
// 事务提交
-
// sqlSession.commit();
-
// 释放资源
-
sqlSession.close();
-
}
-
-
/**
-
* @Title: deleteUser
-
* @Description: 根据用户id删除用户
-
* @param:
-
* @return: void
-
* @throws IOException
-
* @throws @author
-
* Li_Wei
-
*/
-
@Test
-
public void deleteUser() throws IOException {
-
// 创建SqlSession对象
-
SqlSession sqlSession =
this.getSqlSessionFactory().openSession(
true);
-
// 调用方法执行
-
sqlSession.delete(
"mybatis.deleteUser",
3);
-
// 释放资源
-
sqlSession.close();
-
}
-
-
/**
-
* @Title: updateUser
-
* @Description: 根据用户id修改用户
-
* @param:
-
* @return: void
-
* @throws IOException
-
* @throws @author
-
* Li_Wei
-
*/
-
@Test
-
public void updateUserById() throws IOException {
-
// 创建SqlSession对象
-
SqlSession sqlSession =
this.getSqlSessionFactory().openSession(
true);
-
// 调用方法执行
-
// 创建用户对象
-
User user =
new User();
-
user.setId(
1);
-
user.setUsername(
"林诗音和小李飞刀");
-
user.setSex(
"1");
-
-
sqlSession.update(
"mybatis.updateUserById", user);
-
// 释放资源
-
sqlSession.close();
-
}
-
-
/**
-
* @Title: queryUserById
-
* @Description: 根据id查询用户(查询)
-
* @param:
-
* @return: void
-
* @throws IOException
-
* @throws @author
-
* Li_Wei
-
*/
-
@Test
-
public void queryUserById() throws IOException {
-
// 3.使用sqlSessionFactory对象,创建SqlSession对象
-
SqlSession sqlSession =
this.getSqlSessionFactory().openSession();
-
// 4.使用sqlSession对象,调用方法执行
-
Object user = sqlSession.selectOne(
"mybatis.queryUserById",
24);
-
System.out.println(user);
-
// 5.释放资源
-
sqlSession.close();
-
}
-
-
/**
-
* @Title: queryUserNameLike
-
* @Description: 方式一:根据用户名称模糊查询用户
-
* @param:
-
* @return: void
-
* @throws IOException
-
* @throws @author
-
* Li_Wei
-
*/
-
@Test
-
public void queryUserByName1() throws IOException {
-
// 3.使用sqlSessionFactory对象,创建SqlSession对象
-
SqlSession sqlSession =
this.getSqlSessionFactory().openSession();
-
// 4.使用sqlSession对象,调用方法执行
-
List<Object> userList = sqlSession.selectList(
"mybatis.queryUserByName1",
"%小明%");
-
for (Object object : userList) {
-
System.out.println(object);
-
}
-
// 5.释放资源
-
sqlSession.close();
-
}
-
-
/**
-
* @Title: queryUserNameLike
-
* @Description: 根据用户名称模糊查询用户
-
* @param:
-
* @return: void
-
* @throws IOException
-
* @throws @author
-
* Li_Wei
-
*/
-
@Test
-
public void queryUserByName2() throws IOException {
-
// 3.使用sqlSessionFactory对象,创建SqlSession对象
-
SqlSession sqlSession =
this.getSqlSessionFactory().openSession();
-
// 4.使用sqlSession对象,调用方法执行
-
List<Object> userList = sqlSession.selectList(
"mybatis.queryUserByName2",
"小明");
-
for (Object object : userList) {
-
System.out.println(object);
-
}
-
// 5.释放资源
-
sqlSession.close();
-
}
-
}
7、打印结果如下
新增用户:
删除:根据用户id删除用户
修改:根据用户id修改用户
查询:根据id查询
根据用户名称模糊查询:
方式一:使用#{}
方式二:使用${}
方式一与方式二具体看上面的代码。
在方式一与方式二中,我们使用到了#{}与${}两种方式,name这两种方式用什么区别呢?
四、占位符#{}与字符串拼接符${}区别
- 占位符#{},相当于jdbc中的问号?,当参数类型传递的是java简单类型的时候,花括号中的内容可以是任意字符串。
- 字符串拼接符${},当参数传递的是java简单类型的时候,花括号中的内容只能是:value
- sql语句中使用字符串拼接,可能引起sql注入的问题。但是mybatis框架中字符串拼接符可以放心使用。原因是mybatis是后端dao层开发,参数在前端表现层(action)和业务层(service)已经处理好。
五、mybatis框架的原理
六、别名配置与映射文件加载方式
别名有两种方式:
映射文件加载:两种方法
注意:包扫描需要将映射文件放在相应的包下面
七、mybatis与hibernate的比较
相同点
都是对jdbc的封装,都是持久层的框架,都用于dao层的开发。
不同点
- hibernate对sql语句做了封装,提供了HQL语句操作数据库,数据库无关性支持好,在项目需要支持多种数据库的情况下,代码开发量较少,sql语句优化困难。mybaits是直接使用sql语句操作数据库,不支持数据库无关性,在项目需要支持多种数据库的情况下,代码开发量较多,sql语句优化容易。
- hibernate配置java对象与数据库表的对应关系,多表关联关系配置复杂。mybatis是配置java对象与sql语句的对应关系,多表关联关系配置简单。
- hibernate是一个重量级的框架,学习使用门槛高,适合于需求相对稳定,中小型的项目,比如:办公自动化系统(OA)。mybatis是一个轻量级的框架,学习使用门槛低,适合于需求变化频繁,大型的项目,比如:互联网项目。目前企业项目中,mybatis框架使用更多。