Mybatis实现简单的数据库增删改查操作
框架:mybatis(3.5.2)
数据库:mysql
工具:idea
<!-- mybatis核心依赖 --> <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>${mybatis.version}</version> </dependency> <!-- mysql驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> </dependency>
2、新建实体类Users、工具类MybatisUtils、数据访问接口UserDao及它的实现类UserDaoImpl
Users类:
private Integer uid; private String userName; public Integer getUid() { return uid; } public void setUid(Integer uid) { this.uid = uid; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; }
MybatisUtils类:
private static SqlSessionFactory sqlSessionFactory; /** * 在静态代码块中初始化工厂 */ static{ //先查找mybatis的核心配置文件来初始化数据源, //默认从classpath下查找核心配置文件 try { //注意:import org.apache.ibatis.io.Resources; InputStream is = Resources.getResourceAsStream("mybatis.xml"); //创建一个SqlSessionFactoryBuilder来解析配置文件的信息, // 然后创建出SqlSessionFactory实例 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); //build方法传入一个输入流,通过解析后返回一个SqlSessionFactory实例 sqlSessionFactory = builder.build(is); } catch (IOException e) { e.printStackTrace(); } } /** * 提供一个获取SqlSession的方法 * @param autoCommit 在获取SQL Session时可以传递一个boolean类型的参数值, * 这个参数的作用似乎用于设置是否手动提交事务还是自动提交事务, * false为手动提交,true为自动提交 * @return */ public static SqlSession getSqlSession(boolean autoCommit){ //通过openSession方法来创建一个sqlSession实例, //有了SqlSession,就可以来访问数据库 return sqlSessionFactory.openSession(autoCommit); }
UserDao接口:
/** * 通过传递一个对象形式保存用户 * @param user */ void save(Users user); /** * 通过传递一个map集合保存用户 * @param map */ void save2(Map<String, Object> map); /** * 通过传递一个对象修改用户 * @param user */ void update(Users user); /** * 通过id删除用户 * @param id */ void delete(int id); /** * 通过传递多个参数修改用户 * @param userName * @param uid */ void update2(String userName, int uid); /** * 根据id查询一条结果集,返回一个实体对象 * @param uid * @return */ Users getUserById(String uid); /** * 根据id查询一条结果集,返回一个map集合 * @param id * @return */ Map<String, Object> getUserById2(String id); /** * 查询所有,返回多个Users对象 * @return */ List<Users> listUser(); /** * 根据所有结果集,返回多个map集合 * @return */ List<Map<String, Object>> listUser2();
在UserDaoImpl类实现UserDao接口并重写抽象方法:
@Override public void save(Users user) { //获取SqlSession实例,true表示自动提交事务 try(SqlSession session = MybatisUtils.getSqlSession(true)){ //getMapper方法返回一个代理对象,这个代理对象也是实现了UserDao接口 //底层使用JDK动态代理技术 UserDao dao = session.getMapper(UserDao.class); //当执行save方法时,其实调用的时代理对象的save, //它会解析mapper映射配置文件,找到id为save的元素 //并执行其中的sql语句 dao.save(user); }catch (RuntimeException e){ throw e; } } @Override public void save2(Map<String, Object> map) { try(SqlSession sqlSession = MybatisUtils.getSqlSession(true)){ sqlSession.getMapper(UserDao.class).save2(map); }catch(RuntimeException e){ throw e; } } @Override public void update(Users user) { try(SqlSession sqlSession = MybatisUtils.getSqlSession(true)){ sqlSession.getMapper(UserDao.class).update(user); }catch (RuntimeException e){ throw e; } } @Override public void delete(int id) { try(SqlSession sqlSession = MybatisUtils.getSqlSession(true)){ sqlSession.getMapper(UserDao.class).delete(id); }catch (RuntimeException e){ throw e; } } @Override public void update2(String userName, int uid) { try(SqlSession sqlSession = MybatisUtils.getSqlSession(true)) { sqlSession.getMapper(UserDao.class).update2(userName, uid); }catch (RuntimeException e){ throw e; } } @Override public Users getUserById(String uid) { try(SqlSession sqlSession = MybatisUtils.getSqlSession(true)) { return sqlSession.getMapper(UserDao.class).getUserById(uid); }catch (RuntimeException e){ throw e; } } @Override public Map<String, Object> getUserById2(String id) { try(SqlSession sqlSession = MybatisUtils.getSqlSession(true)) { return sqlSession.getMapper(UserDao.class).getUserById2(id); }catch (RuntimeException e){ throw e; } } @Override public List<Users> listUser() { try(SqlSession sqlSession = MybatisUtils.getSqlSession(true)) { return sqlSession.getMapper(UserDao.class).listUser(); }catch (RuntimeException e){ throw e; } } @Override public List<Map<String, Object>> listUser2() { try(SqlSession sqlSession = MybatisUtils.getSqlSession(true)) { return sqlSession.getMapper(UserDao.class).listUser2(); }catch (RuntimeException e){ throw e; } }
上述这些类的结构如图所示:
3、在main目录下的resources目录中新建一个mybatis.xml文件,以及mapper文件夹下新建一个UsersMapper.xml(此文件命名规范是实体类名+Mapper)如图所示:
mybatis.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"> <!-- mybatis核心配置,用于配置相关数据源以及连接池等信息,以及实体类的别称映射,插件配置等等 --> <configuration> <!-- 指定实体类的别名,方便在mapper配置中进行引用 --> <typeAliases> <!-- 方法1、定义一个alias别名,缺点在于需要一个实体类分别指定 <typeAlias type="edu.nf.ch01.entity.Users" alias="user" />--> <!-- 方法2、也可以使用package来给某个包下面的所有实体类自动创建别名, 自动创建的别名规则是类的类名并将首字母改为小写 --> <package name="edu.nf.ch01.entity"/> </typeAliases> <!-- 配置数据源环境,default指定默认的数据源 --> <environments default="mysql"> <!-- 创建一个MySQL的数据源环境,id就叫mysql --> <environment id="mysql"> <!-- 配置事务管理,这里有JDBC和MANAGED两个值 JDBC:使用本地jdbc的事务 MANAGED:mybatis不参与事务管理,由运行容器来管理事务--> <transactionManager type="JDBC"/> <!-- 配置数据源,type指定获取连接的方式,有以下几个值: POOLED:使用mybatis自带的数据库连接池(方便连接的复用) UNPOOLRF:不使用连接池,而是每次请求都从数据库去获取连接 JMDI:通过查找JNDI树去获取数据源对象,通常结合web容器或者EJB容器来配置 --> <dataSource type="POOLED"> <!-- 配置数据源信息,驱动,url,连接的账号密码等 --> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <!-- 指定mapper配置文件 --> <mappers> <mapper resource="mapper/UsersMapper.xml" /> </mappers> </configuration>
UsersMapper.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指定Dao接口的完整类名, 因为mybatis在解析的时候要根据这个类名找到相应dao方法执行 --> <mapper namespace="edu.nf.ch01.dao.UserDao"> <!-- 映射SQL语句,比如<insert>标签用于映射insert语句, id属性对应Dao接口中的方法名 parameterType表示Dao接口方法参数的类型,可以指定完整类名, 这里指定实体类的别名,也就是在mybatis.xml中定义的别名 在sql语句中使用#{}表达式来指定要插入的列,{}中指定实体的字段名--> <insert id="save" parameterType="edu.nf.ch01.entity.Users"> insert into user_info(u_name) values(#{userName}) </insert> <!-- 如果参数类型时Map集合,那么#{}表达式对应的就是Map的kek,parameterType中也可以为map --> <insert id="save2" parameterType="java.util.Map"> insert into user_info(u_name) values(#{uname}) </insert> <update id="update" parameterType="edu.nf.ch01.entity.Users"> update user_info set u_name = #{userName} where u_id = #{uid}; </update> <delete id="delete" parameterType="int"> delete from user_info where u_id = #{id} </delete> <!-- 当有多个参数时,不需要指定parameterType属性, 而是使用#{param1}#{param2}...的方式映射参数,对应方法参数的顺序 --> <update id="update2"> update user_info set u_name = #{param1} where u_id = #{param2} </update> <!-- 查询当个用户,将结果集封装成一个实体对象 resultType属性指定查询结果集的返回类型, 如果返回一个实体,则返回引用mybatis.xml文件中Alias设置的别名 需要注意的是,查询sql语句中,查询column必须要和实体的字段名称相同--> <select id="getUserById" parameterType="java.lang.String" resultType="users"> select u_id as uid, u_name as userName from user_info2 where u_id = #{id} </select> <!-- 查询单个用户,将结果集封装成一个map集合 此时只需要将resultType设置为map即可--> <select id="getUserById2" parameterType="java.lang.String" resultType="map"> select u_id, u_name from user_info2 where u_id = #{id} </select> <!-- 查询用户列表,返回list集合,集合中封装了多个实体对象 --> <select id="listUser" resultType="users"> select u_id as uid, u_name as userName from user_info2 </select> <!-- 查询用户列表,返回list集合,集合中存放多个map对象 --> <select id="listUser2" resultType="map"> select u_id, u_name from user_info2 </select> </mapper>
数据库:mybatis
数据表:user_info
create table user_info( u_id int primary key auto_increment, u_name varchar(50) not null );