1. Mybatis框架的CRUD操作
1.1 实现添加操作
- 以对用户表进行DRUD操作为例
1.1.1 构建环境
1.1.1.1 添加依赖(pom.xml)
<?xml version="1.0" encoding="UTF-8"?>
<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.azure</groupId>
<artifactId>day48projects</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.40</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
</project>
1.1.1.2 主配置文件(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>
<!--数据库环境配置-->
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="pooled">
<property name="driver" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql:///mybatis?characterEncoding=utf8"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</dataSource>
</environment>
</environments>
<!--在此处添加映射文件-->
</configuration>
1.1.1.3 创建实体类
package com.azure.entity;
import java.util.Date;
public class User {
private int id;
private String username;
private Date birthday;
private String sex;
private String address;
public User() {
}
public User(int id, String username, Date birthday, String sex, String address) {
this.id = id;
this.username = username;
this.birthday = birthday;
this.sex = sex;
this.address = address;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
/*此处省略getter&setter*/
}
1.1.2 创建dao层接口及映射
接口
public interface IUserDao {
/*
添加用户
*/
void save(User user);
}
映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namesppace名称空间,用于定义是哪个类的映射文件,这里需要写映射接口的类全名-->
<mapper namespace="com.azure.dao.IUserDao">
<!--
mapper的子标签有insert、update、delete、select等,分别对应CRUD
id:接口中的方法名字
parameterType:设置接口方法参数类型
OGNL表达式:
格式:#{对象的属性名}
用途:获取参数类型对象的数据
要求:表达式里面的属性名与对象属性名必须完全一致
-->
<insert id="save" parameterType="com.azure.entity.User">
insert into user(username, birthday, sex, address) values(#{username},#{birthday},#{sex},#{address})
</insert>
</mapper>
- 注意事项:
- 映射文件是mybatis的mapper,而不是mybatis的config。留意引入的文件类型;
- mapper标签的子标签可以有多个;
- 此处sql语句写法与jdbcTemplate不同,不能用"?"占位,需要用OGNL表达式传入数据。
加载映射文件
- 在主配置文件中添加加载信息
<!--添加映射文件-->
<mappers>
<mapper resource="com/azure/dao/IUserDao.xml"></mapper>
</mappers>
1.1.3 提交事务
- 提交事务有三种方式
- 手动提交事务,在事务代码最后增加提交事务代码;
- 设置自动提交事务:在用工厂类创建SqlSession对象时传入参数true;
- 除去上述两种情况,默认不自动提交,执行完事务代码后马上回滚。
1.1.3.1 手动提交事务(推荐)
- 测试类代码
public class UserdaoTest {
@Test
public void save() throws IOException, ParseException {
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
//SqlSession工厂构造器
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//创建SqlSession工厂
SqlSessionFactory factory = builder.build(is);
//创建SqlSession
SqlSession sqlSession = factory.openSession();
//创建Dao实例
IUserDao userDao = sqlSession.getMapper(IUserDao.class);
/*
先以静态数据模拟,后面会实际操作数据库
*/
User user = new User();
user.setUsername("大黄");
user.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse("2010-10-20"));
user.setSex("男");
user.setAddress("北京");
//执行方法
System.out.println("保存前:" + user);
userDao.save(user);
System.out.println("保存后:" + user);
//手动提交事务
sqlSession.commit();
//关闭资源
sqlSession.close();
is.close();
}
}
1.1.3.2 自动提交事务(不建议)
- 测试类代码
public class UserdaoTest {
@Test
public void save() throws IOException, ParseException {
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
//SqlSession工厂构造器
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//创建SqlSession工厂
SqlSessionFactory factory = builder.build(is);
//创建SqlSession
//openSession(false)默认值,表示需要手动提交
//openSession(true),设置自动提交
SqlSession sqlSession = factory.openSession(true);
//创建Dao实例
IUserDao userDao = sqlSession.getMapper(IUserDao.class);
/*
先以静态数据模拟,后面会实际操作数据库
*/
User user = new User();
user.setUsername("大黄");
user.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse("2010-10-20"));
user.setSex("男");
user.setAddress("北京");
//执行方法
System.out.println("保存前:" + user);
userDao.save(user);
System.out.println("保存后:" + user);
//关闭资源
sqlSession.close();
is.close();
}
}
1.1.4 获取数据库自增长主键
- 主键需要通过设置dao接口映射文件来获取,上节的测试代码是无法获取主键值
1.1.4.1 调整dao接口映射获取主键
- 方法1(推荐):使用子标签selectKey
调整后的IUserDao.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namesppace名称空间,用于定义是哪个类的映射文件,这里需要写映射接口的类全名-->
<mapper namespace="com.azure.dao.IUserDao">
<!--
mapper的子标签有insert、update、delete、select等,分别对应CRUD
id:接口中的方法名字
parameterType:设置接口方法参数类型
OGNL表达式:
格式:#{对象的属性名}
用途:获取参数类型对象的数据
要求:表达式里面的属性名与对象属性名必须完全一致
-->
<!--
插入后获取主键自增长值,常用方法:使用selectKey标签
resultType 查询返回的主键的类型
keyColumn 数据库表中主键列名称
keyProperty对应User对象的属性。把查询的主键值设置到对象哪个属性中。
order 获取主键的时间
AFTER 在执行插入之后获取主键值(mysql中适用,主键自增长)
BEFORE 在执行插入之前获取主键值 (oracle中适用,因为oracle自增长通过序列实现)
标签体:查询最后插入的id值,固定为SELECT LAST_INSERT_ID();
-->
<insert id="save" parameterType="com.azure.entity.User">
<selectKey resultType="int" keyColumn="id" keyProperty="id" order="AFTER">
SELECT LAST_INSERT_ID();
</selectKey>
insert into user(username, birthday, sex, address) values(#{username},#{birthday},#{sex},#{address})
</insert>
</mapper>
- 方法二:使用属性值userGeneratedKeys,仅适用于支持主键自增长的数据库,不推荐
<!--
插入后获取主键自增长,方式2:只适合支持主键自增长的数据库。
useGeneratedKeys="true" true表示插入后获取主键值
keyProperty="id" 对象的哪个属性存储主键值
keyColumn="id" 表的主键列名称
-->
<insert id="save2" parameterType="com.azure.entity.User" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
insert into user(username, birthday, sex, address) values(#{username},#{birthday},#{sex},#{address})
</insert>
1.2 实现修改操作
1.2.1 dao接口
public interface IUserDao {
/**
* 修改
*/
void update(User user);// 省略其他方法
}
1.2.2 dao接口映射
- 在主配置文件中添加修改的映射
<!--修改
因为参数类型不是基本类型,所以使用OGNL表达式时属性名与User对象属性要完全一致
-->
<update id="update" parameterType="com.azure.entity.User">
update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
</update>
1.2.3 测试类
- 在测试类增加update方法
@Test
public void update() throws IOException, ParseException {
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
//SqlSession工厂构造器
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//创建SqlSession工厂
SqlSessionFactory factory = builder.build(is);
//创建SqlSession
SqlSession sqlSession = factory.openSession();
//创建Dao实例
IUserDao userDao = sqlSession.getMapper(IUserDao.class);
/*
先以静态数据模拟,后面会实际操作数据库
*/
User user = new User();
user.setId(49); //用以指明要修改的User的id值
user.setUsername("狗蛋");
user.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse("2000-10-20"));
user.setSex("男");
user.setAddress("北京");
//执行方法
userDao.update(user);
//手动提交事务
sqlSession.commit();
//关闭资源
sqlSession.close();
is.close();
}
1.3 实现删除操作
1.3.1 dao接口
public interface IUserDao {
/*
删除用户信息
*/
void delete(int id);// 省略其他方法
}
1.3.2 dao接口映射
- 在主配置文件中添加修改的映射
<!--删除
当接口的参数只有一个基本类型的时候,参数属性名可以随便写
-->
<delete id="delete" parameterType="int">
delete from user where id=#{id}
</delete>
1.3.3 测试类
- 在测试类增加delete方法
@Test
public void delete() throws IOException, ParseException {
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
//SqlSession工厂构造器
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//创建SqlSession工厂
SqlSessionFactory factory = builder.build(is);
//创建SqlSession
SqlSession sqlSession = factory.openSession();
//创建Dao实例
IUserDao userDao = sqlSession.getMapper(IUserDao.class);
//执行方法
userDao.delete(48);
//手动提交事务
sqlSession.commit();
//关闭资源
sqlSession.close();
is.close();
}
1.4 实现查询操作
1.4.1 dao接口
public interface IUserDao {
/*
实现主键查询
*/
User findById(int id);// 省略其他方法
}
1.4.2 dao接口映射
- 在主配置文件中添加修改的映射
<!--主键查询
parameterType 方法的形参(输入参数)
int 表示方法参数是int类型
_int 也可以表示int类型
integer 也可以表示int类型
java.lang.Integer 也可以表示int类型
resultType 方法返回值(输出参数)
-->
<select id="findById" resultType="com.azure.entity.User">
select * from user where id=#{id}
</select>
1.4.3 测试类
- 在测试类增加findById方法
@Test
public void findById() throws IOException, ParseException {
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
//SqlSession工厂构造器
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//创建SqlSession工厂
SqlSessionFactory factory = builder.build(is);
//创建SqlSession
SqlSession sqlSession = factory.openSession();
//创建Dao实例
IUserDao userDao = sqlSession.getMapper(IUserDao.class);
//执行方法
System.out.println(userDao.findById(49));
//手动提交事务
sqlSession.commit();
//关闭资源
sqlSession.close();
is.close();
}
1.5 实现模糊查询操作
1.5.1 dao接口
public interface IUserDao {
/*
实现模糊查询
*/
List<User> findByName(String name);// 省略其他方法
}
1.5.2 dao接口映射
- 在主配置文件中添加修改的映射
<!--模糊查询
模糊查询有两种方式
1.使用OGNL表达式(推荐)
2.使用字符串拼接(强烈不推荐,会出现sql语句注入问题):select * from user where username like %${value}%
-->
<select id="findByName" parameterType="String" resultType="com.azure.entity.User">
select * from user where username like #{username}
</select>
1.5.3 测试类
- 在测试类增加findByName方法
@Test
public void findByName() throws IOException, ParseException {
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
//SqlSession工厂构造器
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//创建SqlSession工厂
SqlSessionFactory factory = builder.build(is);
//创建SqlSession
SqlSession sqlSession = factory.openSession();
//创建Dao实例
IUserDao userDao = sqlSession.getMapper(IUserDao.class);
//执行方法
List<User> userList = userDao.findByName("%蛋%");
System.out.println(userList);
//手动提交事务
sqlSession.commit();
//关闭资源
sqlSession.close();
is.close();
}
2. Mybatis参数
2.1 输入参数parameterType
- 基本数据类型及其包装类
- 类(pojo、JavaBean等)和集合Map
2.2.1 java简单类型
-
接口方法的参数是简单类型(基本类型、对应包装类型、String类型)
-
映射文件的输入参数与接口类型一致。比如接口方法的参数是int,那么映射文件的类型有四种写法
int 表示方法参数是int类型 _int 也可以表示int类型 integer 也可以表示int类型 java.lang.Integer 也可以表示int类型
2.2.2 pojo类型(Plain Ordinary Java Object)
-
POJO是一个简单的、普通Java对象,它包含业务逻辑处理或持久化逻辑等,但不是JavaBean、EntityBean等,不具有任何特殊角色,不继承或不实现任何其它Java框架的类或接口。
-
pojo可以拥有类似JavaBean的属性以及对应的getter&setter方法
-
输入参数类型可以是pojo类型
2.2.3 pojo包装类型
- 一个对象再包装另外一个对象
案例需求:根据姓名、生日范围查询用户
2.2.3.1创建实体类
public class QueryVo {
// 查询需求: 按照姓名、生日的范围查询。
private User user;
private Date start;
private Date end;
public QueryVo(){}
public QueryVo(User user, Date start, Date end) {
this.user = user;
this.start = start;
this.end = end;
}
/*省略toString、getter&setter*/
}
2.2.3.2 dao接口
/*
* 根据条件查询
*/
List<User> findByCondition(QueryVo queryVo);
2.2.3.3 接口映射
<!--
条件查询
#{user.username} 获取的是QueryVo中User对象的username属性
注意:xml中不能写<号,需要把小于号转译: < 或者使用CDATA批量转译
-->
<select id="findByCondition" parameterType="com.azure.entity.QueryVo" resultType="com.azure.entity.User">
<![CDATA[
select * from user where username=#{user.username} and birthday>=#{start} and birthday <= #{end}
]]>
/*select * from user where username=#{user.username} and birthday>=#{start} and birthday <= #{end}*/
</select>
2.2.3.4 测试类
@Test
public void findByCondition() throws IOException, ParseException {
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
//SqlSession工厂构造器
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//创建SqlSession工厂
SqlSessionFactory factory = builder.build(is);
//创建SqlSession
SqlSession sqlSession = factory.openSession();
//创建Dao实例
IUserDao userDao = sqlSession.getMapper(IUserDao.class);
//执行方法
QueryVo queryVo = new QueryVo();
User user = new User();
user.setUsername("狗蛋");
queryVo.setUser(user);
queryVo.setStart(new SimpleDateFormat("yyyy-MM-dd").parse("1990-01-01" ));
queryVo.setEnd(new SimpleDateFormat("yyyy-MM-dd").parse("2020-01-01" ));
List<User> users = userDao.findByCondition(queryVo);
System.out.println(users);
//手动提交事务
sqlSession.commit();
//关闭资源
sqlSession.close();
is.close();
}
2.3 输出参数 resultType
- 基本数据类型及其包装类
- 类(pojo、JavaBean等)
- 用于单表查询
2.3.1 dao接口
/*
统计查询数量
*/
long count();
2.3.2 接口映射
<select id="count" resultType="long">
select count(*) from user
</select>
2.3.3 测试类
@Test
public void count() throws IOException, ParseException {
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
//SqlSession工厂构造器
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//创建SqlSession工厂
SqlSessionFactory factory = builder.build(is);
//创建SqlSession
SqlSession sqlSession = factory.openSession();
//创建Dao实例
IUserDao userDao = sqlSession.getMapper(IUserDao.class);
//执行方法
long count = userDao.count();
System.out.println(count);
//手动提交事务
sqlSession.commit();
//关闭资源
sqlSession.close();
is.close();
}
2.4 输出参数resultMap
- 通过设置列与属性的映射关系,解决列与属性不一致时候不能正确封装数据的问题。此时数据库中的列名称与对象的属性可以不一致。
- 多用于多表查询
下面以查询所有用户为例
2.4.1 dao接口
/*
查询所有用户
*/
List<User> findAll();
2.4.2 接口映射
<!--查询全部
使用resultMap确定列名与对象属性的映射关系
resultMap的属性
id:通过id确定引用的映射关系
type:要封装的类
resultMap的子标签
id:对象唯一标记与表主键建立映射关系
result:对象其他属性与表非主键字段建立映射关系
其属性值:
property:对象的属性
column:表的字段(不区分大小写,但是下划线不可省略),也可以使用别名代替
-->
<resultMap id="userResultMap" type="com.azure.entity.User">
<!--建立对象的唯一标记与表的主键映射关系-->
<id property="id" column="_id"></id>
<!--建立对象的其他属性与表的非主键字段的映射关系-->
<result property="username" column="username_"></result>
<result property="birthday" column="birthday_"></result>
<result property="sex" column="sex_"></result>
<result property="address" column="address_"></result>
</resultMap>
<select id="findAll" resultMap="userResultMap">
select id id_,username username_,birthday birthday_,sex sex_,address address_ FROM USER
</select>
2.4.3 测试类
@Test
public void findAll() throws IOException, ParseException {
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
//SqlSession工厂构造器
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//创建SqlSession工厂
SqlSessionFactory factory = builder.build(is);
//创建SqlSession
SqlSession sqlSession = factory.openSession();
//创建Dao实例
IUserDao userDao = sqlSession.getMapper(IUserDao.class);
//执行方法
List<User> userList = userDao.findAll();
System.out.println(userList);
//手动提交事务
sqlSession.commit();
//关闭资源
sqlSession.close();
is.close();
}
3. Mybatis实现Dao层开发的2种方式
3.1 dao代理开发
-
写一个dao接口,定义操作方式
-
需要针对dao接口,写一个对应的映射配置文件
- 映射文件中,namespace对应接口的全名
- 映射文件中的每个
<insert><delete><update><select>
标签的id与接口的方法名称对应 - 映射文件中的parameterType指定的类型与接口方法参数类型一致
- 映射文件中的resultType指定的类型与接口方法返回类型一致
-
在主配置文件中,除了配置连接数据库信息、连接池信息外,还要指定加载的接口映射文件
-
在执行时候,mybatis会自动根据dao接口,生成代理对象,由代理对象调用具体的实现方法。
3.2 dao传统开发
- 编写dao接口,并编写dao接口实现类
- 比起接口代理开发方式,需要多写实现类。需要硬编码执行操作
4. SqlMapperConfig.xml配置文件详解
4.1 配置顺序
顺序 | 配置标签名称 | 说明 |
---|---|---|
1 | properties | 属性 |
2 | settings | 配置全局参数 |
3 | typeAliases | 类型别名 |
4 | typeHandlers | 类型处理器 |
5 | objectFactory | 对象工厂 |
6 | plugins | 插件 |
7 | environments | 环境集合属性对象 |
8 | databaseIdProvider | 多数据库支持 |
9 | mappers | 映射器 |
说明: 在sqlMapConfig.xml中必须是从上往下的配置顺序!
4.2 properties属性
properties配置顺序最优先,所以会以properties的配置为主,那么sqlMapConfig.xml可以进行如下优化:
4.2.1 使用properties优化
properties有两个参数
- resource:引用本项目类路径下的properties文件数据
- url:引用本项目外部properties文件数据,可以访问网络上的
<properties resource="jdbc.properties">
<property name="jdbc.driver" value="com.mysql.jdbc.Driver"></property>
<property name="jdbc.url" value="jdbc:mysql:///mybatis?characterEncoding=utf8"></property>
<property name="jdbc.username" value="root"></property>
<property name="jdbc.password" value="rootr"></property>
</properties>
<!--数据库环境配置-->
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="pooled">
<property name="driver" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</dataSource>
</environment>
</environments>
4.2.2 抽取properties属性到本地properties文件
将properties的内容封装到一个properties文件中,即可通过不同的配置文件,灵活调用,同时保证数据不会暴露再主配置文件中
4.2.2.1 jdbc.properties文件
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf8
jdbc.username=root
jdbc.password=root
4.2.2.2 主配置文件
<?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>
<properties resource="jdbc.properties"></properties>
<!--数据库环境配置-->
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="pooled">
<property name="driver" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</dataSource>
</environment>
</environments>
<!--添加映射文件-->
<mappers>
<mapper resource="com/azure/dao/IUserDao.xml"></mapper>
</mappers>
</configuration>
4.3 typeAliases属性
-
typeAliases用于给指定类型起别名字
- typeAlias:只能同时给一个类的起别名(不推荐)
- type:设置指定类型全名
- alias:别名,在映射配置文件中类型只需要使用这个别名,不区分大小写
- package,批量给要给包名下所有类起别名,会自动将包下类名作为别名,不区分大小写(推荐)
- typeAlias:只能同时给一个类的起别名(不推荐)
-
配置完typeAliases后,模块下可以通过别名自动关联到被配置的指定类型
<typeAliases>
<!--使用typeAlias-->
<!--<typeAlias type="com.azure.entity.User" alias="user"></typeAlias>-->
<!--使用package自动批量起别名-->
<package name="com.azure.entity"></package>
</typeAliases>
4.4 mappers属性
- 加载接口映射配置文件
- mapper:一次只能加载一个映射配置文件(不推荐)
- package:将包下的所有映射配置文件自动加载推荐
<!--添加映射文件-->
<mappers>
<!--<mapper resource="com/azure/dao/IUserDao.xml"></mapper>-->
<package name="com.azure.dao"></package>
</mappers>
5. 补充知识点
5.1 JavaBean与pojo的区别
POJO是一个简单的、普通Java对象,它包含业务逻辑处理或持久化逻辑等,但不是JavaBean、EntityBean等,不具有任何特殊角色,不继承或不实现任何其它Java框架的类或接口。 可以包含类似与JavaBean属性和对属性访问的setter和getter方法的。
JavaBean 是一种JAVA语言写成的可重用组件。它的方法命名,构造及行为必须符合特定的约定:
- 这个类必须有一个公共的缺省构造函数。
- 这个类的属性使用getter和setter来访问,其他方法遵从标准命名规范。
- 这个类应是可序列化的。
简而言之,当一个Pojo可序列化,有一个无参的构造函数,使用getter和setter方法来访问属性时,他就是一个JavaBean。
5.2 Mybatis中#{}
与${}
的区别
相同:
- #{}和${}都可以用于接收字段的参数值,参数可以是简单类型值或者pojo等类型
区别:
- #{}在预编译过程会自动给传入的数据添加双引号,即将数据转化成字符串类型,而且如果sql语句存在参数时会作为占位符。在使用JDBC使用PreparedStatement时给占位符赋值,并自动进行java类型和JDBC类型的转换。可以避免sql注入的问题
- 不 对 参 数 做 字 符 串 转 换 处 理 , 而 会 直 接 将 参 数 原 样 输 出 , 相 当 于 拼 接 s q l 字 符 串 。 如 果 在 p a r a m e t e r T y p e 传 输 单 个 简 单 类 型 值 , {}不对参数做字符串转换处理,而会直接将参数原样输出,相当于拼接sql字符串。如果在parameterType传输单个简单类型值, 不对参数做字符串转换处理,而会直接将参数原样输出,相当于拼接sql字符串。如果在parameterType传输单个简单类型值,{}括号中只能写value。出现sql注入问题
结论:
- 能使用#{}的场合尽量使用#{},避免sql注入;
- 如果需要对参数原样输出,那么可以使用${}