mybatis学习02.4 基于配置文件开发

数据准备

表结构

idint(11)
usernamevarchar(32)
birthdaydatatime
sexchar(1)
addressvarchar(256)

实体类属性

private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;

注:

1、持久层接口和持久层接口的映射配置必须在相同的包下
例如
接口层 src.main.java.com.hncj.dao.IUserDao.java
接口层的映射配置文件 src/main/resources/com/hncj/dao/IUserDao.xml
2、持久层映射配置中 mapper 标签的 namespace 属性取值必须是持久层接口的全限定类名
3、SQL 语句的配置标签< select>,< insert>,< delete>,< update>的 id 属性必须和持久层接口的方法名相同。

1 单表CRUD

1.1 根据 ID 查询

  • 应用场景
    单表查询操作,基本的传入参数,获取指定行信息。
  • 需求分析
    通过传入用户的 userId,返回该用户的所有信息
  1. 在持久层接口 IUserDao.java 中添加 findById 方法
	User findById(Integer userId);
  1. 在用户的映射文件 IUserDao.xml 中配置
<select id="findById" resultType="com.hncj.domain.User" parameterType="int">
	select * from user where id = #{uid}
</select>
  1. 添加测试方法
//核心代码
public void testFindOne(){
	User user = userDao.findById(50);
	System.out.println(user);
}

1.2 保持操作

  • 应用场景
    单表插入操作,传入参数,插入数据库。
  • 需求分析
    插入一个新增用户,使其 userId 是自增长,其他字段信息是自定义的。
  1. 在持久层接口 IUserDao.java 中添加 findById 方法
	int saveUser(User user);
  1. 在用户的映射文件 IUserDao.xml 中配置
<insert id="saveUser" parameterType="com.hncj.domain.User">
	insert into user(username,birthday,sex,address) value(
		#{username},#{birthday},#{sex},#{address}
	);
</insert>
  1. 添加测试方法
//核心代码
public void testSave(){
	User user = new User();
	user.setUsername("河南人");
	user.setAddress("河南");
	user.setSex("男");
	user.setBirthday(new Date());
	userDao.saveUser(user);
	//需要实现事务提交,才能插入成功
}

1.3 新增用户 id 的返回值

  • 应用场景
    单表插入操作,传入参数,插入数据库,并返回指定行信息。
    相当于先执行一条插入操作,再执行一条查询操作并返回指定行信息。

  • 需求分析
    新增用户后,同时返回新增用户的 id 值。

  1. 在持久层接口 IUserDao.java 中添加 saveUser 方法
	int saveUser(User user);
  1. 在用户的映射文件 IUserDao.xml 中配置
<insert id="saveUser" parameterType="com.hncj.domain.User">
	<selectKey keyColumn="id" keyProperty="id“ resultType="int”
		select last_insert_id();
	</selectKey>
	insert into user(username,birthday,sex,address) value(#{username},#{birthday},#{sex},#{address}
);
</insert>
  1. 添加测试方法
//核心代码
public void testSave(){
	Integer last_insert_id = null;
	User user = new User();
	user.setUsername("河南人");
	user.setAddress("河南");
	user.setSex("男");
	user.setBirthday(new Date());
	last_insert_id = userDao.saveUser(user);
	System.out.println("新增用户的 ID 为:"+ last_insert_id);
	//需要实现事务提交,才能插入成功
}

1.4 用户更新

  • 应用场景
    单表更新操作,传入参数,对指定行信息进行修改。
  • 需求分析
    传入 user 用户参数,将 id 字段作为修改用户信息的标志,修改其他字段。
  1. 在持久层接口 IUserDao.java 中添加 updateUser 方法
	User updateUser(Integer userId);
  1. 在用户的映射文件 IUserDao.xml 中配置
<update id="updateUser" parameterType="com.hncj.domain.User">
	update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
</update>
  1. 添加测试方法
//核心代码
public void testUpdate(){
	User user = userDao.findById(50
	user.setAddress("平顶山");
	int res = userDao.updateUser(user);
	System.out.println(res);
}

1.5 删除用户

  • 应用场景
    单表删除操作,传入参数,删除指定行信息。
  • 需求分析
    根据用户的 userId 去删除该用户信息。
  1. 在持久层接口 IUserDao.java 中添加 deleteUser 方法
	int deleteUser(Integer userId);
  1. 在用户的映射文件 IUserDao.xml 中配置
<delete id="deleteUser" parameterType="int">
	delete from user where id = #{uid}
</delete>
  1. 添加测试方法
//核心代码
public void testDelete(){
	userDao.deleteUser(52);
	System.out.println(res);
}

1.6 用户模糊查询

  • 应用场景
    单表模糊查询操作,传入参数,返回指定行信息。
  • 需求分析
    通过用户的 username 字段信息,去模糊查询这个用户表,并将所有符合条件的用户信息返回到一个 List 集合中。
  1. 在持久层接口 IUserDao.java 中添加 findByName方法
	List<User> findByName(String username);
  1. 在用户的映射文件 IUserDao.xml 中配置
<selete id="findByName" resultType="com.hncj.domain.User" parameterType="String">
	<!-- 模糊查询方式一:-->
	select * from user where username like #{username}
	<!-- 模糊查询方式二:-->
	select * from user where username like '%${value}%'
</select>
  1. 添加测试方法
//核心代码
public void testFindByName(){
	//模糊方式一:
	List<User> users = userDao.findByName("%王%");
	//模糊方式儿:
	List<User> users = userDao.findByName("王");
	for(User user : users)
		System.out.println(user);
}

1.7 查询使用聚合函数

  • 应用场景
    聚合函数的使用。

  • 需求分析
    查询符合用户表中的用户数量。

  1. 在持久层接口 IUserDao.java 中添加 findTotal 方法
	int findTotal();
  1. 在用户的映射文件 IUserDao.xml 中配置
<select id="findTotal" resultType="int">
	select count(*) from user;
</select>
  1. 添加测试方法
//核心代码
public void testFindTotal() throws Exception {
	int res = userDao.findTotal();
	System.out.println(res);
}

1.8 总结

1.8.1 #{}和${}的区别

1、#{}是预编译处理,${}是字符串替换。
2、Mybatis 在处理#{}时,会将 sql 中的#{}替换为?号,调用 PreparedStatement 的 set 方法来赋值;
3、Mybatis 在处理时 , 就 是 把 {}时,就是把时,就是把{}替换成变量的值。
4、使用#{}可以有效的防止 SQL 注入
SQL 语句的配置标签< select>,< insert>,< delete>,< update>

1.8.2 模糊查询like语句的三种书写方式

<!-- like #{}方式-->
select * from user where username like #{username}
<!-- like '%${}%'字符串拼接方式 -->
select * from user where username like '%${value}%'
<!-- like CONCAT('%', #{}, '%') 方式-->
select * from user where username like CONCAT('%', #{name}, '%')
<!-- like + bind标签 + #{}方式-->
<select id="findConcat" parameterType="String" resultType="com.hncj.domain.User"  >
        <bind name="name" value="'%' + _parameter + '%'"/>
        select * from user where username like #{name}
</select>

1、’%${name}%’ 可能引起SQL注入,不推荐

2、"%"#{name}"%" ,这样的形式是无效的,因为#{…}解析成sql语句时候,会在变量外侧自动加单引号’ ',所以这里 % 需要使用双引号" ",不能使用单引号 ’ ',不然会查不到任何结果

3、可以使用 concat()函数,concat(’%’,#{name},’%’),也是一种模糊查询的方式。

<select id="findConcat" resultType="com.hncj.domain.Users" parameterType="com.test.Param">
	select * from user where username like CONCAT('%', '${name}', '%')
</select>

(4)使用bind标签

1.8.2 规范化操作

1、id 属性要与持久层接口方法保持一致
2、parameterType 值为全限定类名,用于对SQL语句的占位符进行传入参数
3、resultType 值为全限定类名,用于将 SQL 语句的执行结果封装到其中
4、resultMap 在表字段名 和 类属性不一致时候,可以自定义 两者的映射关系

2 动态 SQL 语句

2.1 if标签

  • 应用场景
    多条件组合查询,需要在 SQL 后添加 where 1=1 用于字符拼接。
  • 需求分析
    根据用户信息,查询用户列表,并返回到 List 集合中。
  1. 在持久层接口 IUserDao.java 中添加 findByUser 方法
	List<User> findByUser(User user);
  1. 在用户的映射文件 IUserDao.xml 中配置
<select id="findByUser" resultType="user" parameterType="user">
	select * from user where 1=1
	<if test="username=!=null and username!='' ">
		and username like #{username}
	</if>
	<if test="address!=null">
		and address like #{address}
	</if>
</select>
<!-- <if>标签的 test 属性中写的是对象的属性名 -->
  1. 添加测试方法
//核心代码
public void testFindByUser() {
	User u = new User();
	u.setUsername("%王%");
	u.setAddress("%顺义%");
	List<User> users = userDao.findByUser(u);
	for(User user : users) 
		System.out.println(user);
}

2.2 where标签

  • 应用场景
    多条件组合查询时,传入多个参数,简化 if 标签的 where 1=1 条件拼接。
  • 需求分析
    根据用户信息查询,并将查询结果返回到 List 集合中。

简化 使用 if 标签而带来的 where 1=1 的条件拼装,可以采用< where>标签来简化

<select id="findByUser" resultType="user" parameterType="user">
	select * from user where 1=1
	<where> 
		<if test="username"!=null and username!='' ">
			and username like #{username}
		</if>
		<if test="address!=null">
			and address like #{address}
		</if>
	</where>
</select>

2.3 foreach标签

  • 应用场景
    范围查询时,传入多个参数,需要将多个参数,动态添加进去。
  • 需求分析
    通过参入多个用户 userId 信息,将对应的用户信息返回到 List 集合中。
  1. 在持久层接口 IUserDao.java 中添加 findInIds 方法
	List<User> findInIds(QueryVo vo);
  1. 在用户的映射文件 IUserDao.xml 中配置
<select id="findInIds" resultType="user" parameterType="queryvo">
	select * from user where id in 
	<!-- include 导入简化后对的Sql 语句-->
	<!--
	<include refid="defaultsql"> </include>
	-->
	<where>
		<if test="ids!=null and ids.size() > 0"
			<foreach collection="ids" open="id in ("close=")" item="uid" 
separator=",">
				#{uid}
			</foreach>
		</if> 
	</where>
</select>
  1. 添加测试方法
//核心代码
public void testFindByUser() {
	QueryVo vo = new QueryVo();
	List<Integer> ids = new ArrayList<Integer>();
	ids.add(41);
	ids.add(42);
	ids.add(43);
	ids.add(46);
	ids.add(57);
	vo.setIds(ids);
	List<User> users = userDao.findInIds(vo);
	for(User user : users) 
		System.out.println(user);
}

2.4 简化 SQL 片段

  1. 定义简化的 SQL 片段
<sql id="defaultSql">
	select * from user
</slq>
  1. 引用代码片段
<select id="findAll" resultType="user"> 
	<include refid="defaultSql"></include>
</select>

3 多表查询

3.1 一对一

  • 应用场景
    跨表操作,涉及到不止一个实体类对象时。
  • 需求分析
    查询所有账户信息,并关联查询下单用户信息。

实体类属性

//用户实体类属性 User.java
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
//账号实体类属性 Account.java
private Integer id;
private Integer uid;
private Double money;
private User user;
  1. 在持久层接口 AccountDao.java 中添加 findInIds 方法
	List<Account> findAll();
  1. 在账户的映射文件 AccountDao.xml 中配置

由于表字段与类属性不能完全对应,需使用 resultMap建立映射关系

<resultMap type="account" id="accountMap"> <id column="aid" property="id"/>
	<result column="uid" property="uid"/>
	<result column="money" property="money"/>
	<!-- 它是用于指定从表方的引用实体属性的 --> 
	<association property="user" javaType="user">
	<id column="id" property="id"/>
	<result column="username" property="username"/>
	<result column="sex" property="sex"/>
	<result column="birthday" property="birthday"/>
	<result column="address" property="address"/>
	</association>
</resultMap>

<select id="findAll" resultType="accountuser">
	select * a.*,u.username,u.address from account a,user u
		where a.uid = u.id
</select>
  1. 添加测试方法
public void testFindAll() {
	List<Account> accounts = accountDao.findAll();
	for(Account au : accounts) {
		System.out.println(au);
		System.out.println(au.getUser());
	}
}

3.2 一对多

  • 应用场景
    跨表查询,一个实体类对应多个实体类。涉及到跨表操作的 左/右外连接。
  • 需求分析
    用户信息和他的账户信息为一对多关系,
//账户实体类对象 Account.java
private Integer id;
private Integer uid;
private Double money;
//用户实体类对象 User.java
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
private List<Account> accounts;
  1. 在持久层接口 UserDao.java 中添加 findAll 方法
	List<User> findAll();
  1. 在用户的映射文件 UserDao.xml 中配置

由于表字段与类属性不能完全对应,需使用 resultMap建立映射关系

<select id="findAll" resultMap="userMap">
select u.*,a.id as aid ,a.uid,a.money from user u left outer join account 
a on u.id =a.uid
</select>
  1. 添加测试方法
public void testFindAll() {
	List<User> users = userDao.findAll();
	for(User user : users) {
		System.out.println("------------");
		System.out.println(user);
		System.out.println(user.getAccounts());
	} 
}

3.3 多对多

  • 应用场景
    跨表操作,以及中间表构建连接等操作。
  • 需求分析
    一个用户对应多种角色,一种角色对应多个用户。

多对多的关系映射:一个角色可以赋予多个用户

//角色实体类
private Integer roleId;
private String roleName;
private String roleDesc;
private List<User> users; 
  1. 在持久层接口 IRoleDao.java 中添加 findAll 方法
	List<Role> findAll();
  1. 在角色的映射文件 IRoleDao.xml 中配置
<select id="findAll" resultMap="roleMap">
 select u.*,r.id as rid,r.role_name,r.role_desc from role
 left outer join user_role ur on r.id = ur.rid
 left outer join user u on u.id = ur.uid
  1. 添加测试方法
public void testFindAll(){
	List<Role> roles = roleDao.findAll();
	for(Role role : roles){
		 System.out.println("---每个角色的信息----");
		 System.out.println(role);
		 System.out.println(role.getUsers());
	 }
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值