咱们经过写一个简单的MyBatis小项目来在实战中学习MyBatis,接着上一篇继续
咱们开始实现需求中的添加和删除用户功能
(1)向数据库中添加用户数据
使用User.xml,加入添加用户的sql语句。java
<!-- 添加用户 parameterType:指定输入参数类型是pojo(包括用户信息) #{}中指定POJO的属性名,接收到POJO对象的属性值,mybatis经过OGNL获取对象的属性 --> <insert id="insertUser" parameterType="cn.edu.hpu.mybatis.PO.User"> insert into user(username,birthday,sex,address) value(#{username}.#{birthday,jdbcType=DATE}.#{sex},#{address}) </insert>
*注:在字段中有Date和DateTime类型,在插入数据时只要将实体的属性设置成Timestamp就会对应mysql的DateTime类型,Date会对应mysql的Date类型:
#{modified_date,jdbcType=TIMESTAMP}、#{date,jdbcType=DATE}。mysql
测试方法:程序员
//添加用户
sql
@Test public void insertUserTest(){ //mybatis配置文件 String resource="SqlMapConfig.xml"; //将配置文件加载成流 InputStream inputStream; try { inputStream = Resources.getResourceAsStream(resource); //建立会话工厂,传入mybatis配置文件的信息 SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream); //经过工厂获得sqlSession sqlSession=sqlSessionFactory.openSession(); //插入用户对象 User user=new User(); user.setUsername("李云华"); user.setBirthday(new Date()); user.setSex("男"); user.setAddress("云南大理"); //经过SqlSession操做数据库 //第一个参数:映射文件中的statement的Id,等于=namespace+"."+statement的Id //第二个参数:指定和映射文件所匹配的parameterType类型的参数 //sqlSession.selectOne最终结果与你映射文件中所匹配的resultType类型 sqlSession.insert("test.insertUser",user); //提交事务 sqlSession.commit(); } catch (IOException e) { e.printStackTrace(); }finally{ //释放资源 sqlSession.close(); } }
测试结果:
在数据库中插入了
李云华(String), 2015-06-07(Date), 男(String), 云南大理(String)数据库
(2)主键返回
a.自增主键的返回
mysql的自增主键,执行insert以前自动生成一个自增主键
经过mysql函数获取到刚插入记录的自增主键
LAST_INSERT_ID
(当插入一个数据后,当即用这个函数就会返回刚加的主键:SELECT LAST_INSERT_ID())
在刚刚的User.xml中这么写:
apache
<!-- 添加用户 parameterType:指定输入参数类型是pojo(包括用户信息) #{}中指定POJO的属性名,接收到POJO对象的属性值,mybatis经过OGNL获取对象的属性 --> <insert id="insertUser" parameterType="cn.edu.hpu.mybatis.PO.User"> <!-- 将插入数据的主键返回,返回到user对象中。 SELECT_INSERT_ID():获得刚insert进去的主键值,只适用于自增主键 KeyProperty:将查询到主键值设置到parameterType指定对象的哪一个属性。 order:SELECT LAST_INSERT_ID()执行顺序,相对于insert语句来讲它的执行顺序 --> <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer"> SELECT LAST_INSERT_ID() </selectKey> insert into user(username,birthday,sex,address) value(#{username},#{birthday,jdbcType=DATE},#{sex},#{address}) </insert>
咱们在刚刚的方法后面输出user的IDmybatis
//插入用户对象 User user=new User(); user.setUsername("李云华"); user.setBirthday(new Date()); user.setSex("男"); user.setAddress("云南大理"); //经过SqlSession操做数据库 //第一个参数:映射文件中的statement的Id,等于=namespace+"."+statement的Id //第二个参数:指定和映射文件所匹配的parameterType类型的参数 //sqlSession.selectOne最终结果与你映射文件中所匹配的resultType类型 sqlSession.insert("test.insertUser",user); //提交事务 sqlSession.commit(); System.out.println(user.getId());
结果:6
为啥能获得,就是在配置文件里设置了当insert完成以后就把id取出来存到user对象中
b.非自增主键的返回
使用mysql的uuid()函数生成主键,须要修改表中id字段类型为string,长度设置成35位。
执行思路:
先经过uuid()查询到主键,将主键输入到sql语句中。
执行uuid()语句顺序相对于insert语句以前执行。
在刚刚的User.xml中这么写:oracle
<!-- 使用MySql的UUID来生成主键 执行过程: 首先经过uuid()获得主键,将主键设置到user对象的id属性中 其次在insert执行时,从user对象中取出id属性值 --> <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String"> SELECT uuid() </selectKey> insert into user(id,birthday,sex,address) value(#{id},#{birthday,jdbcType=DATE},#{sex},#{address}) 若是使用的数据库是oracle那么经过oracle的序列生成主键写法: <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String"> SELECT 序列名.nextval() </selectKey> insert into user(id,username,birthday,sex,address) value(#{id},#{username},#{birthday,jdbcType=DATE},#{sex},#{address})
映射文件User.xml中添加的语句:框架
<!-- 删除用户 --> <delete id="deleteUser" parameterType="java.lang.Integer"> delete from user where id=#{id} </delete> <!-- 更新用户 分析: 须要传入用户的id,须要传入用户的更新信息. parameterType指定user对象,包括id和更新信息(注意:id必须存在) #{id}:从输入user对象中获取id属性值--> <update id="updateUser" parameterType="cn.edu.hpu.mybatis.PO.User"> update user set username=#{username},birthday=#{birthday,jdbcType=DATE},sex=#{sex},address=#{address} where id=#{id} </update>
测试代码:
删除测试代码:函数
//删除用户 @Test public void deleteUserTest(){ //mybatis配置文件 String resource="SqlMapConfig.xml"; //将配置文件加载成流 InputStream inputStream; try { inputStream = Resources.getResourceAsStream(resource); //建立会话工厂,传入mybatis配置文件的信息 SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream); //经过工厂获得sqlSession sqlSession=sqlSessionFactory.openSession(); //传入id删除用户 sqlSession.delete("test.deleteUser",6); //提交事务 sqlSession.commit(); } catch (IOException e) { e.printStackTrace(); }finally{ //释放资源 sqlSession.close(); } }
测试结果:从数据库删除了id为6的数据
更新测试代码:
//更新用户 @Test public void updateUserTest(){ //mybatis配置文件 String resource="SqlMapConfig.xml"; //将配置文件加载成流 InputStream inputStream; try { inputStream = Resources.getResourceAsStream(resource); //建立会话工厂,传入mybatis配置文件的信息 SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream); //经过工厂获得sqlSession sqlSession=sqlSessionFactory.openSession(); //更新用户信息(更改id=5的用户数据) User user=new User(); user.setId(5); user.setUsername("刘三姐"); user.setBirthday(new Date()); user.setSex("女"); user.setAddress("云南大理"); sqlSession.update("test.updateUser",user); //提交事务 sqlSession.commit(); } catch (IOException e) { e.printStackTrace(); }finally{ //释放资源 sqlSession.close(); } }
测试结果:
id=5的数据被更新
小结:
a.parameterType
在映射文件中经过parameterType指定输入 参数的类型。
b.resultType
在映射文件中经过resultType指定输出结果的类型。
c.#{}和${}
#{}表示一个占位符号,#{}接收输入参数,类型能够是简单类型,pojo、hashmap。
若是接收简单类型,#{}中能够写成value或其它名称。
#{}接收pojo对象值,经过OGNL读取对象中的属性值,经过属性.属性.属性...的方式获取对象属性值。
${}表示一个拼接符号,会引用sql注入,因此不建议使用${}。
${}接收输入参数,类型能够是简单类型,pojo、hashmap。
若是接收简单类型,${}中只能写成value。
${}接收pojo对象值,经过OGNL读取对象中的属性值,经过属性.属性.属性...的方式获取对象属性值。
d.selectOne和selectList
selectOne表示查询出一条记录进行映射。若是使用selectOne能够实现使用selectList也能够实现(list中只有一个对象)。
selectList表示查询出一个列表(多条记录)进行映射。若是使用selectList查询多条记录,不能使用selectOne。
若是使用selectOne报错:
org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 4
最后来讲说hibernate与mybatis,你们若是用过hibernate,刚学mybatis就会很疑惑,mybatis的执行效率并不比 hibernate高多少,并且还要多写sql语句,为何要用它呢?下面来看一下它们的区别,你就会明白mybatis的存在是有必定道理的
看看mybatis和hibernate本质区别和应用场景:hibernate:是一个标准ORM框架(对象关系映射)。入门门槛较高的,不须要程序写sql,sql语句自动生成了。对sql语句进行优化、修改比较困难的。应用场景:适用与需求变化很少的中小型项目,好比:后台管理系统,erp、orm、oa。。mybatis:专一是sql自己,须要程序员本身编写sql语句,sql修改、优化比较方便。mybatis是一个不彻底 的ORM框架,虽然程序员本身写sql,mybatis 也能够实现映射(输入映射、输出映射)。应用场景:适用与需求变化较多的项目,好比:互联网项目。