本文共 13650 字,大约阅读时间需要 45 分钟。
目录
Mybatis基于代理Dao的CRUD操作 重点内容
CRUD中可能遇到的问题:参数的传递以及返回值的封装 介绍Mybatis基于传统dao方式的使用(自己编写dao的实现类) 了解的内容 mybatis主配置文件中的常用配置 properties标签 typeAliases标签 ---解释Integer的写法 mappers标签的子标签:packageOGNL表达式:
Object Graphic Navigation Language 对象 图 导航 语言 它是通过对象的取值方法来获取数据。在写法上把get给省略了。 比如:我们获取用户的名称 类中的写法:user.getUsername(); OGNL表达式写法:user.username mybatis中为什么能直接写username,而不用user.呢: 因为在parameterType中已经提供了属性所属的类,所以此时不需要写对象名
自定义流程复习
mybatis 环境搭建步骤
MyBatis的CRUD操作
根据 ID 查询
/*** 根据 id 查询* @param userId* @return*/User findById(Integer userId);
细节:resultType 属性:用于指定结果集的类型。parameterType 属性 : 传智播客——专注于 Java 、 .Net 和 Php 、网页平面设计工程师的培训北京市昌平区建材城西路金燕龙办公楼一层 电话:400-618-9090用于指定传入参数的类型。sql 语句中使用 #{} 字符:它代表占位符,相当于原来 jdbc 部分所学的 ? ,都是用于执行语句时替换实际的数据。具体的数据是由 #{} 里面的内容决定的。#{} 中内容的写法:由于数据类型是基本类型,所以此处可以随意写。
/****Title: MybastisCRUDTest
*Description: 测试 mybatis 的 crud 操作
*Company: http://www.itheima.com/
*/public class MybastisCRUDTest {private InputStream in ;private SqlSessionFactory factory;private SqlSession session;private IUserDao userDao;@Testpublic void testFindOne() {//6.执行操作User user = userDao.findById(41);System.out.println(user);}@Before//在测试方法执行之前执行public void init()throws Exception {//1.读取配置文件in = Resources.getResourceAsStream("SqlMapConfig.xml");//2.创建构建者对象SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();//3.创建 SqlSession 工厂对象factory = builder.build(in);//4.创建 SqlSession 对象session = factory.openSession();//5.创建 Dao 的代理对象userDao = session.getMapper(IUserDao.class);}@After//在测试方法执行完成之后执行public void destroy() throws Exception{session.commit();//7.释放资源session.close();in.close();}}
保存操作
1 在持久层接口中添加新增方法
/*** 保存用户* @param user* @return 影响数据库记录的行数*/int saveUser(User user);
insert into user(username,birthday,sex,address)values(#{username},#{birthday},#{sex},#{address})
细节:parameterType 属性:代表参数的类型,因为我们要传入的是一个类的对象,所以类型就写类的全名称。sql 语句中使用 #{} 字符:它代表占位符,相当于原来 jdbc 部分所学的 ? ,都是用于执行语句时替换实际的数据。具体的数据是由 #{} 里面的内容决定的。#{} 中内容的写法:由于我们保存方法的参数是 一个 User 对象,此处要写 User 对象中的属性名称。它用的是 ognl 表达式。ognl 表达式:它是 apache 提供的一种表达式语言,全称是:Object Graphic Navigation Language 对象图导航语言它是按照一定的语法格式来获取数据的。语法格式就是使用 #{ 对象 . 对象 } 的方式#{user.username} 它会先去找 user 对象,然后在 user 对象中找到 username 属性,并调用getUsername() 方法把值取出来。但是我们在 parameterType 属性上指定了实体类名称,所以可以省略 user.而直接写 username 。
@Testpublic void testSave(){User user = new User();user.setUsername("modify User property");user.setAddress("北京市顺义区");user.setSex("男");user.setBirthday(new Date());System.out.println("保存操作之前:"+user);//5.执行保存方法userDao.saveUser(user);System.out.println("保存操作之后:"+user);}/*打开 Mysql 数据库发现并没有添加任何记录,原因是什么?这一点和 jdbc 是一样的,我们在实现增删改时一定要去控制事务的提交,那么在 mybatis 中如何控制事提交呢?可以使用:session.commit();来实现事务提交。加入事务提交后的代码如下:*/@After//在测试方法执行完成之后执行public void destroy() throws Exception{session.commit();//7.释放资源session.close();in.close();}
4 问题扩展:新增用户 id 的返回值
select last_insert_id(); insert into user(username,birthday,sex,address)values(#{username},#{birthday},#{sex},#{address})
用户更新
/*** 更新用户* @param user* @return 影响数据库记录的行数*/int updateUser(User user);
update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
@Testpublic void testUpdateUser()throws Exception{//1.根据 id 查询User user = userDao.findById(52);//2.更新操作user.setAddress("北京市顺义区");int res = userDao.updateUser(user);System.out.println(res);}
用户删除
/*** 根据 id 删除用户* @param userId* @return*/int deleteUser(Integer userId);
delete from user where id = #{uid}
@Testpublic void testDeleteUser() throws Exception {//6.执行操作int res = userDao.deleteUser(52);System.out.println(res);}
用户模糊查询
/*** 根据名称模糊查询* @param username* @return*/ListfindByName(String username);
@Testpublic void testFindByName(){//5.执行查询一个方法Listusers = userDao.findByName("%王%");for(User user : users){System.out.println(user);}}
在控制台输出的执行 SQL 语句如下:我们在配置文件中没有加入%来作为模糊查询的条件,所以在传入字符串实参时,就需要给定模糊查询的标识%。配置文件中的#{username}也只是一个占位符,所以 SQL 语句显示为“?”在使用mybatis的模糊查询时,有两个特殊符号需要注意
%(百分号):相当于任意多个字符;
_(下划线):相当于任意的单个字符;
我们在上面将原来的#{}占位符,改成了${value}。注意如果用模糊查询的这种写法,那么${value}的写法就是固定的,不能写成其它名字。第二步:测试,如下:/*** 测试模糊查询操作*/@Testpublic void testFindByName(){//5.执行查询一个方法Listusers = userDao.findByName("王");for(User user : users){System.out.println(user);}}
在控制台输出的执行 SQL 语句如下:可以发现,我们在程序代码中就不需要加入模糊查询的匹配符 % 了,这两种方式的实现效果是一样的,但执行的语句是不一样的
#{} 表示一个占位符号通过 #{} 可以实现 preparedStatement 向占位符中设置值,自动进行 java 类型和 jdbc 类型转换,#{} 可以有效防止 sql 注入。 #{} 可以接收简单类型值或 pojo 属性值。 如果 parameterType 传输单个简单类型值, #{} 括号中可以是 value 或其它名称。${} 表示拼接 sql 串通过 ${} 可以将 parameterType 传入的内容拼接在 sql 中且不进行 jdbc 类型转换, ${} 可以接收简单类型值或 pojo 属性值,如果 parameterType 传输单个简单类型值, ${} 括号中只能是 value 。
查询使用聚合函数
/*** 查询总记录条数* @return*/int findTotal();
@Testpublic void testFindTotal() throws Exception {//6.执行操作int res = userDao.findTotal();System.out.println(res);}
传递 pojo 包装对象
/****Title: QueryVo
*Description: 查询条件对象
*Company: http://www.itheima.com/
*/public class QueryVo implements Serializable {private User user;public User getUser() {return user;}public void setUser(User user) {this.user = user;}}
/****Title: IUserDao
*Description: 用户的业务层接口
*Company: http://www.itheima.com/
*/public interface IUserDao {/*** 根据 QueryVo 中的条件查询用户* @param vo* @return*/ListfindByVo(QueryVo vo);}
@Testpublic void testFindByQueryVo() {QueryVo vo = new QueryVo();User user = new User();user.setUserName("%王%");vo.setUser(user);Listusers = userDao.findByVo(vo);for(User u : users) {System.out.println(u);}}
Mybatis 的输出结果封装
当实体类属性和数据库的列名不一样
/****Title: User
*Description: 用户的实体类
*Company: http://www.itheima.com/
*/public class User implements Serializable {private Integer userId;private String userName;private Date userBirthday;private String userSex;private String userAddress;public Integer getUserId() {return userId;}public void setUserId(Integer userId) {this.userId = userId;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public Date getUserBirthday() {return userBirthday;}public void setUserBirthday(Date userBirthday) {传智播客——专注于 Java、.Net 和 Php、网页平面设计工程师的培训北京市昌平区建材城西路金燕龙办公楼一层 电话:400-618-9090this.userBirthday = userBirthday;}public String getUserSex() {return userSex;}public void setUserSex(String userSex) {this.userSex = userSex;}public String getUserAddress() {return userAddress;}public void setUserAddress(String userAddress) {this.userAddress = userAddress;}@Overridepublic String toString() {return "User [userId=" + userId + ", userName=" + userName + ", userBirthday="+ userBirthday + ", userSex="+ userSex + ", userAddress=" + userAddress + "]";}}
/*** 查询所有用户* @return*/ListfindAll();
@Testpublic void testFindAll() {Listusers = userDao.findAll();for(User user : users) {System.out.println(user);}}
resultMap 结果类型
@Testpublic void testFindAll() {Listusers = userDao.findAll();for(User user : users) {System.out.println(user);}}
MyBatis中Dao层开发
/****Title: IUserDao
*Description: 用户的业务层接口
*Company: http://www.itheima.com/
*/public interface IUserDao {/*** 查询所有用户* @return*/ListfindAll();/*** 根据 id 查询* @param userId* @return*/User findById(Integer userId);/*** 保存用户* @param user* @return 影响数据库记录的行数*/int saveUser(User user);/*** 更新用户* @param user* @return 影响数据库记录的行数*/int updateUser(User user);/*** 根据 id 删除用户* @param userId* @return*/int deleteUser(Integer userId);/*** 查询总记录条数* @return*/int findTotal();}
/****Title: UserDaoImpl
*Description: dao 的实现类
*Company: http://www.itheima.com/
*/public class UserDaoImpl implements IUserDao {private SqlSessionFactory factory;public UserDaoImpl(SqlSessionFactory factory) {this.factory = factory;}@Overridepublic ListfindAll() {SqlSession session = factory.openSession();List users = session.selectList("com.itheima.dao.IUserDao.findAll");session.close();return users;}@Overridepublic User findById(Integer userId) {SqlSession session = factory.openSession();User user = session.selectOne("com.itheima.dao.IUserDao.findById",userId);session.close();return user;}@Overridepublic int saveUser(User user) {SqlSession session = factory.openSession();int res = session.insert("com.itheima.dao.IUserDao.saveUser",user);session.commit();session.close();return res;}@Overridepublic int updateUser(User user) {SqlSession session = factory.openSession();int res = session.update("com.itheima.dao.IUserDao.updateUser",user);session.commit();session.close();return res;}@Overridepublic int deleteUser(Integer userId) {SqlSession session = factory.openSession();int res = session.delete("com.itheima.dao.IUserDao.deleteUser",userId);session.commit();session.close();return res;}@Overridepublic int findTotal() {SqlSession session = factory.openSession();int res = session.selectOne("com.itheima.dao.IUserDao.findTotal");session.close();return res;}}
select * from user where id = #{uid} select last_insert_id(); insert into user(username,birthday,sex,address)values(#{username},#{birthday},#{sex},#{address})update user setusername=#{username},birthday=#{birthday},sex=#{sex},address=#{address} whereid=#{id} delete from user where id = #{uid}
/****Title: MybastisCRUDTest
*Description: 测试 mybatis 的 crud 操作
*Company: http://www.itheima.com/
*/public class MybastisCRUDTest {private InputStream in ;private SqlSessionFactory factory;private IUserDao userDao;@Testpublic void testFindAll() {Listusers = userDao.findAll();for(User user : users) {System.out.println(user);}}@Testpublic void testFindOne() {//6.执行操作User user = userDao.findById(56);System.out.println(user);}@Testpublic void testSaveUser() throws Exception {User user = new User();user.setUsername("mybatis dao user");//6.执行操作int res = userDao.saveUser(user);System.out.println(res);System.out.println(user.getId());}@Testpublic void testUpdateUser()throws Exception{//1.根据 id 查询User user = userDao.findById(41);//2.更新操作user.setAddress("北京市顺义区");int res = userDao.updateUser(user);System.out.println(res);}@Testpublic void testDeleteUser() throws Exception {//6.执行操作int res = userDao.deleteUser(56);System.out.println(res);}@Testpublic void testFindTotal() throws Exception {//6.执行操作int res = userDao.findTotal();System.out.println(res);}@Before//在测试方法执行之前执行public void init()throws Exception {//1.读取配置文件in = Resources.getResourceAsStream("SqlMapConfig.xml");//2.创建构建者对象SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();//3.创建 SqlSession 工厂对象factory = builder.build(in);//4.创建 Dao 接口的实现类userDao = new UserDaoImpl(factory);}@After//在测试方法执行完成之后执行public void destroy() throws Exception{//7.释放资源in.close();}}
编写Dao实现类的执行过程
——————————————————————————————————————————————————————————————————————————————————————————————————————
代理Dao的执行过程
SqlMapConfig.xml配置文件
-properties (属性)--property-settings (全局配置参数)--setting-typeAliases (类型别名)--typeAliase--package-typeHandlers (类型处理器)-objectFactory (对象工厂)-plugins (插件)-environments (环境集合属性对象)--environment (环境子属性对象)---transactionManager (事务管理)---dataSource (数据源)-mappers (映射器)--mapper--package
2 properties(属性)
传智播客——专注于 Java、.Net 和 Php、网页平面设计工程师的培训北京市昌平区建材城西路金燕龙办公楼一层 电话:400-618-9090
3 typeAliases(类型别名)
4 mappers(映射器)
使用相对于类路径的资源如: <mapper resource="com/itheima/dao/IUserDao.xml" />
使用 mapper 接口类路径如:<mapper class="com.itheima.dao.UserDao"/>注意:此种方法要求 mapper 接口名称和 mapper 映射文件名称相同,且放在同一个目录中
注册指定包下的所有 mapper 接口如: <package name="cn.itcast.mybatis.mapper"/>注意:此种方法要求 mapper 接口名称和 mapper 映射文件名称相同,且放在同一个目录中
转载地址:https://blog.csdn.net/m0_56426304/article/details/117700023 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!