Mybatis学习笔记之二:在项目中使用Mybatis
2017-07-09 22:36
369 查看
在开发之前,需要做好以下准备工作:
1、JDK以及IDE已经配置完成
2、数据库安装完成
3、相关依赖(Mybatis的jar文件以及JDBC的驱动)
笔者这儿使用的是JDK8,开发工具STS,数据库Mysql 5.6.26,Mybatis版本3.3。
准备好上诉工作就可以开始编写了。
1、创建数据库以及表
2、创建项目并将依赖的jar包加入到类路径中。
3、编写mybatis的配置文件mybatis-config.xml(名字可以随意命名)以及数据库连接配置文件
db.properties
4、编写实体类(略)以及实体类的配置文件,配置文件名最好以mapper结尾。
UserMapper.xml
userMapper配置文件只写了插入和查找,可以自己补全删除、更新语句。
5、使用Mybatis操纵数据
使用Mybatis有好几种方式,先介绍最基本的。
5.1、直接使用Mybatis的session进行操作。
先写一个工具类SqlSessionUtil.java
IUserDao.java
实现类UserDao.java
我们约定统一配置,插入数据id为save、删除delete、更新update、列表list。然后编写一个IBaseDao.java
这儿使用了泛型,因为不知道实际添加时是什么类型的对象。
继续编写BaseDao.java
继续编写IUserDao.java
这个接口中什么方法也没有,因为公共方法已经写进IBaseDao中了,我们可以在这里面写User对象独有的方法,这儿继承IBaseDao需要指定具体实现类型。
编写UserDao.java
接下来做下测试吧!
成功了,让我们看看下一种使用方式吧!
5.3、使用接口
在5.2中使用的是类,Mybatis还提供了一种接口的使用方式。
使用方式如下:
与使用类一致,也可以写一个IBaseDao来简化代码,这儿就不再赘述了。接口里面的方法要与配置文件中的id相对应,如果接口方法名不存在于配置文件中会报错。
这种方式可以有代码提示,即到底配置文件中有哪些sql语句(前提是保证接口中方法与配置文件中id一一对应)。
特别注意:session.getMapper(class类型)中的class类型
例如:IUserDao的全称限定名是org.yamikaze.dao.impl.IUserDao,那么userMapper配置文件中的命名空间就一定是这个字符串,否则会报错。
1、JDK以及IDE已经配置完成
2、数据库安装完成
3、相关依赖(Mybatis的jar文件以及JDBC的驱动)
笔者这儿使用的是JDK8,开发工具STS,数据库Mysql 5.6.26,Mybatis版本3.3。
准备好上诉工作就可以开始编写了。
1、创建数据库以及表
2、创建项目并将依赖的jar包加入到类路径中。
3、编写mybatis的配置文件mybatis-config.xml(名字可以随意命名)以及数据库连接配置文件
db.properties
url = jdbc:mysql://localhost:3306/ym_mybatis user = root password = 951001 driver = com.mysql.jdbc.Drivermybatis-config.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> <!--这个properties可以引入外部的配置文件 --> <properties resource="jdbc.properties"/> <!--配置别名,后面会讲有什么作用 --> <typeAliases> <package name="cn.yamikaze.model"/> </typeAliases> <!--配置默认的开发環境 --> <environments default="development"> <!--可以配置多个开发环境,但是外层的默认开发环境必须是配置的其中一个环境 --> <environment id="development"> <!--配置事务管理,这儿使用JDBC的事务 --> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <!--配置与数据库的连接 --> <!--使用${}获取前面引入的配置文件中的值 --> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${user}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments> <!--配置实体类的映射文件(实体类的sql语句存放的文件)--> <mappers> <mapper resource="cn/yamikaze/model/UserMapper.xml"/> </mappers> </configuration>
4、编写实体类(略)以及实体类的配置文件,配置文件名最好以mapper结尾。
UserMapper.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"> <mapper namespace="org.yamikaze.dao.impl.IUserDao"><!--命名空间不能重复--> <!--insert、update、delete、select标签分别对应数据库的相应语句,在同一个配置文件中id属性必须唯一 parameterType表示传进来的参数类型,Mybatis内置了一些类型,比如int、map、string等。而useGenerateKeys 表示会使用JDBC的getGeneratedKeys方法取出数据库自动递增的主键。如果配置了keyProperty属性, 会自动将取出来的主键注入到keyProperty配置的属性中,但这只对insert和update有效--> <insert id="save" parameterType="User" useGeneratedKeys="true" keyProperty="id"> <!--#{}表示一个占位符,类似于JDBC中PreparedStatement的setParameter方法, 中间的值会在传进来的对象中自动查找,例如user对象中有username属性,那么使用#{username} 就会到user中查找username属性,如果没有找到,就会抛出错误--> insert into t_user(username,password,sex) values(#{username},#{password},#{sex}) </insert> <select id="loadByUsername" parameterType="string" resultType="User"> SELECT * FROM t_user WHERE username = #{username} </select> </mapper>还记得在Mybatis-config.xml中配置的typeAliases吗?这儿我们写的参数对象是User,因为配置了别名,所以不用写出User的全称限定名。前面配置的是package=org.yamikaze.model,那么这个包下面的所有类都可以直接使用简单名称。当然你也可以使用typeAlias配置别名,如果有多个实体类包,配置多个package。
userMapper配置文件只写了插入和查找,可以自己补全删除、更新语句。
5、使用Mybatis操纵数据
使用Mybatis有好几种方式,先介绍最基本的。
5.1、直接使用Mybatis的session进行操作。
public static void main(String[] args) { insert(); } public static void insert() { InputStream is = null; SqlSessionFactory factory = null; SqlSession session = null; try { /*读取Mybatis的配置文件,这儿使用的是Mybatis的Resources类,但你可以使用InputStream*/ is = Resources.getResourceAsStream("mybatis-config.xml"); /*通过配置文件获取Mybatis的工场*/ factory = new SqlSessionFactoryBuilder().build(is); /*通过工场打开一个会话*/ session = factory.openSession(); /*创建实体类对象,并设入相应属性*/ User user = new User(); user.setUsername("zs3"); user.setPassword("123"); user.setSex("man"); /*由于是插入数据,这儿使用insert方法,相应的有selectOne方法、selectList、delete方法*/ /*第一个参数表示哪个命名空间里的哪个方法(配置中填写的id属性,所以一个配置文件不能有相同的id) * user是传递的参数*/ session.insert("org.yamikaze.dao.impl.IUserDao.save",user); /** * 注意:如果调用的方法会修改数据库的数据,一定要记得提交,因为Mybatis使用的是JDBC的事务, * JDBC是默认自动提交事务的 * 但Mybatis在通过JDBC获取连接时关闭了自动提交 */ session.commit(); /*因为设置了useGeneratedKeys和keyProperty属性,会自动将ID注入到user对象中*/ System.out.print(user.getId()); } catch (IOException e) { /*修改数据时发生异常记得回滚数据*/ if(session!=null) session.rollback(); } finally { /*关闭session*/ if(session!=null) session.close(); } }5.2、使用类的方式,并且对5.1的方式简化一下,因为在整个程序运行期间,可能会获取多个session,但是读取配置和获取工厂只会获取一次,所以我们可以将这部分提取出来。
先写一个工具类SqlSessionUtil.java
package org.yamikaze.utils; 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 java.io.IOException; import java.io.InputStream; /** * Created by yamikaze */ public class SqlSessionUtil { private static SqlSessionFactory factory; private SqlSessionUtil(){} static { init(); } private static void init(){ try { InputStream is = Resources.getResourceAsStream("mybatis-config.xml"); factory = new SqlSessionFactoryBuilder().build(is); } catch (IOException e) { // System.out.println("读取配置错误"); } } public static SqlSession openSession() { return factory.openSession(); } public static void closeSession(SqlSession session) { if(session!=null) session.close(); } public static void rollback(SqlSession session) { if(session!=null) session.rollback(); } }编写DAO
IUserDao.java
package org.yamikaze.dao.impl; import org.yamikaze.model.User; /** * Created by yamikaze on 2017/7/5. */ public interface IUserDao { public void save(User user); public User loadByUsername(String us 4000 ername); }
实现类UserDao.java
package org.yamikaze.dao.impl; import org.apache.ibatis.session.SqlSession; import org.yamikaze.model.User; import org.yamikaze.utils.SqlSessionUtil; import java.io.IOException; /** * Created by yamikaze on 2017/7/11. */ public class UserDao implements IUserDao{ @Override public User loadByUsername(String username) { return null; } @Override public void save(User user) { SqlSession session = null; try { session = SqlSessionUtil.openSession(); session.insert("org.yamikaze.dao.impl.IUserDao.save",user); session.commit(); } catch (Exception e) { SqlSessionUtil.rollback(session); } finally { SqlSessionUtil.closeSession(session); } } }save方法变得简单了,但现在问题是session的insert方法需要一个id,向上面那样写肯定是不方便的,我们知道org.yamikaze.dao.impl.IUserDao是命名空间,而save是id,如果所有的mapper配置文件中没有重复的id,可以不加上命名空间,如果有就要加上命名空间,但是这种加法不是很方便,我们可以将命名空间改为实体类的全称限定名,然后在代码中使用这种方式:
@Override public void save(User user) { SqlSession session = null; try { session = SqlSessionUtil.openSession(); session.insert(User.class.getName()+".save",user);//与调用session.insert("org.yamikaze.model.User.save",user);是一致的 session.commit(); } catch (Exception e) { SqlSessionUtil.rollback(session); } finally { SqlSessionUtil.closeSession(session); } }这种方式又有一个问题存在,那就是每个实体类都会有save、delete、update等共通的方法,然后你会发现,就方法的参数以及id不同,那么可以使用以下方式再简化一下:
我们约定统一配置,插入数据id为save、删除delete、更新update、列表list。然后编写一个IBaseDao.java
package org.yamikaze.dao.impl; import java.util.List; /** * Created by yamikaze on 2017/7/11. */ public interface IBaseDao<T> { void save(T t); void update(T t); void delete(int id); T load(int id); List<T> listAll(); }
这儿使用了泛型,因为不知道实际添加时是什么类型的对象。
继续编写BaseDao.java
package org.yamikaze.dao.impl; import org.apache.ibatis.session.SqlSession; import org.yamikaze.utils.SqlSessionUtil; import java.lang.reflect.*; import java.util.List; /** * Created by yamikaze on 2017/7/11. */ public class BaseDao <T> implements IBaseDao<T>{ private Class clz; /** * 获取T.class对象, * @return */ protected Class getClz() { Type genType = getClass().getGenericSuperclass(); Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); clz = (Class) params[0]; return clz; } @Override public T load(int id) { SqlSession session = null; try { session = SqlSessionUtil.openSession(); return session.selectOne(getClz().getName()+".load",id); //查找数据,可以不用提交 } catch (Exception e) { SqlSessionUtil.rollback(session); } finally { } return null; } @Override public List<T> listAll() { SqlSession session = null; try { session = SqlSessionUtil.openSession(); return session.selectList(getClz().getName()+".listAll"); } catch (Exception e) { } finally { SqlSessionUtil.closeSession(session); } return null; } @Override public void save(T t) { SqlSession session = null; try { session = SqlSessionUtil.openSession(); session.insert(getClz().getName()+".save",t); session.commit(); } catch (Exception e) { SqlSessionUtil.rollback(session); } finally { SqlSessionUtil.closeSession(session); } } @Override public void delete(int id) { SqlSession session = null; try { session = SqlSessionUtil.openSession(); session.delete(getClz().getName()+".delete",id); session.commit(); } catch (Exception e) { SqlSessionUtil.rollback(session); } finally { SqlSessionUtil.closeSession(session); } } @Override public void update(T t) { SqlSession session = null; try { session = SqlSessionUtil.openSession(); session.update(getClz().getName()+".update",t); session.commit(); } catch (Exception e) { SqlSessionUtil.rollback(session); } finally { SqlSessionUtil.closeSession(session); } } }IBaseDao与BaseDao是针对所有对象的共通的CRUD方法。
继续编写IUserDao.java
package org.yamikaze.dao.impl; import org.yamikaze.model.User; /** * Created by yamikaze on 2017/7/5. */ public interface IUserDao extends IBaseDao<User>{ User loadByUsername(String username); }
这个接口中什么方法也没有,因为公共方法已经写进IBaseDao中了,我们可以在这里面写User对象独有的方法,这儿继承IBaseDao需要指定具体实现类型。
编写UserDao.java
package org.yamikaze.dao.impl; import org.apache.ibatis.session.SqlSession; import org.yamikaze.model.User; import org.yamikaze.utils.SqlSessionUtil; import java.io.IOException; /** * Created by yamikaze on 2017/7/11. */ public class UserDao extends BaseDao<User> implements IUserDao{ public User loadByUsername(String username) { SqlSession session = null; try { session = SqlSessionUtil.openSession(); return session.selectOne(getClz().getName()+".loadByUsername",username); } catch(Exception e) { } finally { SqlSessionUtil.closeSession(session); } return null; } }因为公共方法的实现在BaseDao中实现了,所以我们只实现IUserDao中的方法
接下来做下测试吧!
package org.yamikaze.test; import org.yamikaze.dao.impl.IUserDao; import org.yamikaze.dao.impl.UserDao; import org.yamikaze.model.User; /** * Created by yamikaze on 2017/7/11. */ public class UserDaoTest { public static void main(String[] args) { IUserDao userDao = new UserDao(); User u = new User(); u.setUsername("tom"); u.setSex("man"); u.setPassword("951001"); userDao.save(u); } }测试结果
成功了,让我们看看下一种使用方式吧!
5.3、使用接口
在5.2中使用的是类,Mybatis还提供了一种接口的使用方式。
使用方式如下:
public static void insert() { InputStream is = null; SqlSessionFactory factory = null; SqlSession session = null; try { is = Resources.getResourceAsStream("mybatis-config.xml"); factory = new SqlSessionFactoryBuilder().build(is); session = factory.openSession(); IUserDao userDao = session.getMapper(IUserDao.class); User user = new User(); user.setUsername("zs3"); user.setPassword("123"); user.setSex("man"); userDao.save(user); session.commit(); } catch (IOException e) { e.printStackTrace(); } finally { if(session!=null) session.close(); } }可以看出与使用类的方式相差不大,但是不同的是我们调用的是借口里面的方法。
与使用类一致,也可以写一个IBaseDao来简化代码,这儿就不再赘述了。接口里面的方法要与配置文件中的id相对应,如果接口方法名不存在于配置文件中会报错。
这种方式可以有代码提示,即到底配置文件中有哪些sql语句(前提是保证接口中方法与配置文件中id一一对应)。
特别注意:session.getMapper(class类型)中的class类型
例如:IUserDao的全称限定名是org.yamikaze.dao.impl.IUserDao,那么userMapper配置文件中的命名空间就一定是这个字符串,否则会报错。
相关文章推荐
- Redis学习笔记之二 :在Java项目中使用Redis
- Redis学习笔记之二 :在Java项目中使用Redis
- 【Visual C++】游戏编程学习笔记之二:定时器的使用
- 2、MyBatis.NET学习笔记之CodeSmith使用
- 项目管理学习笔记之二.工作分解
- Maven学习笔记(八)Maven的入门使用—5. 使用Archetype生成项目骨架
- 项目管理学习笔记之二范围管理过程总结
- Cocos2dx 学习笔记整理----在项目中使用图片(二)
- 项目管理学习笔记之二.工作分解
- OC学习笔记二 使用xcode创建项目
- SpringMVC + Spring + MyBatis 学习笔记:在类和方法上都使用RequestMapping如何访问
- directx 学习笔记之一 如何安装并且在visual studio2010的项目中使用directx
- 【Mybatis学习笔记】系列之二:Mybatis双项一对多关联
- 【Git学习笔记】使用GitHub参与开源项目
- 学习使用Alchemy笔记之二
- 使用git 之二 添加与提交(学习笔记二)
- Java学习笔记32:Spring整合mybatis使用
- MyBatis增删改示例——MyBatis学习笔记之二
- 【Visual C++】游戏编程学习笔记之二:定时器的使用
- C#使用mybatis学习笔记