1.#与$区别:
#{}表示一个占位符号,#{}接收输入参数,类型可以是简单类型,pojo、hashmap。
如果接收简单类型,#{}中可以写成value或其它名称。如:SELECT * FROM USER WHERE id=#{value}
#{}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。
${}表示一个拼接符号,会引用sql注入,所以不建议使用${}。
${}接收输入参数,类型可以是简单类型,pojo、hashmap。
如果接收简单类型,${}中只能写成value。select * from user where username like '%${value}'
${}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。
2.parameterType和resultType
在映射文件中通过parameterType指定输入参数的类型。在映射文件中通过resultType指定输出结果的类型。
3.selectOne和selectList
selectOne表示查询出一条记录进行映射。如果使用selectOne可以实现使用selectList也可以实现(list中只有一个对象)。
selectList表示查询出一个列表(多条记录)进行映射。如果使用selectList查询多条记录,不能使用selectOne。
4.当参数为一个与多个时区别
参数为一个时,写法例:
<select id="findUserById" parameterType="int" resultType="cn.itcast.mybatis.po.User">
SELECT * FROM USER WHERE id=#{value}
</select>
参数为多个时,写法如:
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User" >
insert intouser(username,birthday,sex,address) value(#{username},#{birthday},#{sex},#{address})
</insert>
注:参数为一个时占位符里面的变量可以随意写,当参数为多个时则占位符里的变量要与Bean里的属性对应。
5.正确获得插入记录后的id值
1)mysql中自增主键:
插入语句如果想获得插入的记录的id(主键)则需要在insert语句之上加上如下代码,如不加则输入的结果不正确。
<selectKey keyProperty="id"order="AFTER" resultType="java.lang.Integer"> //AFTER必须大写,指在运行完insert语句之后再执行下面的语句
selectlast_insert_id()
</selectKey>
2)mysql中不自增主键:
需要在同样的位置处写如下代码,注意此时的resultType为String类型
<selectKey keyProperty="id"order="BEFORE" resultType="java.lang.String">
select uuid()
</selectKey>
3)oracle 中通过序列生成主键:
<selectKey keyProperty="id"order="BEFORE" resultType="java.lang.String">
select 序列名.nextval()
</selectKey>
6.入门程序
a.首先要在SqlMapConfig.xml里把你单个的sql语句所在的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>
<!-- 加载 映射文件 -->
<mappers>
<mapper resource="sqlmap/User.xml"/>
</mappers>
</configuration>
b.在你的单独的xml文件里写sql语句,如User.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进行分类化管理,理解sql隔离
注意:使用mapper代理方法开发,namespace有特殊重要的作用
-->
<mapper namespace="test">
<!-- 根据ID查询 -->
<select id="findUserById" parameterType="int" resultType="cn.itcast.mybatis.po.User">
SELECT * FROM USER WHEREid=#{value}
</select>
<!-- 根据名字模糊查询 -->
<select id="findUserByName" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User">
select * from user where usernamelike '%${value}'
</select>
<!-- 插入 -->
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User" >
insert intouser(username,birthday,sex,address)value(#{username},#{birthday},#{sex},#{address})
</insert>
<!-- 删除 -->
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from user where id=#{id}
</delete>
<!-- 更新 -->
<update id="updateUser" parameterType="cn.itcast.mybatis.po.User">
update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}where id=#{id}
</update>
</mapper>
c.测试代码
1)根据ID查询
publicvoid findUserByIdTest() throws IOException{
// mybatis配置文件
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类型的参数
// sqlSession.selectOne结果是与映射文件中所匹配的resultType类型的对象
// selectOne查询出一条记录
User user = sqlSession.selectOne("test.findUserById", 1);
System.out.println(user);
sqlSession.close();
}
2)模糊查询
publicvoid findUserByNameTest() throws IOException{
String resource="SqlMapConfig.xml";
InputStream inputStream=Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory=newSqlSessionFactoryBuilder().build(inputStream);
SqlSessionsqlSession=sqlSessionFactory.openSession();
// list中的user和映射文件中resultType所指定的类型一致
List<User>list=sqlSession.selectList("test.findUserByName", "小明");
System.out.println(list);
sqlSession.close();
}
3)插入
publicvoid insertUserTest() throws IOException{
String resource = "SqlMapConfig.xml";
InputStream inputStream =Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = newSqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession =sqlSessionFactory.openSession();
User user = new User();
user.setUsername("郝晓利");
user.setBirthday(new Date());
user.setSex("1");
user.setAddress("河南郑州");
sqlSession.insert("test.insertUser", user);
// 提交事务
sqlSession.commit();
System.out.println(user.getId());
sqlSession.close();
}
4)删除
publicvoid deleteUserTest() throws IOException{
String resource="SqlMapConfig.xml";
InputStream inputStream=Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory=newSqlSessionFactoryBuilder().build(inputStream);
SqlSessionsqlSession=sqlSessionFactory.openSession();
sqlSession.delete("test.deleteUser",28);
sqlSession.commit();
sqlSession.close();
}
5)更新
publicvoid updateUserTest() throws IOException{
String resource="SqlMapConfig.xml";
InputStream inputStream=Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory=newSqlSessionFactoryBuilder().build(inputStream);
SqlSessionsqlSession=sqlSessionFactory.openSession();
User user=new User();
user.setId(27);
user.setUsername("郝晓利");
user.setAddress("河北邯郸");
user.setBirthday(new Date());
user.setSex("2");
sqlSession.update("test.updateUser", user);
sqlSession.commit();
sqlSession.close();
}
注:除查询外,增、删、改都要提交事务。每个方法的前4行代码都是一样的,只在操作数据库sqlSession处不一样。
7.mybatis和hibernate本质区别和应用场景
hibernate:是一个标准ORM框架(对象关系映射)。入门门槛较高的,不需要程序写sql,sql语句自动生成了。对sql语句进行优化、修改比较困难的。
应用场景:适用与需求变化不多的中小型项目,比如:后台管理系统,erp、orm、oa。。
mybatis:专注是sql本身,需要程序员自己编写sql语句,sql修改、优化比较方便。mybatis是一个不完全的ORM框架,虽然程序员自己写sql,mybatis 也可以实现映射(输入映射、输出映射)。
应用场景:适用与需求变化较多的项目,比如:互联网项目。
8.mybatis开发Dao两种方法
1)原始dao开发方法(程序需要编写dao接口和dao实现类)
需要向dao实现类中注入SqlSessionFactory,在方法体内通过SqlSessionFactory创建SqlSession
如DAO接口:
DAO的实现类:
publicclass 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
publicvoid insertUser(User user) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行插入操作
sqlSession.insert("test.insertUser", user);
// 提交事务
sqlSession.commit();
// 释放资源
sqlSession.close();
}
@Override
publicvoid deleteUser(int id) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行插入操作
sqlSession.delete("test.deleteUser", id);
// 提交事务
sqlSession.commit();
// 释放资源
sqlSession.close();
}
}
测试:
总结Dao方法的缺点:
a.dao接口实现类方法中存在大量模板方法,设想能否将这些代码提取出来,大大减轻程序员的工作量。
b.调用sqlsession方法时将statement的id硬编码了,不利于以后维护。
c.调用sqlsession方法时传入的变量,由于sqlsession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,不利于程序员开发。
2)mybaits的mapper接口(相当于dao接口)代理开发方法
程序员还需要编写mapper.xml映射文件
程序员编写mapper接口需要遵循一些开发规范,mybatis可以自动生成mapper接口实现类代理对象。
后续请看《mybatis基础(二)》