SSM框架整合(二)

3.7添加用户

3.7.1映射文件

在User.xml中配置添加用户的Statement

<!-- 添加用户 
parameterType:指定输入参数类型是pojo(包括用户信息)
#{}中指定pojo的属性名,接收到pojo对象的属性值,mybatis通过OGNL获取对象的属性值
-->
<select id="insertUser" parameterType="cn.itcast.po.User">
insert into users(username,password) values(#{username},#{password})
</select>

3.7.2程序代码

//添加用户信息
	
		@Test
		public void InsertUserTest() throws IOException {
			//mybaits配置文件
			String resource="SqlMapConfig.xml";
			
			InputStream inputStream=Resources.getResourceAsStream(resource);
			//创建回话工厂,传入mybatis的配置文件信息
			SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
			//通过工厂得到SqlSession操作数据库
			SqlSession sqlSession=sqlSessionFactory.openSession();		
			//通过SqlSession操作数据库
			//第一个参数:映射文件中的statement的id,等于namespace+.+statement的id
			//第二个参数:指定和映射文件中所匹配的parameterType类型的参数
			//插入用户对象
			User user=new User();
			user.setUsername("赵信");
			user.setPassword("打野");
			sqlSession.insert("test.insertUser", user);
			//提交事务
			sqlSession.commit();
			//关闭会话
			sqlSession.close();
		}
		

3.7.3自增主键返回

mysql自增主键,执行insert提交之前自动生成一个自增主键

通过mysql函数获取到刚提交记录的自增主键

LAST_INSERT_ID()

是在insert之后调用

3.7.4 非自增主键的返回(使用uuid)

使用mysql的uuid()函数生成主键,需要修改表中字段类型改为string,长度设置35位,

执行思路:

先通过uuid()语句得到主键,

执行uuid()语句顺序相当于insert语句之前执行。

<!-- 使用mysql的uuid()生成主键 
执行过程:
首先通过uuid()得到主键,将主键设置到user对象的id属性,
其次再insert执行时,将user对象中取出uuid的值
uid是User对象的属性,类型必须要和resultType的值对应
 -->
<!-- <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
	select uuid()
</selectKey> 
insert into users(uid,username,password) values(#{uid},#{username},#{password})-->

3.8删除用户

3.8.1删除用户映射文件

<!-- 删除用户
根据id删除用户,需要传入id
 -->
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from users where uid=#{id}
</delete>

3.8.2删除用户代码

//删除用户信息
		
			@Test
			public void DeleteUserTest() throws IOException {
				//mybaits配置文件
				String resource="SqlMapConfig.xml";
				
				InputStream inputStream=Resources.getResourceAsStream(resource);
				//创建回话工厂,传入mybatis的配置文件信息
				SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
				//通过工厂得到SqlSession操作数据库
				SqlSession sqlSession=sqlSessionFactory.openSession();		
				//通过SqlSession操作数据库
				//第一个参数:映射文件中的statement的id,等于namespace+.+statement的id
				//第二个参数:传入id,删除用户
				
				sqlSession.delete("test.deleteUser",7);
			
				//提交事务
				sqlSession.commit();
				//关闭会话
				sqlSession.close();
			}
			
			
			


3.9 更新用户

3.9.1 更新用户映射文件

<!-- 根据id更新用户 
	分析:需要传入用户的id
	需要传入用户的更新消息
	parameterType指定user对象,包括id和更新信息,注意,id必须存在
	#{id}从输入的对象中获取id的属性值,
-->
<update id="updateUser" parameterType="cn.itcast.po.User">
update users set username=#{username},password=#{password} where uid=#{uid}
</update>


3.9.2更新用户代码

//更新用户信息
			
				@Test
				public void UpdateUserTest() throws IOException {
					//mybaits配置文件
					String resource="SqlMapConfig.xml";
					
					InputStream inputStream=Resources.getResourceAsStream(resource);
					//创建回话工厂,传入mybatis的配置文件信息
					SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
					//通过工厂得到SqlSession操作数据库
					SqlSession sqlSession=sqlSessionFactory.openSession();		
					//通过SqlSession操作数据库
					//第一个参数:映射文件中的statement的id,等于namespace+.+statement的id
					//第二个参数:指定和映射文件中所匹配的parameterType类型的参数
					//插入用户对象
					User user=new User();
					//必须设置id
					user.setUid(5);
					user.setUsername("大龙");
					user.setPassword("打打打");
					sqlSession.insert("test.updateUser", user);
				
					//提交事务
					sqlSession.commit();
					//关闭会话
					sqlSession.close();
				}

3.10总结

3.10.1 parameterType

在映射文件中通过parameterType指定输入参数的类型

3.10.2 resultType

在映射文件中通过resultType指定输出结果类型

3.10.3 #{}和${}

#{}表示一个占位符,#{}接收输入参数,可以是简单类型,pojo,hashmap

如果接收简单类型,#{}中可以写成value或其他名称。#{}接收pojo对象值,通过ognl读取对象中的属性值。通过属性.属性.属性....的方式获取。

${}表示一个拼接符号,会引起sql注入,所以不建议使用。

${}接收输入参数,类型可以是简单类型,pojo,hashmap

如果接收简单类型,${}中只能写成value或者其他名称。


3.10.4 selectOne 和selectList

selectOne表示查询出一条记录进行映射。如果使用selectOne可以实现,使用selectList也可以实现

selectList表示查询出一个列表(多条记录)进行映射。selectOne不能够代替。

3.11 mybatis和hibernate本质区别和应用场景

hibernate:  是一个标准的ORM框架(对象关系映射),入门门槛较高的,不需要程序员写sql,sql语句自动生成了。

对sql语句进行优化,修改比较困难。

应用场景:

适用于需求变化不多的中小型项目,比如后台管理系统,erp、orm、o。。。

mybatis:专注的是sql本身,需要程序员自己编写sql语句,sql修改、优化比较方便。mybatis是一个不完全的ORM框架。虽然程序员自己写sql,mybatis也可以实现映射(输入输出)。

应用场景:

适用于需求变化较多的项目,比如:互联网项目。

企业进行技术选型,以低成本,噶火爆作为技术选型原则,根据项目组的技术选型。

4 mybatis开发dao的方法

4.1  SqlSession使用范围

4.1.1 SqlSessionFactoryBuilder

通过SqlSessionFactoryBuilder创建回话工厂sqlSessionFactory

将SqlSessionFactoryBuilder当成一个工具类使用即可,不需要使用单例管理,SqlSessionFactoryBuilder

在需要创建SqlSessionFactory时候,只需要new一次SqlSessionFactoryBuilder即可。


4.1.2 SqlSessionFactory

通过SqlSessionFactory创建SqlSession,适用单例模式管理sqlSessionFactory(工厂一旦创建,适用一个实例)

将来mybatis和spring整合后,适用单例模式管理sqlSessionFactory

4.1.3 SqlSession

SqlSession是一个面向用户(程序员)的接口

SqlSession中提供了很多操作数据库的方法:如selectOne(返回单个对象)、selectLisst(返回单个)

SqlSession是线程不安全的,在SqlSession实现类中,除了有接口中操作数据库的方法,还有数据域属性,

SqlSession最佳应用场合在方法体内,定义成局部变量使用。

4.2 原始dao开发方法(程序员需要些dao接口和dao实现类)

4.2.1 思路

程序员需要些dao接口和dao实现类

需要向dao实现类中注入SqlSessionFactory,在方法体内通过SqlSessionFactory创建SqlSession

4.2.2 测试代码

定义接口。

package cn.itcast.mybatis.dao;

import cn.itcast.po.User;

public interface UserDao {

	//根据id查询用户信息
	public User findUserById(int id)throws Exception;
	
	//添加用户信息
	public void insertUser(User user)throws Exception;
	
	
	//删除用户信息
	public void deleteUser(int id)throws Exception;
	
}

实现接口。

package cn.itcast.mybatis.dao;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import cn.itcast.po.User;

public class UserDaoImpl implements UserDao{

	
	//需要向dao实现类中注入SqlSessionFactory
	
	//这里通过构造方法注入
	private SqlSessionFactory sqlSessionFactory;
	public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
		this.sqlSessionFactory=sqlSessionFactory;
	}
	@Override
	public User findUserById(int id) throws Exception {
		SqlSession sqlSession = sqlSessionFactory.openSession();
		User user = sqlSession.selectOne("test.findUserById", id);
		//释放资源
		sqlSession.close();
		return user;
	}

	@Override
	public void insertUser(User user) throws Exception {
		SqlSession sqlSession = sqlSessionFactory.openSession();
		sqlSession.insert("test.insertUser", user);
		
		//提交事务
		sqlSession.commit();
		
		//释放资源
		sqlSession.close();
	}

	@Override
	public void deleteUser(int id) throws Exception {
		SqlSession sqlSession = sqlSessionFactory.openSession();
		sqlSession.delete("test.deleteUser", id);
		
		//提交事务
		sqlSession.commit();
		
		//释放资源
		sqlSession.close();
		
	}

}

通过测试类进行测试。

package cn.itcast.mybatis.test;

import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import cn.itcast.mybatis.dao.UserDao;
import cn.itcast.mybatis.dao.UserDaoImpl;
import cn.itcast.po.User;

public class UserDaoImplTest {
	
	private SqlSessionFactory sqlSessionFactory;
	//此方法是在执行testFindUserById之前执行
	@Before
	public void setUp()throws Exception{
		//创建sqlSessionFactory
		String resource="SqlMapConfig.xml";
		
		InputStream inputStream=Resources.getResourceAsStream(resource);
		//创建回话工厂,传入mybatis的配置文件信息
		sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
		
	}
	@Test
	public void testFindUserById() throws Exception {
		//创建UserDao的对象
		UserDao userDao = new UserDaoImpl(sqlSessionFactory);
		User user=userDao.findUserById(1);
		System.out.println(user);
		
	}
}

4.2.3 原始dao开发方法问题

1 ,dao接口实现类中存在大量模板方法,摄像能否将这些代码提取出来,打打减轻程序员的工作量,。

2 ,调用sqlsession方法时将statement的id硬编码了。

3 ,调用sqlsession方法时传入的变量,由于sqlsession方法使用泛型,即使变量类型传入错误,也不报错。

4.3 mapper代理方法(程序员只需要mapper接口,相当于dao接口)

4.3.1 思路(mapper开发规范)

程序员还需要编写mapper.xml映射文件

程序员只要编写mapper接口需要遵循一些开发规范,mabatis可以自动将生成mapper接口实现类代理对象。

开发规范:

1 ,在mapper.xml中,namespace等于mapper接口地址。

<!--  namespace命名空间,作用就是对sql进行分了化管理,理解sql隔离
 注意:使用mapper代理方法,namespace有特殊作用 -->
<mapper namespace="cn.itcast.mybatis.mapper.UserMapper">

2 ,mapper.java接口中的方法名和mapper.xml中statement的id一致。

3 ,mapper.java接口中的方法输入参数类型 和mapper.xml中的statement的parameterType指定的类型一致。

4 ,mapper.java接口中的方法返回值类型和mapper.xml中statement的resultType指定的类型一致。

<select id="findUserById" parameterType="int" resultType="cn.itcast.po.User">
	select * from users where uid=#{id}
</select>
配置文件将与接口中定义的方法一一对应,id对应着接口名,parameterType代表传入参数类型,resultType代表返回类型


	//UserMapper.java接口   根据id查询用户信息
	public User findUserById(int id)throws Exception;

总结:

以上开发规范主要对下面代码统一生成,

User user=sqlSession.selectOne("test.findUserById", 1);以及

List<User> list=sqlSession.selectList("test.findUserByName","sa");等

4.3.2 mapper.java

public interface UserMapper {

	//根据id查询用户信息
	public User findUserById(int id)throws Exception;

4.3.3 mapper.xml

<mapper namespace="cn.itcast.mybatis.mapper.UserMapper">

<select id="findUserById" parameterType="int" resultType="cn.itcast.po.User">
	select * from users where uid=#{id}
</select>

4.3.4  在SqlMapConfig.xml中加载mapper.xml

 <!-- 加载映射文件 -->
 <mappers>
 <mapper resource="sqlmap/User.xml"/>
 <mapper resource="mapper/UserMapper.xml"/>
 </mappers>

4.3.5 测试

package cn.itcast.mybatis.test;

import static org.junit.Assert.*;

import java.io.InputStream;

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.Before;
import org.junit.Test;

import cn.itcast.mybatis.mapper.UserMapper;
import cn.itcast.po.User;

public class UserMapperTest {

	private SqlSessionFactory sqlSessionFactory;
	@Before
	public void setUp() throws Exception {
		//创建sqlSessionFactory
		String resource="SqlMapConfig.xml";
		
		InputStream inputStream=Resources.getResourceAsStream(resource);
		//创建回话工厂,传入mybatis的配置文件信息
		sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
	}

	@Test
	public void testFindUserById() throws Exception {
		
		SqlSession sqlSession=sqlSessionFactory.openSession();
		//创建UserMapper对象
		UserMapper userMapper=sqlSession.getMapper(UserMapper.class);//重点
		
		//调用UserMapper的方法
		User user=userMapper.findUserById(2);
		System.out.println(user);
	}

}

4.3.6一些问题的总结

4.3.6。1代理对象内部调用selectOne或者selectList

如果mapper方法返回单个pojo对象(非集合对象),代理对象内部通过selectOne查询数据库,

如果mapper方法返回集合对象selectList查询数据库,如果用selectOne,则会导致报错。


4.3.6.2  mapper接口方法参数只能有一个,是否影响系统开发

mapper接口方法参数只能有一个,系统是否不利于系统维护

系统框架中,dao层的代码是被业务层公用的,即使mapper接口只有一个参数,可以使用包装类型的pojo满足不同的业务方法的需求。

注意:持久层方法的参数可以用包装类型,map.....,service方法中建议不要使用包装类型(不利于业务层的可扩展性)。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值