mybatis第二天

Mybatis第二天

 

框架课程

1. 课程计划

1、输入映射和输出映射

a) 输入参数映射

b) 返回值映射

2、动态Sql

a) If标签

b) Where标签

c) Sql片段

d) Foreach标签

3、关联对象映射

a) Association(关联单个对象,即一对一)

b) Collection(关联集合,即一对多)

4、Mybatis整合Spring

a) 如何整合Spring

b) 使用原始的方式开发Dao

c) 使用Mapper动态代理方式开发Dao

5、Mybatis逆向工程(能够使用)

2. 输入映射和输出映射

Mapper.xml映射文件中定义了操作数据库的Sql,每个Sql是一个statement,映射文件是Mybatis的核心。

2.1. 环境准备

1. 复制昨天的工程,按照下图进行

  1. 粘贴并更名,如下图

  1. 只保留Mapper接口开发相关的文件,其它的删除

最终效果如下图:

  1. 如下图修改SqlMapConfig.xml配置文件。Mapper映射器保留包扫描的方式

2.2. parameterType(输入类型)

2.2.1. 传递简单类型

参考第一天内容。

使用#{}占位符,或者${}进行Sql拼接。

2.2.2. 传递Pojo对象

参考第一天的内容。

#{}或者${}括号中的值为Pojo属性名称。

2.2.3. 传递Pojo包装对象

包装对象:Pojo类中的一个属性是另外一个Pojo。

为什么使用包装对象?

在平时的开发中,不一定就是单纯的对一个实体进行增删改查,例如完成用户信息的综合查询,有时需要传入查询条件很复杂,可能包括用户信息、关联表的其它信息等。针对这种需求,在Mybatis中我们可以使用自定义的包装类型的Pojo,在包装类型的Pojo中将复杂的查询条件包装进去。

功能需求:根据用户名模糊查询用户信息,查询条件放到QueryVo的user属性中。

2.2.3.1. 编写QueryVo

public class QueryVo {

// 包含其他的pojo

private User user;

public User getUser() {

return user;

}

public void setUser(User user) {

this.user = user;

}

}

2.2.3.2. Sql语句

SELECT * FROM USER WHERE USERNAME LIKE ‘%王%‘

2.2.3.3. Mapper.xml文件

在UserMapper.xml中配置Sql,如下图。

2.2.3.4. Mapper接口

在UserMapper接口中添加方法,如下图:

2.2.3.5. 测试方法

在UserMapeprTest增加测试方法,如下:

@Test

public void testQueryUserByQueryVo() {

// mybatis和spring整合,整合之后,交给spring管理

SqlSession sqlSession = this.sqlSessionFactory.openSession();

// 创建Mapper接口的动态代理对象,整合之后,交给spring管理

UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

// 使用userMapper执行查询,使用包装对象

QueryVo queryVo = new QueryVo();

// 设置user条件

User user = new User();

user.setUsername("%王%");

// 设置到包装对象中

queryVo.setUser(user);

// 执行查询

List<User> list = userMapper.queryUserByQueryVo(queryVo);

for (User u : list) {

System.out.println(u);

}

// mybatis和spring整合,整合之后,交给spring管理

sqlSession.close();

}

2.2.3.6. 效果

测试结果如下图:

2.2.4. 传递HashMap

2.2.4.1. Mapper.xml文件

在UserMapper.xml中配置Sql,如下图。

2.2.4.2. Mapper接口

在UserMapper接口中添加方法,如下图:

2.2.4.3. 测试方法

在UserMapeprTest增加测试方法,如下:

@Test

public void testQueryUserByHashMap () {

// mybatis和spring整合,整合之后,交给spring管理

SqlSession sqlSession = this.sqlSessionFactory.openSession();

// 创建Mapper接口的动态代理对象,整合之后,交给spring管理

UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

HashMap<String,String> map = new HashMap<String,String>();

map.put("username", "%王%");

List<User> list = userMapper.queryUserByHashMap(map);

for (User u : list) {

System.out.println(u);

}

sqlSession.close();

}

2.2.4.4. 效果

测试结果如下图:

2.3. resultType(输出类型)

2.3.1. 输出简单类型

功能需求:查询用户表数据条数

Sql语句:

SELECT count(*) FROM user

2.3.1.1. Mapper.xml文件

在UserMapper.xml中配置Sql,如下图:

2.3.1.2. Mapper接口

在UserMapper添加方法,如下图:

2.3.1.3. 测试方法

在UserMapeprTest增加测试方法,如下:

@Test

public void testQueryUserCount() {

// mybatis和spring整合,整合之后,交给spring管理

SqlSession sqlSession = this.sqlSessionFactory.openSession();

// 创建Mapper接口的动态代理对象,整合之后,交给spring管理

UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

// 使用userMapper执行查询用户数据条数

int count = userMapper.queryUserCount();

System.out.println(count);

// mybatis和spring整合,整合之后,交给spring管理

sqlSession.close();

}

2.3.1.4. 效果

测试结果如下图:

注意:输出简单类型必须查询出来的结果集有一条记录,最终将第一个字段的值转换为输出类型

2.3.2. 输出Pojo对象

参考第一天内容

2.3.3. 输出Pojo列表

参考第一天内容

2.3.4. 输出HashMap

2.3.4.1. Mapper.xml文件

在UserMapper.xml中配置Sql,如下图

2.3.4.2. Mapper接口

在UserMapper接口中添加方法,如下图:

2.3.4.3. 测试方法

在UserMapeprTest增加测试方法,如下:

@Test

public void testQueryUserByHashMap () {

// mybatis和spring整合,整合之后,交给spring管理

SqlSession sqlSession = this.sqlSessionFactory.openSession();

// 创建Mapper接口的动态代理对象,整合之后,交给spring管理

UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

HashMap<String,Object> map = userMapper.queryUserByIdForHashmap(2);

Iterator<String> it = map.keySet().iterator();

while(it.hasNext()) {

String key = it.next();

System.out.println(key+":"+map.get(key));

}

sqlSession.close();

}

2.3.4.4. 效果

测试结果如下图:

2.4. resultMap

可以指定将查询结果映射为Pojo,但需要Pojo的属性名和Sql查询的列名一致方可映射成功。

如果Sql查询字段名和Pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系 ,resultMap实质上还需要将查询结果映射到Pojo对象中。

功能需求:查询订单表orders的所有数据

Sql语句:

SELECT id, user_id, number, createtime, note FROM orders

2.4.1. 创建数据表、初始化测试数据、声明Pojo对象

创建订单表并查询订单表的全部数据

数据库表如下图:

Orders对象:

public class Orders {

// 订单id

private int id;

// 用户id

private Integer userId;

// 订单号

private String number;

// 订单创建时间

private Date createtime;

// 备注

private String note;

get/set…

}

2.4.2. Mapper.xml文件

创建OrdersMapper.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">

<!-- namespace:命名空间,用于隔离sql,还有一个很重要的作用,Mapper动态代理开发的时候使用,需要指定Mapper的类路径 -->

<mapper namespace="com.itheima.mybatis.mapper.OrdersMapper">

<!-- 查询所有的订单数据 -->

<select id="queryOrdersAll" resultType="orders">

SELECT id, user_id,

number,

createtime, note FROM orders

</select>

</mapper>

2.4.3. Mapper接口

编写接口如下:

public interface OrdersMapper {

/**

* 查询所有订单

*

* @return

*/

List<Orders> queryOrdersAll();

}

2.4.4. 测试方法

编写测试方法OrdersMapperTest如下:

public class OrdersMapperTest {

private SqlSessionFactory sqlSessionFactory;

@Before

public void init() throws Exception {

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

this.sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

}

@Test

public void testQueryAll() {

// 获取sqlSession

SqlSession sqlSession = this.sqlSessionFactory.openSession();

// 获取OrderMapper

OrdersMapper orderMapper = sqlSession.getMapper(OrdersMapper.class);

// 执行查询

List<Orders> list = orderMapper.queryOrdersAll();

for (Orders order : list) {

System.out.println(order);

}

}

}

2.4.5. 效果

测试效果如下图:

发现userId为null

解决方案:使用resultMap

2.4.6. 使用resultMap

由于上边的mapper.xml中Sql查询列(user_id)和Order类属性(userId)不一致,所以查询结果不能映射到Pojo中。

需要定义resultMap,把orderResultMap将Sql查询列(user_id)和Order类属性(userId)对应起来

改造OrderMapper.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">

<!-- namespace:命名空间,用于隔离sql,还有一个很重要的作用,Mapper动态代理开发的时候使用,需要指定Mapper的类路径 -->

<mapper namespace="com.itheima.mybatis.mapper.OrdersMapper">

<!-- resultMap最终还是要将结果映射到pojo上,type就是指定映射到哪一个pojo -->

<!-- id:设置ResultMap的id -->

<resultMap type="orders" id="orderResultMap">

<!-- 定义主键 ,非常重要。如果是多个字段,则定义多个id -->

<!-- property:主键在pojo中的属性名 -->

<!-- column:主键在数据库中的列名 -->

<id property="id" column="id" />

<!-- 定义普通属性 -->

<result property="userId" column="user_id" />

<result property="number" column="number" />

<result property="createtime" column="createtime" />

<result property="note" column="note" />

</resultMap>

<!-- 查询所有的订单数据 -->

<select id="queryOrdersAll" resultMap="orderResultMap">

SELECT id, user_id,

number,

createtime, note FROM orders

</select>

</mapper>

2.4.7. 效果

只需要修改Mapper.xml就可以了,再次测试结果如下:

3. 动态Sql

通过Mybatis提供的各种标签方法实现动态拼接Sql。

功能需求:根据性别和名字查询用户

Sql语句:

SELECT id, username, birthday, sex, address FROM `user` WHERE sex = 1 AND username LIKE ‘%张%‘

3.1. If标签

3.1.1. Mapper.xml文件

UserMapper.xml配置Sql,如下:

<!-- 根据条件查询用户 -->

<select id="queryUserByWhere" parameterType="user" resultType="user">

SELECT id, username, birthday, sex, address FROM `user`

WHERE sex = #{sex} AND username LIKE #{username}

</select>

3.1.2. Mapper接口

编写Mapper接口,如下图:

3.1.3. 测试方法

在UserMapperTest添加测试方法,如下:

@Test

public void testQueryUserByWhere() {

// mybatis和spring整合,整合之后,交给spring管理

SqlSession sqlSession = this.sqlSessionFactory.openSession();

// 创建Mapper接口的动态代理对象,整合之后,交给spring管理

UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

// 使用userMapper执行根据条件查询用户

User user = new User();

user.setSex("1");

user.setUsername("%张%");

List<User> list = userMapper.queryUserByWhere(user);

for (User u : list) {

System.out.println(u);

}

// mybatis和spring整合,整合之后,交给spring管理

sqlSession.close();

}

3.1.4. 效果

测试效果如下图:

如果注释掉 user.setSex("1"),测试结果如下图:

测试结果二很显然不合理。

按照之前所学的,要解决这个问题,需要编写多个Sql,查询条件越多,需要编写的Sql就更多了,显然这样是不靠谱的。

解决方案,使用动态Sql的if标签

3.1.5. 使用if标签

改造UserMapper.xml,如下:

<!-- 根据条件查询用户 -->

<select id="queryUserByWhere" parameterType="user" resultType="user">

SELECT id, username, birthday, sex, address FROM `user`

WHERE 1=1

<if test="sex != null and sex != ‘‘">

AND sex = #{sex}

</if>

<if test="username != null and username != ‘‘">

AND username LIKE

#{username}

</if>

</select>

注意字符串类型的数据需要做不等于空字符串校验。

3.1.6. 效果

如上图所示,测试OK

3.2. Where标签

上面的Sql还有where 1=1 这样的语句,很麻烦

可以使用where标签进行改造

改造UserMapper.xml,如下

<!-- 根据条件查询用户 -->

<select id="queryUserByWhere" parameterType="user" resultType="user">

SELECT id, username, birthday, sex, address FROM `user`

<!-- where标签可以自动添加where,同时处理sql语句中第一个and关键字 -->

<where>

<if test="sex != null">

AND sex = #{sex}

</if>

<if test="username != null and username != ‘‘">

AND username LIKE #{username}

</if>

</where>

</select>

3.2.1. 效果

测试效果如下图:

3.3. Sql片段

Sql中可将重复的Sql提取出来,使用时用include引用即可,最终达到Sql重用的目的。

把上面例子中的id, username, birthday, sex, address提取出来,作为Sql片段,如下:

<!-- 根据条件查询用户 -->

<select id="queryUserByWhere" parameterType="user" resultType="user">

<!-- SELECT id, username, birthday, sex, address FROM `user` -->

<!-- 使用include标签加载sql片段;refid是sql片段id -->

SELECT <include refid="userFields" /> FROM `user`

<!-- where标签可以自动添加where关键字,同时处理sql语句中第一个and关键字 -->

<where>

<if test="sex != null">

AND sex = #{sex}

</if>

<if test="username != null and username != ‘‘">

AND username LIKE #{username}

</if>

</where>

</select>

<!-- 声明sql片段 -->

<sql id="userFields">

id, username, birthday, sex, address

</sql>

如果要使用别的Mapper.xml配置的Sql片段,可以在refid前面加上对应的Mapper.xml的namespace,如下

SELECT <include refid="com.itheima.mybatis.mapper.OrdersMapper.userFields" /> FROM `user`

3.4. foreach标签

向Sql传递List,Mybatis使用foreach解析。

功能需求:根据多个id查询用户信息

查询Sql语句:

SELECT * FROM user WHERE id IN (1,10,24)

3.4.1. Mapper.xml文件

UserMapper.xml添加Sql,如下:

<!-- 根据ids查询用户 -->

<select id="queryUserByIds" parameterType="list" resultType="user">

SELECT * FROM `user`

<where>

<!-- foreach标签,进行遍历 -->

<!-- collection:遍历的集合,如果传入List集合则必须为“list”,

如果传入普通数组,则必须为“array” -->

<!-- item:遍历的项目,可以随便写,,但是和后面的#{}里面要一致 -->

<!-- open:在前面添加的sql片段 -->

<!-- close:在结尾处添加的sql片段 -->

<!-- separator:指定遍历的元素之间使用的分隔符 -->

<foreach collection="list" item="item" open="id IN (" close=")"

separator=",">

#{item}

</foreach>

</where>

</select>

测试方法如下图:

@Test

public void testQueryUserByIds() {

// mybatis和spring整合,整合之后,交给spring管理

SqlSession sqlSession = this.sqlSessionFactory.openSession();

// 创建Mapper接口的动态代理对象,整合之后,交给spring管理

UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

// 使用userMapper执行根据条件查询用户

List<Integer> ids = new ArrayList<Integer>();

ids.add(2);

ids.add(3);

ids.add(4);

List<User> list = userMapper.queryUserByIds(ids);

for (User u : list) {

System.out.println(u);

}

// mybatis和spring整合,整合之后,交给spring管理

sqlSession.close();

}

3.4.2. 效果

测试效果如下图:

4. 关联对象映射

关联对象是什么?比如用户和订单,一个用户可以有多个订单,但是一个订单只能属于一个用户,按照面向对象的思维,如果从用户对象出发,我们希望在用户对象当中持有该用户的订单对象集合;如果从订单对象出发,我们希望在订单对象当中持有所属的用户对象,使用的时候便可以通过对象.的方式调用,用户对象和订单对象就是关联对象。

Mybatis框架使用我们自定义的Sql语句(比如join)查询出关联数据之后,无法使用resultType自动完成这种复杂的关联对象映射,这种情况下,我们必须手动映射。

4.1. Association(关联单个对象,即一对一)

功能需求:查询所有订单信息,关联查询下单的用户信息。

Sql语句:

SELECT

o.id,

o.user_id,

o.number,

o.createtime,

o.note,

u.username,

u.address

FROM

`orders` o

LEFT JOIN `user` u ON o.user_id = u.id

4.1.1. 改造Pojo类

在Orders类中加入user属性,user属性用于存储关联查询出来的用户信息,

改造Orders如下图:

4.1.2. Mapper.xml

这里resultMap指定orderUserResultMap,如下:

<resultMap type="orders" id="orderUserResultMap">

<id property="id" column="id" />

<result property="userId" column="user_id" />

<result property="number" column="number" />

<result property="createtime" column="createtime" />

<result property="note" column="note" />

<!-- association :配置单个关联对象 -->

<!-- property:orders里面的User属性名 -->

<!-- javaType:属性类型 -->

<association property="user" javaType="user">

<!-- id:声明主键,表示user_id是关联查询对象的唯一标识-->

<id property="id" column="user_id" />

<result property="username" column="username" />

<result property="address" column="address" />

</association>

</resultMap>

<!-- 查询订单,订单内部包含用户属性 -->

<select id="queryOrderUserResultMap" resultMap="orderUserResultMap">

SELECT

o.id,

o.user_id,

o.number,

o.createtime,

o.note,

u.username,

u.address

FROM

`orders` o

LEFT JOIN `user` u ON o.user_id = u.id

</select>

4.1.3. Mapper接口

编写OrdersMapper如下图:

4.1.4. 测试方法

在OrdersMapperTest增加测试方法,如下:

@Test

public void testQueryOrderUserResultMap() {

// mybatis和spring整合,整合之后,交给spring管理

SqlSession sqlSession = this.sqlSessionFactory.openSession();

// 创建Mapper接口的动态代理对象,整合之后,交给spring管理

OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);

List<Orders> list = ordersMapper.queryOrderUserResultMap();

for (Orders o : list) {

System.out.println(o);

}

// mybatis和spring整合,整合之后,交给spring管理

sqlSession.close();

}

4.1.5. 效果

测试效果如下图:

4.1.6. 扩展:使用resultType

使用resultType,改造订单Pojo类,此Pojo类中包括了订单信息和用户信息

这样返回对象的时候,Mybatis自动把用户信息也注入进来了

4.1.6.1. 改造Pojo类

OrderUser类继承Order类后OrderUser类包括了Order类的所有字段,只需要定义用户的信息字段即可,如下图:

4.1.6.2. Mapper.xml

在OrdersMapper.xml添加Sql,如下

<!-- 查询订单,同时包含用户数据 -->

<select id="queryOrderUser" resultType="orderUser">

SELECT

o.id,

o.user_id

userId,

o.number,

o.createtime,

o.note,

u.username,

u.address

FROM

`orders` o

LEFT JOIN `user` u ON o.user_id = u.id

</select>

4.1.6.3. Mapper接口

在OrdersMapper接口添加方法,如下图:

4.1.6.4. 测试方法:

在OrdersMapperTest添加测试方法,如下:

@Test

public void testQueryOrderUser() {

// mybatis和spring整合,整合之后,交给spring管理

SqlSession sqlSession = this.sqlSessionFactory.openSession();

// 创建Mapper接口的动态代理对象,整合之后,交给spring管理

OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);

List<OrderUser> list = ordersMapper.queryOrderUser();

for (OrderUser ou : list) {

System.out.println(ou);

}

// mybatis和spring整合,整合之后,交给spring管理

sqlSession.close();

}

4.1.6.5. 效果

测试结果如下图:

4.1.6.6. 小结

定义专门的Pojo类作为输出类型,其中定义了Sql查询结果集所有的字段。此方法较为简单,企业中使用普遍。

4.2. Collection(关联集合,即一对多)

功能需求:查询所有用户信息及用户关联的订单信息。

Sql语句:

SELECT

u.id,

u.username,

u.birthday,

u.sex,

u.address,

o.id oid,

o.number,

o.createtime,

o.note

FROM

`user` u

LEFT JOIN `orders` o ON u.id = o.user_id

4.2.1. 修改Pojo类

在User类中加入List<Order> orders属性,如下图:

4.2.2. Mapper.xml

在UserMapper.xml添加Sql,如下:

<resultMap type="user" id="userOrderResultMap">

<id property="id" column="id" />

<result property="username" column="username" />

<result property="birthday" column="birthday" />

<result property="sex" column="sex" />

<result property="address" column="address" />

<!-- 配置关联多个对象-->

<collection property="orders" ofType="orders">

<!-- 配置主键,是关联Order的唯一标识 -->

<id property="id" column="oid" />

<result property="number" column="number" />

<result property="createtime" column="createtime" />

<result property="note" column="note" />

</collection>

</resultMap>

<!-- 查询订单同时查询该用户下的所有订单 -->

<select id="queryUserOrder" resultMap="userOrderResultMap">

SELECT

u.id,

u.username,

u.birthday,

u.sex,

u.address,

o.id oid,

o.number,

o.createtime,

o.note

FROM

`user` u

LEFT JOIN `orders` o ON u.id = o.user_id

</select>

4.2.3. Mapper接口

编写UserMapper接口,如下图:

4.2.4. 测试方法

在UserMapperTest增加测试方法,如下

@Test

public void testQueryUserOrder() {

// mybatis和spring整合,整合之后,交给spring管理

SqlSession sqlSession = this.sqlSessionFactory.openSession();

// 创建Mapper接口的动态代理对象,整合之后,交给spring管理

UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

// 使用userMapper执行根据条件查询用户

List<User> list = userMapper.queryUserOrder();

for (User u : list) {

System.out.println(u);

}

// mybatis和spring整合,整合之后,交给spring管理

sqlSession.close();

}

4.2.5. 效果

测试效果如下图:

5. Mybatis整合Spring

5.1. 整合思路

n SqlSessionFactory对象应该放到Spring容器中作为单例存在。

n 传统Dao的开发方式中,应该从Spring容器中获得sqlsession对象。

n Mapper代理形式中,应该从Spring容器中直接获得mapper的代理对象。

n 数据库的连接以及数据库连接池事务管理都交给Spring容器来完成。

5.2. 整合引入的Jar包

n Log4j日志jar包

n Mysql的数据库驱动jar包

n Mybatis的jar包

n Junit测试jar包

n Spring的jar包

n Spring+Mybatis的整合包

n 数据库连接池jar包

5.3. 整合的步骤

5.3.1. 创建Maven工程

5.3.2. 引入Jar包

如下图:

5.3.3. 加入配置文件

  1. Spring的配置文件
  2. Mybatis的配置文件SqlMapConfig.xml

a) 数据库连接及连接池

b) 事务管理(暂时可以不配置)

c) sqlSessionFactory对象,配置到Spring容器中

d) mapper代理对象或者是Dao实现类配置到Spring容器中。

如下图

5.3.3.1. SqlMapConfig.xml

配置文件是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>

<!-- 设置别名 -->

<typeAliases>

<!-- 2. 指定扫描包,会把包内所有的类都设置别名,别名的名称就是类名,大小写不敏感 -->

<package name="com.itheima.mybatis.pojo" />

</typeAliases>

</configuration>

注意:Mybatis与Spring整合之后SqlMapConfig.xml文件不是必须的

5.3.3.2. applicationContext.xml

SqlSessionFactoryBean属于mybatis-spring这个jar包

对于Spring来说,Mybatis是另外一个架构,需要整合jar包。

整合Mybatis需要的是SqlSessionFactoryBean,位置如下图:

applicationContext.xml,配置内容如下

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"

xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd

http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd

http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd">

<!-- 加载配置文件 -->

<context:property-placeholder location="classpath:db.properties" />

<!-- 数据库连接池 -->

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"

destroy-method="close">

<property name="driverClassName" value="${jdbc.driver}" />

<property name="url" value="${jdbc.url}" />

<property name="username" value="${jdbc.username}" />

<property name="password" value="${jdbc.password}" />

</bean>

<!-- 配置SqlSessionFactory -->

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

<!-- 配置mybatis核心配置文件 -->

<property name="configLocation" value="classpath:SqlMapConfig.xml" />

<!-- 配置数据源 -->

<property name="dataSource" ref="dataSource" />

</bean>

</beans>

5.3.3.3. db.properties

jdbc.driver=com.mysql.jdbc.Driver

jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8

jdbc.username=root

jdbc.password=root

5.3.3.4. 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

5.4. Dao的开发

两种Dao的实现方式:

1、原始Dao的开发方式

2、使用Mapper动态代理的开发方式

a) 直接配置Mapper代理

b) 使用扫描包配置Mapper代理

功能需求:实现根据用户id查询一个用户

5.4.1. 创建Pojo

public class User {

private int id;

private String username;// 用户姓名

private String sex;// 性别

private Date birthday;// 生日

private String address;// 地址

get/set。。。

}

5.4.2. 原始Dao的开发方式

需要Dao实现类需要继承SqlsessionDaoSupport类

5.4.2.1. 实现Mapper.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">

<mapper namespace="test">

<!-- 根据用户id查询 -->

<select id="queryUserById" parameterType="int" resultType="user">

select * from user where id = #{id}

</select>

</mapper>

5.4.2.2. 加载Mapper.xml

在SqlMapConfig如下图进行配置:

5.4.2.3. 实现UserDao接口

public interface UserDao {

/**

* 根据id查询用户

*

* @param id

* @return

*/

User queryUserById(int id);

}

5.4.2.4. 实现UserDaoImpl实现类

编写DAO实现类,实现类必须集成SqlSessionDaoSupport

SqlSessionDaoSupport提供getSqlSession()方法来获取SqlSession

public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {

@Override

public User queryUserById(int id) {

// 获取SqlSession

SqlSession sqlSession = super.getSqlSession();

// 使用SqlSession执行操作

User user = sqlSession.selectOne("queryUserById", id);

// 不要关闭sqlSession

return user;

}

}

5.4.2.5. 配置Dao

把Dao实现类配置到Spring容器中,如下图

5.4.2.6. 测试方法

编写测试方法如下:

public class UserDaoTest {

private ApplicationContext context;

@Before

public void setUp() throws Exception {

this.context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");

}

@Test

public void testQueryUserById() {

// 获取userDao

UserDao userDao = this.context.getBean(UserDao.class);

User user = userDao.queryUserById(2);

System.out.println(user);

}

}

5.4.3. Mapper动态代理方式开发Dao

5.4.3.1. 实现Mapper.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">

<mapper namespace="com.itheima.mybatis.mapper.UserMapper">

<!-- 根据用户id查询 -->

<select id="queryUserById" parameterType="int" resultType="user">

select * from user where id = #{id}

</select>

</mapper>

5.4.3.2. 实现UserMapper接口

public interface UserMapper {

/**

* 根据用户id查询

*

* @param id

* @return

*/

User queryUserById(int id);

}

5.4.3.3. 方式一:配置mapper代理

在applicationContext.xml添加配置

MapperFactoryBean也是属于mybatis-spring整合包

<!-- Mapper代理开发方式一,配置Mapper代理对象 -->

<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">

<!-- 配置Mapper接口 -->

<property name="mapperInterface" value="com.itheima.mybatis.mapper.UserMapper" />

<!-- 配置sqlSessionFactory -->

<property name="sqlSessionFactory" ref="sqlSessionFactory" />

</bean>

5.4.3.4. 测试方法

public class UserMapperTest {

private ApplicationContext context;

@Before

public void setUp() throws Exception {

this.context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");

}

@Test

public void testQueryUserById() {

// 获取Mapper

UserMapper userMapper = this.context.getBean(UserMapper.class);

User user = userMapper.queryUserById(2);

System.out.println(user);

}

}

5.4.3.5. 方式二:扫描包形式配置mapper

<!-- Mapper代理开发方式二,扫描包方式配置代理 -->

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">

<!-- 配置Mapper接口 -->

<property name="basePackage" value="com.itheima.mybatis.mapper" />

</bean>

注意:每个mapper代理对象的id就是类名,首字母小写

6. Mybatis逆向工程

使用官方网站的Mapper自动生成工具mybatis-generator-core-1.3.2来生成po类和Mapper映射文件

6.1. 导入逆向工程

使用课前资料已有逆向工程,如下图:

6.1.1. 导入逆向工程到Eclipse中

将逆向工程复制到eclipse工作空间,如下图方式进行导入:

6.2. 修改配置文件

在generatorConfig.xml中配置Mapper生成的详细信息,如下图:

注意修改以下几点:

  1. 修改要生成的数据库表
  2. Pojo文件所在包路径
  3. Mapper所在的包路径

配置文件如下:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE generatorConfiguration

PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"

"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>

<context id="testTables" targetRuntime="MyBatis3">

<commentGenerator>

<!-- 是否去除自动生成的注释 true:是 : false:否 -->

<property name="suppressAllComments" value="true" />

</commentGenerator>

<!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->

<jdbcConnection driverClass="com.mysql.jdbc.Driver"

connectionURL="jdbc:mysql://localhost:3306/mybatis" userId="root" password="root">

</jdbcConnection>

<!-- <jdbcConnection driverClass="oracle.jdbc.OracleDriver" connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:yycg"

userId="yycg" password="yycg"> </jdbcConnection> -->

<!-- targetProject:生成PO类的位置 -->

<javaModelGenerator targetPackage="com.itheima.ssm.pojo"

targetProject=".\src">

</javaModelGenerator>

<!-- targetProject:mapper映射文件生成的位置 -->

<sqlMapGenerator targetPackage="com.itheima.ssm.mapper"

targetProject=".\src">

</sqlMapGenerator>

<!-- targetPackage:mapper接口生成的位置 -->

<javaClientGenerator type="XMLMAPPER"

targetPackage="com.itheima.ssm.mapper" targetProject=".\src">

</javaClientGenerator>

<!-- 指定数据库表 -->

<table schema="" tableName="user"></table>

<table schema="" tableName="orders"></table>

</context>

</generatorConfiguration>

6.3. 生成逆向工程代码(能够使用)

找到下图所示的Java文件,执行工程main主函数

刷新工程,发现代码生成,如下图:

6.4. 测试逆向工程代码

1. 复制生成的代码到mybatis-day02-315-spring工程,如下图

2. 修改Spring配置文件

在applicationContext.xml修改

<!-- Mapper代理的方式开发,扫描包方式配置代理 -->

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">

<!-- 配置Mapper接口,如果需要加载多个包,直接写进来,中间用,分隔 -->

<!-- <property name="basePackage" value="com.itheima.mybatis.mapper" /> -->

<property name="basePackage" value="com.itheima.ssm.mapper" />

</bean>

3. 编写测试方法:

public class UserMapperTest {

private ApplicationContext context;

@Before

public void setUp() throws Exception {

this.context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");

}

@Test

public void testInsert() {

// 获取Mapper

UserMapper userMapper = this.context.getBean(UserMapper.class);

User user = new User();

user.setUsername("曹操");

user.setSex("1");

user.setBirthday(new Date());

user.setAddress("三国");

userMapper.insert(user);

}

@Test

public void testSelectByExample() {

// 获取Mapper

UserMapper userMapper = this.context.getBean(UserMapper.class);

// 创建User对象扩展类,用户设置查询条件

UserExample example = new UserExample();

example.createCriteria().andUsernameLike("%王%");

// 查询数据

List<User> list = userMapper.selectByExample(example);

System.out.println(list.size());

}

@Test

public void testSelectByPrimaryKey() {

// 获取Mapper

UserMapper userMapper = this.context.getBean(UserMapper.class);

User user = userMapper.selectByPrimaryKey(2);

System.out.println(user);

}

}

注意:

    1. 逆向工程生成的代码只能做单表查询
    2. 不能在生成的代码上进行扩展,因为如果数据库变更,需要重新使用逆向工程生成代码,原来编写的代码就被覆盖了
    3. 一张表会生成4个文件

原文地址:https://www.cnblogs.com/shan1393/p/9307272.html

时间: 2024-11-05 17:55:58

mybatis第二天的相关文章

关于整合spring+mybatis 第二种方式

和第一种方式一样的步骤,不过bean.xml中有些许差异 <!-- 配置sqlSessionFactory --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property&g

mybatis第二天——大纲待更新

大纲摘要: 1.输入映射和输出映射 a) 输入参数映射 b) 返回值映射 2.动态sql a) If b) Where c) Foreach d) Sql片段 3.关联查询 a) 一对一关联 b) 一对多关联 4.Mybatis整合spring 一.输入映射和输出映射 1.输入映射 也就是day01提到的入参 传递简单类型:见day01,这里不再赘述 传递POJO包装类型: 开发中通过pojo传递查询条件 ,查询条件是综合的查询条件, 不仅包括用户查询条件还包括其它的查询条件(比如将用户购买商品

MyBatis源码解读(1)——SqlSessionFactory

在前面对MyBatis稍微有点了解过后,现在来对MyBatis的源码试着解读一下,并不是解析,暂时定为解读.所有对MyBatis解读均是基于MyBatis-3.4.1,官网中文文档:http://www.mybatis.org/mybatis-3/zh/getting-started.html,MyBatis-3.4.1.jar. 本应在开始读MyBatis源码时首先应该了解下MyBatis的SqlSession的四大对象:Executor.StatemenHandler.ParameterHa

mybatis学习第(二)天

Mybatis第二天    高级映射   查询缓存 关于与spring的整合和反转工程我偷懒了,下次看. 使用的sql: CREATE TABLE USER( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(32) NOT NULL, -- 用户名称 birthday DATE, -- 生日 sex CHAR(1), -- 性别:1表示男,2表示女 address VARCHAR(256) -- 地址 ); CREATE TABLE ord

JAVAEE——SpringMVC第一天:介绍、入门程序、架构讲解、SpringMVC整合MyBatis、参数绑定、SpringMVC和Struts2的区别

1. 学习计划   第一天 1.SpringMVC介绍 2.入门程序 3.SpringMVC架构讲解 a) 框架结构 b) 组件说明 4.SpringMVC整合MyBatis 5.参数绑定 a) SpringMVC默认支持的类型 b) 简单数据类型 c) Pojo类型 d) Pojo包装类型 e) 自定义参数绑定 6.SpringMVC和Struts2的区别   第二天 1.高级参数绑定 a) 数组类型的参数绑定 b) List类型的绑定 2.@RequestMapping注解的使用 3.Con

20160526-20160531mybatis入门进阶

mybatis第二天  高级映射 查询缓存 和spring整合 课程复习: mybatis是什么? mybatis是一人持久层框架,mybatis是一个不完全的ORM框架.sql语句需要程序员自己去编写,但是mybatis也有映射(输入参数映射.输出结果映射). mybatis入门门槛不高,学习成本低,让程序员把精力放在sql语句上,对sql语句优化非常方便,适用与需求变化较多项目,比如互联网项目. mybatis框架执行过程: 1.配置mybatis的配置文件,SqlMapConfig.xml

最新大数据24期 共十天高清视频教程 附课件源码

课程目录: 大数据24期-01-JavaSE基础-15天 第一天: 01.什么是计算机软件02.什么数据软件开发--利用编程语言来写剧本03.什么是jdk--怎么安装jdk03.什么是jdk--怎么安装jdk04.安装启动eclipse04.安装启动eclipse05.配置eclipse的字体和布局06.新建一个java的类的步骤07.第一个java编程作品--HelloWorld08.java中的变量定义和变量赋值语法09.第一个java程序中的知识点梳理--终端输入--终端输出10.第二个j

【MyBatis框架】MyBatis入门程序第二部分

我们通过写一个简单的MyBatis小项目来在实战中学习MyBatis,接着上一篇继续 我们开始实现需求中的添加和删除用户功能 (1)向数据库中添加用户数据 使用User.xml,加入添加用户的sql语句. [html] view plain copy <!-- 添加用户 parameterType:指定输入参数类型是pojo(包括用户信息) #{}中指定POJO的属性名,接收到POJO对象的属性值,mybatis通过OGNL获取对象的属性 --> <insert id="ins

Java Persistence with MyBatis 3(中文版) 第二章 引导MyBatis

MyBatis最关键的组成部分是SqlSessionFactory,我们可以从中获取SqlSession,并执行映射的SQL语句.SqlSessionFactory对象可以通过基于XML的配置信息或者Java API 创建. 我们将探索各种MaBatis配置元素,如dataSource,environments,全局参数设置,typeAlias,typeHandlers,SQL映射:接着我们将实例化SqlSessionFactory. 本章将涵盖一下内容: l  使用 XML配置MyBatis