整个实验使用Maven 来管理项目,编译器IDEA,github仓库 https://github.com/pallcard/mybatis
1.引入依赖(pom.xml)
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
</dependencies>
说明:(pom.xml)
Maven 项目默认编译项目为JDK 1.5,通过引入以下依赖来指定Maven 编译版本
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
2.JDBC测试类JDBCTest.java
public class JDBCTest {
public static void main(String[] args) throws Exception {
Connection connection = null;
PreparedStatement prepareStatement = null;
ResultSet rs = null;
try {
// 加载驱动(每次加载驱动,驱动名硬编码)
Class.forName("com.mysql.jdbc.Driver");
// 获取连接(每次获取连接,连接信息硬编码)
String url = "jdbc:mysql://127.0.0.1:3306/mybatis_demo";
String user = "root";
String password = "";
connection = DriverManager.getConnection(url, user, password);
// 获取statement,preparedStatement (sql和java代码耦合)
String sql = "select * from tb_user where id=?";
prepareStatement = connection.prepareStatement(sql);
// 设置参数(参数类型手动判断、设置)
prepareStatement.setLong(1, 1l);
// 执行查询
rs = prepareStatement.executeQuery();
// 处理结果集(结果集中数据类型、下标、列名要手动判断)
while (rs.next()) {
System.out.println(rs.getString("user_name"));
System.out.println(rs.getString("name"));
System.out.println(rs.getInt("age"));
System.out.println(rs.getDate("birthday"));
}
} finally {
//(每次都要打开或关闭连接,浪费资源)
// 关闭连接,释放资源
if (rs != null) {
rs.close();
}
if (prepareStatement != null) {
prepareStatement.close();
}
if (connection != null) {
connection.close();
}
}
}
}
1.引入依赖(pom.xml)
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.8</version>
</dependency>
<!--引入日志依赖包-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
</dependency>
2.User.java
public class User {
private int id;
private String userName;
private String password;
private String name;
private Integer age;
private Integer sex;
private Date birthday;
private String created;
private String updated;
// get、set、toString省
}
添加log4j.properties
log4j.rootLogger=DEBUG,A1
log4j.logger.org.apache=DEBUG
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c]-[%p] %m%n
3.全局配置文件(mybatis-config.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>
<properties>
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis_demo?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true"/>
<property name="username" value="root"/>
<property name="password" value=""/>
</properties>
<!-- 环境,可以配置多个,default:指定采用哪个环境 -->
<environments default="test">
<!-- id:唯一标识 -->
<environment id="test">
<!-- 事务管理器,JDBC类型的事务管理器 -->
<transactionManager type="JDBC" />
<!-- 数据源,池类型的数据源 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis_demo?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true" />
<property name="username" value="root" />
<property name="password" value="" />
</dataSource>
</environment>
<environment id="development">
<!-- 事务管理器,JDBC类型的事务管理器 -->
<transactionManager type="JDBC" />
<!-- 数据源,池类型的数据源 -->
<dataSource type="POOLED">
<property name="driver" value="${driver}" /> <!-- 配置了properties,所以可以直接引用 -->
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mappers/UserMapper.xml" />
</mappers>
</configuration>
4.配置Map.xml(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">
<!-- mappers:根标签,namespace:命名空间,随便写,一般保证命名空间唯一 -->
<mapper namespace="UserMapper">
<!-- statement,内容:sql语句。id:唯一标识,随便写,在同一个命名空间下保持唯一
resultType:sql语句查询结果集的封装类型,tb_user即为数据库中的表
-->
<select id="selectUser" resultType="cn.wishhust.mybatis.first.User">
select * from tb_user where id = #{id};
</select>
</mapper>
5.MybatisTest.java
public class MybatisTest {
public static void main(String[] args) throws Exception {
// 指定全局配置文件
String resource = "mybatis-config.xml";
// 读取配置文件
InputStream inputStream = Resources.getResourceAsStream(resource);
// 构建sqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 获取sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
// 操作CRUD,第一个参数:指定statement,规则:命名空间+“.”+statementId
// 第二个参数:指定传入sql的参数:这里是用户id
User user = sqlSession.selectOne("UserMapper.selectUser", 1);
System.out.println(user);
} finally {
sqlSession.close();
}
}
}
6.Mybatis步骤
1)配置mybatis-config.xml 全局的配置文件 (1、数据源,2、外部的mapper)
2)创建SqlSessionFactory
3)通过SqlSessionFactory创建SqlSession对象
4)通过SqlSession操作数据库 CRUD
5)调用session.commit()提交事务
6)调用session.close()关闭会话
1.UserDao接口
public interface UserDao {
/**
* 根据id查询用户信息
*
* @param id
* @return
*/
public User queryUserById(int id);
/**
* 查询所有用户信息
*
* @return
*/
public List<User> queryUserAll();
/**
* 新增用户
*
* @param user
*/
public void insertUser(User user);
/**
* 更新用户信息
*
* @param user
*/
public void updateUser(User user);
/**
* 根据id删除用户信息
*
* @param id
*/
public void deleteUser(int id);
}
2.UserDaoImpl
public class UserDaoImpl implements UserDao {
public SqlSession sqlSession;
public UserDaoImpl(SqlSession sqlSession) {
this.sqlSession = sqlSession;
}
@Override
public User queryUserById(int id) {
return this.sqlSession.selectOne("UserDao.queryUserById", id);
}
@Override
public List<User> queryUserAll() {
return this.sqlSession.selectList("UserDao.queryUserAll");
}
@Override
public void insertUser(User user) {
this.sqlSession.insert("UserDao.insertUser", user);
}
@Override
public void updateUser(User user) {
this.sqlSession.update("UserDao.updateUser", user);
}
@Override
public void deleteUser(int id) {
this.sqlSession.delete("UserDao.deleteUser", id);
}
}
3.UserDaoMapper.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:命名空间,随便写,一般保证命名空间唯一 -->
<mapper namespace="UserDao">
<!-- statement,内容:sql语句。id:唯一标识,随便写,在同一个命名空间下保持唯一
resultType:sql语句查询结果集的封装类型,tb_user即为数据库中的表
-->
<!--<select id="queryUserById" resultType="com.zpc.mybatis.pojo.User">-->
<!--select * from tb_user where id = #{id}-->
<!--</select>-->
<!--使用别名-->
<select id="queryUserById" resultType="cn.wishhust.mybatis.pojo.User">
select
tuser.id as id,
tuser.user_name as userName,
tuser.password as password,
tuser.name as name,
tuser.age as age,
tuser.birthday as birthday,
tuser.sex as sex,
tuser.created as created,
tuser.updated as updated
from
tb_user tuser
where tuser.id = #{id};
</select>
<select id="queryUserAll" resultType="cn.wishhust.mybatis.pojo.User">
select * from tb_user;
</select>
<!--插入数据-->
<insert id="insertUser" parameterType="cn.wishhust.mybatis.pojo.User">
INSERT INTO tb_user (
user_name,
password,
name,
age,
sex,
birthday,
created,
updated
)
VALUES
(
#{userName},
#{password},
#{name},
#{age},
#{sex},
#{birthday},
now(),
now()
);
</insert>
<update id="updateUser" parameterType="cn.wishhust.mybatis.pojo.User">
UPDATE tb_user
<trim prefix="set" suffixOverrides=",">
<if test="userName!=null">user_name = #{userName},</if>
<if test="password!=null">password = #{password},</if>
<if test="name!=null">name = #{name},</if>
<if test="age!=null">age = #{age},</if>
<if test="sex!=null">sex = #{sex},</if>
<if test="birthday!=null">birthday = #{birthday},</if>
updated = now(),
</trim>
WHERE
(id = #{id});
</update>
<delete id="deleteUser">
delete from tb_user where id=#{id}
</delete>
</mapper>
4.mybatis-config.xml
<mappers>
<mapper resource="mappers/UserMapper.xml" />
<mapper resource="mappers/UserDaoMapper.xml" />
</mappers>
5.测试
引入依赖
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
UserDaoTest .java(测试类的生成可以在UserDao上Alt+enter,选择创建测试类)
public class UserDaoTest {
public UserDao userDao;
public SqlSession sqlSession;
@Before
public void setUp() throws Exception {
// mybatis-config.xml
String resource = "mybatis-config.xml";
// 读取配置文件
InputStream is = Resources.getResourceAsStream(resource);
// 构建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
// 获取sqlSession
sqlSession = sqlSessionFactory.openSession();
this.userDao = new UserDaoImpl(sqlSession);
}
@Test
public void queryUserById() {
System.out.println(this.userDao.queryUserById(1));
}
@Test
public void queryUserAll() {
List<User> userList = this.userDao.queryUserAll();
for (User user : userList) {
System.out.println(user);
}
}
@Test
public void insertUser() {
User user = new User();
user.setAge(16);
user.setBirthday(new Date("1990/09/02"));
user.setName("大鹏");
user.setPassword("123456");
user.setSex(1);
user.setUserName("evan");
this.userDao.insertUser(user);
this.sqlSession.commit();
}
@Test
public void updateUser() {
User user = new User();
user.setBirthday(new Date());
user.setName("www");
user.setPassword("654321");
user.setSex(1);
user.setUserName("www");
user.setId(1);
this.userDao.updateUser(user);
this.sqlSession.commit();
}
@Test
public void deleteUser() {
this.userDao.deleteUser(4);
this.sqlSession.commit();
}
}
1.UserMapper(对应原UserDao)
public interface UserMapper {
/**
* 登录(直接使用注解指定传入参数名称)
* @param userName
* @param password
* @return
*/
public User login(@Param("userName") String userName, @Param("password") String password);
/**
* 根据表名查询用户信息(直接使用注解指定传入参数名称)
* @param tableName
* @return
*/
public List<User> queryUserByTableName(@Param("tableName") String tableName);
/**
* 根据Id查询用户信息
* @param id
* @return
*/
public User queryUserById(int id);
/**
* 查询所有用户信息
* @return
*/
public List<User> queryUserAll();
/**
* 新增用户信息
* @param user
*/
public void insertUser(User user);
/**
* 根据id更新用户信息
* @param user
*/
public void updateUser(User user);
/**
* 根据id删除用户信息
* @param id
*/
public void deleteUserById(int id);
}
2.UserMapper.xml
mapper:根标签,namespace:命名空间,为了使用接口动态代理,这里必须是接口的全路径名
<?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:命名空间,随便写,一般保证命名空间唯一 ,为了使用接口动态代理,这里必须是接口的全路径名-->
<mapper namespace="cn.wishhust.mybatis.mappers.UserMapper">
<!--
1.#{},预编译的方式preparedstatement,使用占位符替换,防止sql注入,一个参数的时候,任意参数名可以接收
2.${},普通的Statement,字符串直接拼接,不可以防止sql注入,一个参数的时候,必须使用${value}接收参数
-->
<select id="queryUserByTableName" resultType="cn.wishhust.mybatis.pojo.User">
select * from ${tableName}
</select>
<select id="login" resultType="cn.wishhust.mybatis.pojo.User">
select * from tb_user where user_name = #{userName} and password = #{password}
</select>
<!-- statement,内容:sql语句。
id:唯一标识,随便写,在同一个命名空间下保持唯一,使用动态代理之后要求和方法名保持一致
resultType:sql语句查询结果集的封装类型,使用动态代理之后和方法的返回类型一致;resultMap:二选一
parameterType:参数的类型,使用动态代理之后和方法的参数类型一致
-->
<select id="queryUserById" resultType="cn.wishhust.mybatis.pojo.User">
select * from tb_user where id = #{id}
</select>
<select id="queryUserAll" resultType="cn.wishhust.mybatis.pojo.User">
select * from tb_user
</select>
<!-- 新增的Statement
id:唯一标识,随便写,在同一个命名空间下保持唯一,使用动态代理之后要求和方法名保持一致
parameterType:参数的类型,使用动态代理之后和方法的参数类型一致
useGeneratedKeys:开启主键回写
keyColumn:指定数据库的主键
keyProperty:主键对应的pojo属性名
-->
<insert id="insertUser" useGeneratedKeys="true" keyColumn="id" keyProperty="id"
parameterType="cn.wishhust.mybatis.pojo.User">
INSERT INTO tb_user (
id,
user_name,
password,
name,
age,
sex,
birthday,
created,
updated
)
VALUES
(
null,
#{userName},
#{password},
#{name},
#{age},
#{sex},
#{birthday},
NOW(),
NOW()
);
</insert>
<!--
更新的statement
id:唯一标识,随便写,在同一个命名空间下保持唯一,使用动态代理之后要求和方法名保持一致
parameterType:参数的类型,使用动态代理之后和方法的参数类型一致
-->
<update id="updateUser" parameterType="cn.wishhust.mybatis.pojo.User">
UPDATE tb_user
<trim prefix="set" suffixOverrides=",">
<if test="userName!=null">user_name = #{userName},</if>
<if test="password!=null">password = #{password},</if>
<if test="name!=null">name = #{name},</if>
<if test="age!=null">age = #{age},</if>
<if test="sex!=null">sex = #{sex},</if>
<if test="birthday!=null">birthday = #{birthday},</if>
updated = now(),
</trim>
WHERE
(id = #{id});
</update>
<!--
删除的statement
id:唯一标识,随便写,在同一个命名空间下保持唯一,使用动态代理之后要求和方法名保持一致
parameterType:参数的类型,使用动态代理之后和方法的参数类型一致
-->
<delete id="deleteUserById" parameterType="java.lang.Integer">
delete from tb_user where id=#{id}
</delete>
</mapper>
3.mybatis-config.xml
<mappers>
<mapper resource="mappers/UserMapper.xml" />
<mapper resource="mappers/UserDaoMapper.xml" />
<mapper resource="mappers/UserMapper2.xml" />
</mappers>
4.测试
a.映射文件的命名空间(namespace)必须是mapper接口的全路径
b.映射文件的statement的id必须和mapper接口的方法名保持一致
c.Statement的resultType必须和mapper接口方法的返回类型一致
d.statement的parameterType必须和mapper接口方法的参数类型一致(不一定)
public class UserMapperTest {
public UserMapper userMapper;
@Before
public void setUp() throws Exception {
// 指定配置文件
String resource = "mybatis-config.xml";
// 读取配置文件
InputStream inputStream = Resources.getResourceAsStream(resource);
// 构建sqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 获取sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession(true);
// 1. 映射文件的命名空间(namespace)必须是mapper接口的全路径
// 2. 映射文件的statement的id必须和mapper接口的方法名保持一致
// 3. Statement的resultType必须和mapper接口方法的返回类型一致
// 4. statement的parameterType必须和mapper接口方法的参数类型一致(不一定)
this.userMapper = sqlSession.getMapper(UserMapper.class);
}
@Test
public void login() {
System.out.println(this.userMapper.login("lk", "123456"));
}
@Test
public void queryUserByTableName() {
List<User> userList = this.userMapper.queryUserByTableName("tb_user");
for (User user : userList) {
System.out.println(user);
}
}
@Test
public void queryUserById() {
System.out.println(this.userMapper.queryUserById(1));
}
@Test
public void queryUserAll() {
List<User> userList = this.userMapper.queryUserAll();
for (User user : userList) {
System.out.println(user);
}
}
@Test
public void insertUser() {
User user = new User();
user.setAge(20);
user.setBirthday(new Date());
user.setName("大神");
user.setPassword("123456");
user.setSex(2);
user.setUserName("bigGod222");
this.userMapper.insertUser(user);
System.out.println(user.getId());
}
@Test
public void updateUser() {
User user = new User();
user.setBirthday(new Date());
user.setName("静静");
user.setPassword("123456");
user.setSex(0);
user.setUserName("Jinjin");
user.setId(1);
this.userMapper.updateUser(user);
}
@Test
public void deleteUserById() {
this.userMapper.deleteUserById(1);
}
}
1.CRUD标签
id属性:当前名称空间下的statement的唯一标识。必须。要求id和mapper接口中的方法的名字一致。
resultType:将结果集映射为java的对象类型。必须(和 resultMap 二选一)
parameterType:传入参数类型。可以省略
id:唯一标识,随便写,在同一个命名空间下保持唯一,使用动态代理之后要求和方法名保持一致
parameterType:参数的类型,使用动态代理之后和方法的参数类型一致
useGeneratedKeys:开启主键回写
keyColumn:指定数据库的主键
keyProperty:主键对应的pojo属性名
标签内部:具体的sql语句。
id属性:当前名称空间下的statement的唯一标识(必须属性);
parameterType:传入的参数类型,可以省略。
标签内部:具体的sql语句。
id属性:当前名称空间下的statement的唯一标识(必须属性);
parameterType:传入的参数类型,可以省略。
标签内部:具体的sql语句。
2.#{}和${}
#{} 和 ${} 在预编译中的处理是不一样的。#{} 在预处理时,会把参数部分用一个占位符 ? 代替;而 ${} 则只是简单的字符串替换.优先使用 #{}, ${} 会导致 sql 注入的问题。
场景1:数据库有两个一模一样的表。历史表,当前表
查询表中的信息,有时候从历史表中去查询数据,有时候需要去新的表去查询数据。
希望使用1个方法来完成操作。
<select id="queryUserByTableName" resultType="com.zpc.mybatis.pojo.User">
select * from #{tableName}
</select>
<-- 相当于select * from “tb_user”; 会报错 -->
<-- 正确做法 -->
<select id="queryUserByTableName" resultType="com.zpc.mybatis.pojo.User">
select * from ${tableName}
</select>
注意:
使用 去 取 出 参 数 值 信 息 , 需 要 使 用 {} 去取出参数值信息,需要使用 去取出参数值信息,需要使用{value}
#{} 只是表示占位,与参数的名字无关,如果只有一个参数,会自动对应。多参数时,通常在方法的参数列表上加上一个注释@Param(“xxxx”) 显式指定参数的名字
3.sql片段
<--定义-->
<sql id=””></sql>
<--使用-->
<include refId=”” />
动态sql有
1.if
场景:查询用户,如果输入了姓名,则按姓名查询
// 接口
List<User> queryUserListByName(@Param("userName") String userName);
<--mapper-->
<mapper namespace="cn.wishhust.mybatis.dao.mappers.DynamicSqlMapper">
<!--if的简单使用-->
<select id="queryUserListByName"
resultType="cn.wishhust.mybatis.pojo.User">
select * from tb_user
<if test="userName != null and userName.trim() != ''">
where user_name like '%${userName}%'
</if>
</select>
</mapper>
2.choose,when,otherwise
场景:查询用户,如果输入了姓名则按照姓名模糊查找,否则如果输入了年龄则按照年龄查找,否则查找姓名为“ls”的用户。
// 接口
List<User> queryUserListByNameOrAge(@Param("userName") String userName,
@Param("age") Integer age);
<--mapper-->
<mapper namespace="cn.wishhust.mybatis.dao.mappers.DynamicSqlMapper">
<!--choose when otherwise的简单使用-->
<select id="queryUserListByNameOrAge"
resultType="cn.wishhust.mybatis.pojo.User">
select * from tb_user WHERE
<!--
1.一旦有条件成立的when,后续的when则不会执行
2.当所有的when都不执行时,才会执行otherwise
-->
<choose>
<when test="userName!=null and userName.trim()!=''">
user_name like '%${userName}%'
</when>
<when test="age!=null">
age = #{age}
</when>
<otherwise>
user_name = 'ls'
</otherwise>
</choose>
</select>
</mapper>
3.where 和set
场景一:查询所有用户,如果输入了姓名按照姓名进行模糊查询,如果输入年龄,按照年龄进行查询,如果两者都输入,两个条件都要成立。
// 接口
List<User> queryUserListByNameAndAge(@Param("userName") String userName,
@Param("age") Integer age);
<--mapper-->
<mapper namespace="cn.wishhust.mybatis.dao.mappers.DynamicSqlMapper">
<!--where 和set的简单使用-->
<select id="queryUserListByNameAndAge" resultType="cn.wishhust.mybatis.pojo.User">
select * from tb_user
<!--如果多出一个and,会自动去除,如果缺少and或者多出多个and则会报错-->
<where>
<if test="userName!=null and userName.trim()!=''">
and name like '%${userName}%'
</if>
<if test="age!=null">
and age = #{age}
</if>
</where>
</select>
</mapper>
场景二:修改用户信息,如果参数user中的某个属性为null,则不修改。
// 接口
void updateUser(User user);
<--mapper-->
<mapper namespace="cn.wishhust.mybatis.dao.mappers.DynamicSqlMapper">
<update id="updateUser" parameterType="cn.wishhust.mybatis.pojo.User">
UPDATE tb_user
<trim prefix="set" suffixOverrides=",">
<if test="userName!=null">user_name = #{userName},</if>
<if test="password!=null">password = #{password},</if>
<if test="name!=null">name = #{name},</if>
<if test="age!=null">age = #{age},</if>
<if test="sex!=null">sex = #{sex},</if>
<if test="birthday!=null">birthday = #{birthday},</if>
updated = now(),
</trim>
WHERE
(id = #{id});
</update>
</mapper>
4.foreach
场景:按照多个id查询用户信息。
// 接口
List<User> queryUserListByIds(@Param("ids") int[] ids);
<--mapper-->
<mapper namespace="cn.wishhust.mybatis.dao.mappers.DynamicSqlMapper">
<!--foreach的简单使用-->
<select id="queryUserListByIds" resultType="cn.wishhust.mybatis.pojo.User">
select * from tb_user where id in
<foreach collection="ids" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</select>
</mapper>
一对一查询
需求:查询订单,并查询出下单人的信息。
Order.java
public class Order {
private Integer id;
private Long userId;
private String orderNumber;
private Date createdTime;
private Date updatedTime;
private User user;
// get,set,toString
}
OrderMapper.java
public interface OrderMapper {
Order queryOrderWithUserByOrderNumber(@Param("number") String number);
}
OrderMapper.xml
<!-- mappers:根标签,namespace:命名空间,随便写,一般保证命名空间唯一 -->
<mapper namespace="cn.wishhust.mybatis.dao.mappers.OrderMapper">
<resultMap id="OrderUserResultMap"
type="cn.wishhust.mybatis.pojo.Order"
autoMapping="true">
<!--
指定主键
column:数据库的列名
property:java实体类中的属性名
-->
<id column="id" property="id"/>
<!--association:完成子对象的映射-->
<!--property:子对象在父对象中的属性名-->
<!--javaType:子对象的java类型-->
<!--autoMapping:完成子对象的自动映射,若开启驼峰,则按驼峰匹配-->
<association property="user"
javaType="cn.wishhust.mybatis.pojo.User"
autoMapping="true">
<id column="user_id" property="id"/>
</association>
</resultMap>
<select id="queryOrderWithUserByOrderNumber"
resultMap="OrderUserResultMap">
select * from tb_order o left join tb_user u
on o.user_id=u.id
where o.order_number = #{number}
</select>
</mapper>
一级缓存
Mybatis的一级缓存的作用域是session,当openSession()后,如果执行相同的SQL(相同语句和参数),Mybatis不进行执行SQL,而是从缓存中命中返回。原理:
Mybatis执行查询时首先去缓存区命中,如果命中直接返回,没有命中则执行SQL,从数据库中查询。
在mybatis中,一级缓存默认是开启的,并且一直无法关闭
一级缓存满足条件:
1、同一个session中
2、相同的SQL和参数
二级缓存
mybatis 的二级缓存的作用域是一个mapper的namespace ,同一个namespace中查询sql可以从缓存中命中。
<mapper namespace="cn.wishhust.mybatis.dao.mappers.UserMapper">
<cache/>
...
</mapper>
<settings>
<!--开启驼峰匹配-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!--开启二级缓存,全局总开关,这里关闭,mapper中开启了也没用-->
<setting name="cacheEnabled" value="false"/>
</settings>
方法一:
转义字符 | 字符 | 说明 |
---|---|---|
<; | < | 小于 |
>; | > | 小于 |
&; | & | 和 |
&apos; | ’ | 省略号 |
"; | " | 引号 |
方法二:
注:使用标记的sql语句中的 等标签不会被解析。
参考:https://blog.csdn.net/hellozpc/article/details/80878563#102choose_when_otherwise_1444