一、mybatis介绍
mybatis是一个持久层的框架,让程序将主要精力放在sql上,通过mybatis提供的映射方式,自由灵活生成(半自动化,大部分需要程序员编写sql)满足需要sql语句,mybatis可以将向 preparedStatement中的输入参数自动进行输入映射,将查询结果集灵活映射成java对象。(输出映射)。
二、框架介绍
1、创建全局配置文件,SqlMapConfig.xml,名称是不固定的,用于配置了数据源、事务,映射文件(配置sql),等mybatis运行环境
2、SqlSessionFactory(会话工厂),根据配置文件创建工厂。作用:用于创建SqlSession
3、SqlSession(会话),是一个接口,面向用户(程序员)的接口。作用:操作数据库(发出sql增、删、改、查)
4、Executor(执行器),是一个接口(基本执行器、缓存执行器)。作用:SqlSession内部通过执行器操作数据库
三、实现增删改查
1、创建数据库配置文件 db.properties
配置连接mysql数据库的基本信息
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=1234
2、创建全局配置文件 SqlMapConfig.xml
添加一些必须的配置
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理,事务控制由mybatis-->
<transactionManager type="JDBC" />
<!-- 数据库连接池,由mybatis管理-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<!-- 别名定义 -->
<typeAliases>
<!-- 针对单个别名定义
type:类型的路径
alias:别名
-->
<!-- <typeAlias type="cn.itcast.mybatis.po.User" alias="user"/> -->
<!-- 批量别名定义
指定包名,mybatis自动扫描包中的po类,自动定义别名,别名就是类名(首字母大写或小写都可以)
-->
<package name="com.dd.mybatis.po"/>
</typeAliases>
3、创建mapper接口
public interface UserMapper {
public User findUserById(int id) throws Exception;
// 添加信息
public void insertToUser(User user)throws Exception;
// 删除信息
public void deleteToUser(Integer id)throws Exception;
public void updateUser(User user) throws Exception;
}
4、创建mapper.xml映射文件
创建UserMapper.xml
<mapper namespace="com.dd.mapper.UserMapper">
<select id="findUserById" parameterType="int" resultType="user">
SELECT * FROM USER WHERE id=#{value}
</select>
<insert id="insertUser" parameterType="com.dd.mybatis.po.User">
insert into user(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="com.dd.mybatis.po.User">
update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}
where id=#{id}
</update>
</mapper>
将映射文件加入全局配置文件
<mappers>
<!-- 批量加载mapper
指定mapper接口的包名,mybatis自动扫描包下边所有mapper接口进行加载
遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录 中
上边规范的前提是:使用的是mapper代理方法
-->
<package name="com.dd.mapper"/>
</mappers>
5、创建pojo实体类User.java
public class User implements Serializable{
private static final long serialVersionUID = 1L;
//属性名和数据库表的字段对应
private int id;
private String username;// 用户姓名
private String sex;// 性别
private Date birthday;// 生日
private String address;// 地址
// 订单信息
private List<Orders> ordersList;
public List<Orders> getOrdersList() {
return ordersList;
}
public void setOrdersList(List<Orders> ordersList) {
this.ordersList = ordersList;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", sex=" + sex
+ ", birthday=" + birthday + ", address=" + address + "]";
}
}
6、mapper代理开发规范
1)、在mapper.xml中namespace等于mapper接口地址
2)、mapper.java接口中的方法名和mapper.xml中statement的id一致,如下面
public User findUserById(int id) throws Exception; //方法名是 findUserById
/statement的id也是findUserById
SELECT * FROM USER WHERE id=#{value}
3)、mapper.java接口中的方法输入参数类型和mapper.xml中statement的parameterType指定的类型一致
4)、mapper.java接口中的方法返回值类型和mapper.xml中statement的resultType指定的类型一致。
7、代码实现与测试
@Before – 表示在任意使用@Test注解标注的public void方法执行之前执行
@Test – 使用该注解标注的public void方法会表示为一个测试方法
1)首先加载配置文件,和创建会话工厂,另外已经前提建好数据库和表
@Before
SqlSessionFactory sqlSessionFactory;
public void before() throws Exception {
// mybatis配置文件
String resource = "SqlMapConfig.xml";
// 得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
// 创建会话工厂,出入文件配置流
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
2)通过ID查询一条信息
@Test
public void findUserBtId() throws Exception {
SqlSession sqlSession = null;
try {
sqlSession = sqlSessionFactory.openSession();
// 创建UserMapper对象,mybatis自动生成UserMapper代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.findUserById(1);
System.out.println(user);
} catch (Exception e) {
// TODO: handle exception
}finally{
// 关闭资源
sqlSession.close();
}
}
3)插入数据
@Test
public void insertUser()throws Exception{
SqlSession sqlSession=null;
try {
sqlSession=sqlSessionFactory.openSession();
User user=new User();
user.setUsername("小强");
user.setSex("男");
user.setBirthday(new Date());
user.setAddress("商洛");
// 创建UserMapper对象,mybatis自动生成UserMapper代理对象
UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
userMapper.insertToUser(user);
// 提交数据
sqlSession.commit();
} catch (Exception e) {
// TODO: handle exception
}finally{
sqlSession.close();
}
}
4)、修改数据
@Test
public void updateUser() throws Exception{
SqlSession sqlSession=null;
try {
sqlSession=sqlSessionFactory.openSession();
User user=new User();
user.setId(27);
user.setUsername("小强");
user.setSex("男");
user.setBirthday(new Date());
user.setAddress("商洛洛南");
// 创建UserMapper对象,mybatis自动生成UserMapper代理对象
UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
userMapper.updateUser(user);
sqlSession.commit();
} catch (Exception e) {
// TODO: handle exception
}finally{
sqlSession.close();
}
}
5)删除数据
@Test
public void deteteUser() throws Exception{
SqlSession sqlSession=null;
try {
sqlSession=sqlSessionFactory.openSession();
// 创建UserMapper对象,mybatis自动生成UserMapper代理对象
UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
userMapper.deleteToUser(27);
sqlSession.commit();
}catch(Exception e){
}finally{
sqlSession.close();
}
}
8、总结
列出原始Dao开发的部分代码进行比较
1)接口方法
2)实现方法
3)测试
存在的问题
- 调用sqlsession方法时将statement的id硬编码了
- 调用sqlsession方法时传入的变量,由于sqlsession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,不利于程序员开发。
mapper代理方法总结
1)代理对象内部调用selectOne或selectList
如果mapper方法返回单个pojo对象(非集合对象),代理对象内部通过selectOne查询数据库。
如果mapper方法返回集合对象,代理对象内部通过selectList查询数据库。
2)接口方法参数只能有一个,系统是否不利于扩展维护
可以使用包装类型的pojo满足不同的业务方法的需求