MyBatis入门
MyBatis是一个第一类持久性框架,支持自定义SQL,存储过程和高级映射。MyBatis几乎消除了所有JDBC代码和手动设置参数以及检索结果。MyBatis可以使用简单的XML或Annotations来配置和映射基元,Map接口和Java POJO(Plain Old Java Objects)到数据库记录。
优势
-
简化了JDBC的开发
-
能够更好的完成ORM(对象关系映射)
1.Mybatis原理图
#### 2.准备环境
(1)创建mybatisdb数据库,创建user表
Create database mybatisdb;
Use mybatisdb;
Create table user(
id int primary key auto_increment,
name varchar(100),
addr varchar(100),
age int);
Insert into user values(null,'guangtouqiang','北京',28);
Insert into user values(null,'xiongda','上海',30);
Insert into user values(null,'xiaonger','上海',19);
(2)编译器引入dtd文件
dtd2.jpg 引入dtd.png作为xml的约束文件,没连网的情况下也可以在编写xml时可以出现提示信息。
3.MyBatis入门案例( 从XML构建SqlSessionFactory)
(1)需求
利用MyBatis框架查询user表中的所有数据
(2)创建mybatisDemo的Java工程,并导入jar包
(3)创建sqlMapConfig.xml
<?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>
<!-- 配置MyBatis开发环境 -->
<environments default="test">
<!-- 测试环境 -->
<environment id="test">
<!-- MyBatis事务交给JDBC管理 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置数据源(连接池) -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatisdb"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
<!-- 开发环境 -->
</environments>
<!-- 引入映射文件 -->
<mappers>
<!-- 引入UserMapper.xml -->
<mapper resource="com/znonline/pojo/UserMapper.xml"/>
</mappers>
</configuration>
(4)创建log4j.properties
用来打印日志文件(SQL语句),可以很清楚的看到执行的sql和执行sql使用的参数。
# 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
(5)创建pojo对象
POJO对象的属性名字要和数据库表字段的名字保持一致否则无法封装结果集
package com.znonline.pojo;
/**
* User表
*/
public class User {
// id
private int id;
// 用户名
private String name;
// 地址
private String addr;
// 年龄
private int age;
public User() {
}
public User(int id, String name, String addr, int age) {
this.id = id;
this.name = name;
this.addr = addr;
this.age = age;
}
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 getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", addr=" + addr + ", age=" + age + "]";
}
}
(6) 创建映射文件UserMapper.xml
在User类的同级包下,创建UserMapper.xml,代表这个文件是User对象的映射文件
<?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">
<!-- 映射文件
namespace是该文件的唯一标识
-->
<mapper namespace="userns">
<!-- 用来查询的SQL,
id是该SQL的唯一标识 ,resultType是结果集要封装的实体(类的全路径)-->
<select id="all" resultType="com.znonline.pojo.User">
select * from user
</select>
</mapper>
(7) sqlMapConfig.xml中引入UserMapper.xml
上面已引入
(8)创建UserTest类
package com.znonline.test;
import java.io.IOException;
import java.io.InputStream;
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.znonline.pojo.User;
/**
* 测试User
* @author zn
*/
public class UserTest {
@Test
public void FindUserAll() throws IOException {
//1.创建会话工厂
InputStream in = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(in);
//2.创建Sqlsession,执行SQL
SqlSession session = ssf.openSession();
//定位SQL位置 (namespace值.id值)
List list = session.selectList("userns.all");
//3.处理结果集
for(User u:list) {
System.out.println(u);
}
//4.释放资源
session.close();
}
}
mybatisDemo演示.png
4.综合案例 - Maven工程
实现User表的CRUD
(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.znonline</groupId>
<artifactId>mybatisDemoV2.0</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!--添加mysql驱动程序依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.40</version>
</dependency>
<!--整合junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<!--整合mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.8</version>
</dependency>
<!--整合log4j日志 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
<build>
<plugins>
<!--配置JDK1.7 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
(2).创建sqlMapConfig.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.znonline</groupId>
<artifactId>mybatisDemoV2.0</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!--添加mysql驱动程序依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.40</version>
</dependency>
<!--整合junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<!--整合mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.8</version>
</dependency>
<!--整合log4j日志 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
<build>
<plugins>
<!--配置JDK1.7 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
(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).创建pojo对象
(5).主体业务
- Select
Map:
<!-- 查询User表中所有数据 -->
<select id="findAll" resultType="zn.online.pojo.User">
select * from user
</select>
<!-- 查询User表总记录数 -->
<select id="count" resultType="int">
select count(*) from user
</select>
<!-- 根据id查询User -->
<select id="findById" resultType="zn.online.pojo.User" parameterType="int">
select * from user where id=#{userId}
</select>
Test:
/**
* User 的CRUD操作
* @author zn
*/
public class UserTest {
// 声明会话工厂,线程安全
SqlSessionFactory ssf = null;
/**
* 测试前初始化步骤
*/
@Before
public void init() {
InputStream in;
try {
//
in = Resources.getResourceAsStream("sqlMapConfig.xml");
ssf = new SqlSessionFactoryBuilder().build(in);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 查询User表中所有数据
*/
@Test
public void findAll() {
SqlSession session = ssf.openSession();
List list = session.selectList("userns.findAll");
// 3.处理结果集
for (User u : list) {
System.out.println(u);
}
session.close();
}
/**
* 查询User表总记录数
*/
@Test
public void count() {
SqlSession session = ssf.openSession();
int count = session.selectOne("userns.count");
System.out.println("User_Table count:"+count);
session.close();
}
/**
* 根据id查询User
*/
@Test
public void findById() {
SqlSession session = ssf.openSession();
int userId = 3;
User user = session.selectOne("userns.findById", userId);
System.out.println(user);
session.close();
}
}
show:
findAll.png Usercount.png
UserfindById.png
- Insert
Map:
<!-- 在User中新增一条记录 -->
<insert id="save" parameterType="zn.online.pojo.User">
insert into user values(null,#{name},#{addr},#{age})
</insert>
Test:
/**
* 在User中新增一条记录
*/
@Test
public void save() {
SqlSession session = ssf.openSession();
User user = new User();
user.setName("lisi");
user.setAddr("上海");
user.setAge(21);
session.insert("userns.save", user);
// MyBatis需要手动提交事务
session.commit();
session.close();
}
Log/show:
UserInsert.png
- Update
Map:
<!-- 修改指定的记录
动态取值: #{age} age是User中对应的属性
-->
<update id="updateAgeByName" parameterType="zn.online.pojo.User">
update user set age=#{age}
where name=#{name}
</update>
Test:
/**
* 修改指定User名字的年龄
*/
@Test
public void updateAgeByName() {
SqlSession session = ssf.openSession();
User user = new User();
user.setAge(25);
user.setName("zhangsan");
session.update("userns.updateAgeByName", user);
session.commit();
session.close();
}
Log/Show:
UserUpdateAgeByName.png
- Delete
Map:
<!-- 按id删除指定User表中的数据 -->
<delete id="deleteById">
delete from user where id=#{id}
</delete>
Test:
/**
* 按id删除指定User表中数据
*/
@Test
public void deleteById() {
SqlSession session = ssf.openSession();
int id = 3;
session.delete("userns.deleteById", id);
session.commit();
session.close();
}
Log/Show:
5.mybatis入门总结
MyBatis的真正力量在于Mapped Statements。这就是魔术发生的地方。尽管功能强大,但Mapper XML文件相对简单。当然,如果您将它们与等效的JDBC代码进行比较,您会立即看到节省了95%的代码。MyBatis专注于SQL,并尽力避开您的方式。
Mapper XML文件只有几个第一类元素(按照它们应该被定义的顺序):
-
cache- 为给定命名空间配置缓存。
-
cache-ref- 从另一个命名空间引用缓存配置。
-
resultMap- 描述如何从数据库结果集加载对象的最复杂和最强大的元素。
-
parameterMap~~~~- 已弃用!老派的方式来映射参数。内联参数是首选,将来可能会删除此元素。这里没有记录。 -
sql- 可重用的SQL块,可以被其他语句引用。
-
insert- 映射的INSERT语句。
-
update- 映射的UPDATE语句。
-
delete- 映射的DELETE语句。
-
select- 映射的SELECT语句。
接下来的部分将详细描述每个元素,从语句本身开始。
1.查询(select)
<figure id="ag-204" class="ag-paragraph">
Map标签 | 相关描述 |
---|---|
id | 作为该SQL的唯一标志 |
paramentType | 代表要执行这个select语句需要传入一个类型为long的参数,即User对象的id |
resultType | 完成ORM的映射关系所在 返回的预期类型的完全限定类名或别名 对于集合,这应该是集合包含的类型,而不是集合本身的类型 |
</figure>
<figure id="ag-232" class="ag-paragraph">
Test查询可以使用的方法 | 相关描述 |
---|---|
selectList | 代表这次调用的select语句查询的结果集会有一条以上的数据 |
selectOne | 返回一条数据,也可以用selectList方法,返回一个指定的数据 |
</figure>
2.新增(Insert)
<figure id="ag-259" class="ag-paragraph">
Map标签 | 相关描述 |
---|---|
id | 作为这条SQL的唯一标志 |
ParameterType | 指定参数类型,通常制定一个对象类型 |
flushCache | 将此设置为true将导致在调用此语句时刷新第2级和本地缓存。 默认值:对于insert,update和delete语句为true。 |
timeout | 这将设置驱动程序在抛出异常之前等待数据库从请求返回的最大秒数。 默认为未设置(取决于驱动程序) |
statementType | STATEMENT,PREPARED或CALLABLE中的任何一个 默认值:PREPARED。 |
</figure>
<figure id="ag-296" class="ag-paragraph">
Test查询可以使用的方法 | 相关描述 |
---|---|
Insert(String statement) | 没有参数的话,直接执行查询的sql即可 |
Insert(Stringstatement,Objectparam) | 需要参数的话,可以传入 |
</figure>
3.修改(update)
4.删除(delete)
6.扩展
1.别名
在sqlMapConfig.xml中,可以使用typeAliases元素来简化开发的操作
2.SQL中有特殊字符
当SQL中有特殊字符<,mybatis不能正常解析时,用<![CDATA[??]]>括起来就解决了
``
3. #和$取值的区别
两种方式都可以获取参数的值。
推荐能用#不用$:
-
{}(推荐!)
1.相当于JDBC中的PreparedStatement,是经过预编译的,是安全的。
2.会为参数自动拼接引号。
3.执行SQL效果:select * from user whereuserId=”1”andpwd=”2”
-
${}:
1.相当于JDBC中的Statement ,未经过预编译,仅仅是取变量的值,是非安全的,存在SQL注入。
2.执行SQL效果:select * from user whereuserId=1andpwd=2
网友评论