Hibernate 支持原生 SQL 查询,对于熟悉并钟情于 SQL 语句的开发者来讲,是一个很大的福音。实例:String sql="select * from student";SQLQuery sqlQuery= session.createSQLQuery(sql);Hibernate 提供了一个与原生 SQL 有关的 SQLQuery 对象。SQLQuery 是 Query 的子类,可适应不同的原生 SQL 语句查询。
强参数查询使用 SQL 查询时,可以指定查询条件,这个地球人都知道。HQL 中同样能使用条件查询:from Student s where s.stuId> 2在 HQL 中,如果查询条件中的数据需要通过参数传递,则会有两种方案:匿名方案,已经司空见惯,对不对;from Student s where s.stuId> ?命名参数方案。from Student s where s.stuId> :id参数名前面一定要有一个冒号 :id。完整实例献上:String hql="from Student s where s.stuId> :id";Query query=session.createQuery(hql);query.setInteger("id", 2);List<Student> stus= query.list();for (Student student : stus) { ystem.out.println(student);}return null;可自行查看控制台上的输出结果。强命名参数和 ? 占位符作用是一样的,但是,强命名参数可减少指定实参时的出错率。分页查询分页查询是很实用的查询机制。使用原生 SQL 分页查询时,需要自己构建查询 SQL 语句,不同的数据库中的分页查询语句编写也有差异性。Hibernate 通过其提供的分页查询功能很好地避开了这些问题。分页查询之前,先搞清楚几个与查询有关的参数:pageSize: 每一页大小;pageNum: 页码。假如数据库中有 20 行数据,分页查询时指定 pageSize 为 5,则每 5 条数据为一个逻辑页,总共有 4 页。如果要查询第 3 页数据,即 pageNum=3。则需要跳过去的记录数为:(pageNum-1)*pageSize=(3-1)*5=10 ,也就是从第 11 条数据开始查询。现在直接上实例代码:String hql = "from Student s order by stuId" ;Query query = session.createQuery(hql);int pageNum=3;int pageSize=5;int passNum=(pageNum-1)*pageSize;query.setFirstResult(passNum);query.setMaxResults(pageSize);List<Student> stus = query.list();for (Student student : stus) { System.out.println(student.getStuName()); }return null;HIbernate 会从第 11 条记录开始,查询出 5 条记录。针对不同的数据库系统,Hibernate 会给出最佳的 SQL 分页方案。联合查询程序中所需要的数据可不一定在同一张表中,往往都是在多张表中。原生 SQL 通过多表连接或子查询方式解决这个问题。使用 HQL 一样能表达出多表连接的意图。可能你会问:前面的一对一、一对多、多对多映射关联关系后,不就已经能够查询出多张表中的数据吗。如下面表数据:在学生类中采用立即查询策略:@ManyToOne(targetEntity = ClassRoom.class, cascade = CascadeType.REMOVE,fetch=FetchType.EAGER)@JoinColumn(name = "classRoomId")public ClassRoom getClassRoom() { return classRoom;}查询所有学生:String hql = "from Student s";Query query = session.createQuery(hql);List<Student> stus = query.list();System.out.println("-----------------------------");for (Student student : stus) {System.out.println("学生姓名:"+student.getStuName());System.out.println("班级名称: "+student.getClassRoom().getClassRoomName()); }return null;不要怀疑,结果一定是会出现的。但是,可以看到控制台输出了很多 SQL 语句。那是因为,Hibernate 会先查询出所有学生,然后根据班级 ID 再进入班级表进行查询,这就是 Hibernate 查询过程的 1+N 问题。可改成下面的关联查询方式:String hql = "select s.stuName,c.classRoomName from Student s,ClassRoom c where s.classRoom=c";Query query = session.createQuery(hql);List<Object[]> stus = query.list();System.out.println("-----------------------------");for (Object[] student : stus) { System.out.println("学生姓名:"+student[0]); System.out.println("班级名称: "+student[1]); }return null;控制台输入结果:Hibernate: select student0_.stuName as col_0_0_, classroom1_.classRoomName as col_1_0_ from Student student0_ cross join ClassRoom classroom1_ where student0_.classRoomId=classroom1_.classRoomIdHibernate 仅构建了一条 SQL 语句,直接查询出来了所有数据,看得出来,其性能要大于 1+N 方案。HQL 比想象中要简单,比你预期的功能要强大。有了它,再也不怕查询不到我们需要的数据。
为了更好地理解它们,来一个实例:查询姓名叫 “Hibernate” 的学生。Criteria criteria = session.createCriteria(Student.class);Criterion criterion = Restrictions.eq("stuName", "Hibernate");criteria.add(criterion);Student student = (Student) criteria.uniqueResult();System.out.println(student);Criteria 查询封装了关系型数据库的概念,所以,一定要注意,使用方法进行数据过滤时,都是属性进行比较。确认查询出来的数据只有一条记录时,可以使用 uniqueResult() 方法。条件查询的关键是了解 Restrictions,它所提供的很多类似于逻辑运算符的方法:Restrictions.eq(): 相当于 =;Restrictions.not(Exprission.eq()) : 相当于 <>;Restrictions.le(): 相当于 <=;Restrictions.gt(): 相当于 >;Restrictions.ge(): 相当于 >=;Restrictions.lt(): 相当于 <;Restrictions.isnull(): 相当于 is null;Restrictions.isNotNull(): 相当于 is not null ;Restrictions.like(): 相当于 like;Restrictions.and(): 相当于 and;Restrictions.conjunction(): 相当于 and;Restrictions.or(): 相当于 or;Restrictions.disjunction() : 相当于 or;Restrictions.not(): 相当于 not;Restrictions.in(): 相当于 in;Restrictions.not(Restrictions.in()): 相当于 not in;Restrictions.between(): 相当于 between x and y;Restrictions.not(Restrictions…between()) : 相当于 not between x and y。如上方法,几乎涵盖了所有 SQL 条件运算符,任意组合上面方法,没有查询不出来的结果。如查询学生编号是 1 或 2 或 4 的学生。使用 SQL,则是:select * from student where stuId in (1,2,4)使用 Criteria 查询,则如下所示:Criterion criterion = Restrictions.in("stuId",new Integer[] {1,2,4} );criteria.add(criterion);如查询学生编号大于 2 且班级编号为 1 的学生。使用 SQL:select * from student where stuId>2 and classRommId=1如果使用 Criteria 查询,则先构建两个约束对象:Criterion criterion = Restrictions.gt("stuId", 2);Criterion criterion1 = Restrictions.eqOrIsNull("classRoom.classRoomId", 1);再把这两个约束作为参数,构建一条联合约束:LogicalExpression logicalExpression = Restrictions.and(criterion, criterion1);criteria.add(logicalExpression);LogicalExpression API 用来表示一个逻辑表达式。是 Criterion 的子类。比较原生 SQL 和 Criteria 查询,会发现原生 SQL 语句要简单很多,使用 Criteria 查询需要掌握很多 API,而且代码量也比较大,这也可能是 Criteria 查询得不到普及的原因吧。但是,Hibernate 既然推出了这种查询方案,想必也有它的考虑。比如说,创建动态查询语句,这点原生 SQL 或 HQL 都没有 Criteria 好。还是那句话,存在就是合理的。如果,你对原生 SQL 有情怀,Criteria 查询中也是可以用的。criteria.add( Restrictions.sqlRestriction("stuId>2 and clasRoomId=1"));注意,不要在 Sql 片段中使用 where 关键字。既然是原生 SQL,所以语句中是字段概念,而不是属性概念。前面讲解 HQL 时,提到了分页查询。Criteria 一样可以实现分页查询,和 HQL 中分页方法一样:Criteria criteria = session.createCriteria(Student.class);criteria.setFirstResult(1);criteria.setMaxResults(5);List results = criteria.list();
排序查询使用 order API 实现:criteria.addOrder(Order.desc("stuId"));criteria.addOrder(Order.asc("stuName"));一样,可以多字段排序。使用聚合函数:聚合函数的功能封装在 projections API 中:criteria.setProjection(Projections.rowCount());criteria.setProjection(Projections.avg("stuId"));criteria.setProjection(Projections.max("stuId"));criteria.setProjection(Projections.min("stuId"));criteria.setProjection(Projections.sum("stuId"));Criteria 也能实现关联查询:Criteria criteria = session.createCriteria(Student.class);criteria.add(Restrictions.like("stuName", "Hibernate%"));Criteria criteria01 = criteria.createCriteria("classRoom");criteria01.add(Restrictions.like("classRoomName", "c19%"));List<Student> students = criteria.list();可以把一个 Criteria 实例看成对一张表的查询,如果需要关联多张表,则可以通过一个 Criteria 再创建一个 Criteria 对象。Hibernate 为 Criteria 查询提供各种各样的 API,适应于任何查询需求,相比较使用的已经很普遍的 SQL 查询,Criteria 查询充满了鸡肋的味道。但对于动态查询需求,Criteria 查询的优势又很明显。
在dao包下新建一个GoodsDAO类,并写入一下内容:package com.colorful.dao;import com.colorful.model.Goods;import com.colorful.util.JDBCUtil;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.util.ArrayList;import java.util.List;public class GoodsDAO { private Connection connection = null; private PreparedStatement preparedStatement = null; private ResultSet resultSet = null; boolean executeResult; public List<Goods> selectGoodsList() { List<Goods> goodsList = new ArrayList<>(); try { // 获得链接 connection = JDBCUtil.getConnection(); // 编写 SQL 语句 String sql = "SELECT `id`, `name`, `price` FROM `imooc_goods` where `delete_time` is null"; // 预编译 SQL preparedStatement = connection.prepareStatement(sql); resultSet = preparedStatement.executeQuery(); while (resultSet.next()) { Goods goods = new Goods(); goods.setId(resultSet.getInt("id")); goods.setName(resultSet.getString("name")); goods.setPrice(resultSet.getDouble("price")); goodsList.add(goods); } } catch (Exception e) { e.printStackTrace(); } finally { // 释放资源 JDBCUtil.release(resultSet, preparedStatement, connection); } return goodsList; }}selectGoodsList()方法就用于查询商品列表(由于数据量不大,此处我没有对列表数据进行分页查询,大家也可以自行加入)。在service包下新建GoodsService,并调用dao层下封装好的方法:package com.colorful.service;import com.colorful.dao.GoodsDAO;import com.colorful.model.Goods;import java.util.List;public class GoodsService { private final GoodsDAO goodsDAO = new GoodsDAO(); /** * 获取商品列表 * @return 商品列表 */ public List<Goods> getGoodsList() { return goodsDAO.selectGoodsList(); }}这样,我们就完成了查询商品列表的服务层代码编写。
多条件的查询还可以更加灵活,上述的例子都只涉及到单条件字段的查询,有时候需要从多个字段进行结果筛选。请书写 SQL 语句,查询imooc_user表中年龄在25到30之间(包含25和30),并且用户名为jerry的用户。分析:条件字段变成了两个——username 和 age,username 只有一个条件,等于jerry,即 =jerry,age 有两个条件,既要大于等于25,还要小于等于30,即 >=25,<=30。三个条件之间均用 AND连接。语句:整理语句如下:SELECT username from imooc_userWHERE username = 'jerry'AND age >= 25AND age <= 30;结果如下:+----------+| username |+----------+| jerry |+----------+注意: SQL中字符串用单引号包括,即''。
什么是 Criteria 查询?Criteria 查询从字面翻译就是标准查询。所谓 标准查询,指的是 HIbernate 提供了纯正的 OOP API 查询方案。不像 HQL 还掺杂了一些 SQL 层面的内容。来一个查询需求:查询所有的学生。想必这学生会很生气,总是被搬来搬去的。上实例之前,先认识 Hibernate 兄弟会中的一名新成员:Criteria。在使用 Criteria 查询之前,必须先创建 Criteria 对象:Criteria cr = session.createCriteria(Student.class);List<Student> stus = cr.list();是不是很 OOP。使用 HQL 时,会有一种时空穿越的感觉 ,OOP 和 SQL 语法交替出现,很容易犯晕。使用 Criteria 进行查询时则不会。而且,Criteria 不是一个人在战斗,它也有属于自己的兄弟会,为开发者提供了更强有力的支持。先介绍一下它的几个兄弟,并且它们的作用已经从字面告诉了你。Criterion: 这位兄弟长得好生面熟,其实它就 Criteria 的单数存在形式;Oder: 提供排序功能;Restrictions: 限制、约束的意思,和 SQL 中的 where 关键字的作用是一样。所以,它提供了很多类似于运算符的方法,可以对查询数据进行过滤。Criteria 面子上很 OOP ,但是无论你怎么逃,都是在 SQL 的手掌心,也就是说 Criteria 查询最终还是会被 Hibernate 转译成 SQL 语句。只要是使用关系型数据库,SQL 就是逃不掉的宿命。只是直接、间接使用的区别。所以,Criteria 查询中总会找到 SQL 的影子。
Distinct 也可用于多字段查询去重。语法如下:SELECT DISTINCT [col1],[col2] FROM [table_name];其中col表示字段名,table_name表示数据表名称,数字1,2表示多个字段。
在 loc() 函数中,我们通过传入要查询的列表项,可以查询多个数据内容,返回的数据结果是 Series 数据结构或者 DataFrame 数据结构。# 这里的 data 是上面我们从 Excel 中解析出来的数据print(data.loc[[1,2,5],["编程语言","价格"]])# --- 输出结果 --- 编程语言 价格1 python 67.02 C 33.95 C++ 75.0输出解析: 我们传入两个查询列表 [1,2,5] 和 [“编程语言”,“价格”],可以看到查询的结果为二维数据结构的数据集。
请使用 MyBatis 完成对 imooc_user 表多条件查询用户的功能,如果 id 不为空则直接使用 id 查询用户,否则使用 username 查询用户,如果 username 也为空,则直接查询全部用户。分析:按照 MyBatis 的开发模式,需先在 UserMapper.xml 文件中添加多条件查询用户的 select 标签,然后在 UserMapper.java 中添加上对应的方法。步骤:首先,在 UserMapper.xml 中添加 select 标签,并在标签中写入 SQL,使用 choose 中的 when 标签来依次判断 id 和 username 是否为 null,若均为 null,则在 otherwise 中添加上一个永假的值。如下:<select id="selectUserByIdOrName" resultType="com.imooc.mybatis.model.User"> SELECT * FROM imooc_user WHERE <choose> <when test="id != null"> id = #{id} </when> <when test="username != null"> username = #{username} </when> <otherwise> 1 = 0 </otherwise> </choose></select>这里使用了1 = 0作为条件判断的永假值。然后在 UserMapper.java 中添加上对应的接口方法,方法接受 id 和 username 两个参数,都可为空。package com.imooc.mybatis.mapper;import org.apache.ibatis.annotations.Mapper;import com.imooc.mybatis.model.User;@Mapperpublic interface UserMapper { User selectUserByIdOrName(@Param("id") Integer id, @Param("username") String username);}结果:通过如下代码,我们运行 selectUserByIdOrName 这个方法。UserMapper userMapper = session.getMapper(UserMapper.class);User pedro = userMapper.selectUserByIdOrName(null, null);System.out.println(pedro);id 和 username 两个属性均为空,因此所执行的 SQL 为:SELECT * FROM imooc_user WHERE 1 = 0 成功后,结果为:null
Where 后面有多个条件子句的查询称为多条件查询。
请书写 SQL 语句,查询imooc_user表中每一个用户姓名和该用户所参加课程的名称。分析:由题干可知,查询的结果应是用户姓名以及参加课程,因此 imooc_user 表应该作为保留表;考虑到使用左连接,所以 imooc_user 表是左表,imooc_class 表作为右表。语句:整理可得语句如下:SELECT username,class_name FROM imooc_user LEFT OUTER JOIN imooc_class ON imooc_user.class_id = imooc_class.id;结果如下:+----------+---------------+| username | class_name |+----------+---------------+| pedro | SQL必知必会 || peter | SQL必知必会 || faker | C语言入门 || lucy | JVM花落知多少 || jery | <null> |+----------+---------------+
上面介绍了如何向数据表插入一条数据,这里需要查看数据表已有的所有数据: SELECT * FROM teacher;执行结果如下图:“SELECT” 关键字表示这条命令是查询相关命令,"*" 则代表要查询出表中所有的数据。“FROM teacher” 则表明要查询的是哪一个数据表。关于 SELECT 查询语句还有很多中使用场景,比如我们要查询出表中 age 字段的值大于 20 岁的数据。关于 SELECT 的其他使用我们会在后面的小节详细讲解。
下面主要介绍一下 ThinkPHP 框架原生查询,一般情况下,框架自带的方法都可以满足大多数查询需求,但有时候对于复杂的 sql 查询逻辑,使用原生查询比较合适,下面定义一个方法使用原生查询获取学生列表数据: /** * 获取学生列表 * @return \think\response\Json * @throws \think\db\exception\DbException */ public function getStudents() { //每页条数 $size = (int)$this->request->param('size', 15); //页数 $page = (int)$this->request->param('page', 1); $limit = ($page - 1) * $size; $students = Db::query("select * from `student` where `status`=1 order by created_at desc limit {$limit},{$size}"); return json($students); }若 page=2、size=5 返回数据如下:[ { "id": 6, "name": "王五", "age": 25, "id_number": "420117201005123617", "created_at": 1603617951, "update_at": 0, "status": 1 }, { "id": 7, "name": "张红", "age": 19, "id_number": "420117201005123721", "created_at": 1603617951, "update_at": 0, "status": 1 }, { "id": 8, "name": "吴小明", "age": 21, "id_number": "420117201005123197", "created_at": 1603617951, "update_at": 0, "status": 1 }, { "id": 9, "name": "钱学", "age": 19, "id_number": "420117201005121149", "created_at": 1603617951, "update_at": 0, "status": 1 }, { "id": 10, "name": "孙空", "age": 21, "id_number": "420117201005124671", "created_at": 1603617951, "update_at": 0, "status": 1 }]Tips: 此时的数据结构和上面分页的不一样。
以 teacher 表为例,查询年龄大于 18 和 教师姓氏 王 的教师信息:SELECT * FROM teacher WHERE age > 18 AND name LIKE '王%';执行结果如下图:Tips:这里还想加更多的条件可以在后面继续跟 AND,LIKE 后面表达式中 % 表示指代任意内容。
请书写 SQL 语句,从 user_shorcut_view 视图中找出 id 为 2 的用户。分析:使用 Select 指令像查询数据表一样查询视图。语句:SELECT username FROM user_shorcut_view WHERE id = 2;结果如下:+----------+| username |+----------+| pedro |+----------+
前面介绍了如何向表插入数据、删除数据,本小节介绍如何查询表中的数据。查询在实际业务中,SELECT 语句用的非常多,例如网站的数据读取和展示,查询需要了解的数据情况等等。
请书写 SQL 语句,查询imooc_user表中age字段为空的用户名。分析:使用 Select 搭配 Where,且查询条件为 age 为空,即age IS NULL。语句:整理可得语句如下:SELECT username FROM imooc_user WHERE age IS NULL;结果如下:+----------+| username |+----------+| jerry || mike |+----------+
SQL Union 用于合并 Select 查询的多个结果集,使用语法如下:SELECT [col] FROM [table_name1]UNIONSELECT [col] FROM [table_name2]其中table_name代表数据表名称,col表示字段名称,数字 1,2 表示多张表。
Session 提供了 2 个语义很明确的查询方法:get() 方法;load() 方法。有选择,就会有比较。但,请先不用着急区分两者差异性,试着用用。跑之前先学会走吗?查询之前,可预先在表中多添加几条数据!避免池塘没鱼,捕不到鱼还不停怀疑自己,伤情绪。get() 方法有很多重载,选择其中一个方法:public Object get(Class clazz, Serializable id); 参数一: 指定待查询的 PO 对象的类型;参数二: 指定一个实现 Serializable 接口的对象,充当查询条件,一般是主键。编写 get() 方法的查询测试实例:@Test public void testGet() { //会话对象 Session session = sessionFactory.openSession(); // 事务对象 Transaction transaction = null; try { // 打开事务 transaction = session.beginTransaction(); //查询学号为1的学生 Student stu=(Student)session.get(Student.class, new Integer(1)); assertEquals("男", stu.getStuSex()); transaction.commit(); } catch (Exception e) { transaction.rollback(); } finally { session.close(); } } 编写 load() 方法的查询测试实例:@Test public void testLoad() { //会话对象 Session session = sessionFactory.openSession(); // 事务对象 Transaction transaction = null; try { // 打开事务 transaction = session.beginTransaction(); //查询学号为1的学生 Student stu=(Student)session.load(Student.class, new Integer(2)); assertEquals("男", stu.getStuSex()); transaction.commit(); } catch(Exception e) { transaction.rollback(); } finally { session.close(); }} 测试代码和上面没有很明显区别,结果也没有什么不同。这两个方法从测试角度暂时无法区分,但本质上还是有很大区别。
请书写 SQL 语句,查询imooc_user表中age字段非空的用户名。分析:使用 Select 搭配 Where,且查询条件为 age 非空,即age IS NOT NULL。语句:整理可得语句如下:SELECT username FROM imooc_user WHERE age IS NOT NULL;结果如下:+----------+| username |+----------+| pedro |+----------+
请书写 SQL 语句,获取 imooc_user 表中username和age字段数据。分析:按照上面的查询语法写出语句即可。语句:SELECT username,age FROM imooc_user;获得信息如下:+----------+-----+| username | age |+----------+-----+| pedro | 23 || mike | 18 |+----------+-----+username 和 age ,是 imooc_user 的全部字段,因此 SQL 语句可以改写为:SELECT * FROM imooc_user;Select 不仅可以获取多字段数据,也可以用来需要获取单字段数据。如,获取 imooc_user 表中 username 字段数据。整理可得语句如下:SELECT username FROM imooc_user;结果如下:+----------+| username |+----------+| pedro || mike |+----------+
以 teacher 表为例,查询 teacher 表中的所有数据:SELECT * FEOM teacher;执行结果如下图 :Tips:这里没有指定查询条数,默认是查询表所有的行数据。
请书写 SQL 语句,获取imooc_user表中分数大于imooc_user_score_rank表中任意一个分数的用户。分析:从题干中得出,imooc_user 表中的 score 对应 imooc_user_score_rank 中的 score,我们使用 ANY 子查询,第一步从子查询中获取 imooc_user_score_rank 表中的所有分数项,第二步在主查询中使用 ANY 与子查询结果比较。语句:整理可得语句如下:SELECT username FROM imooc_user WHERE score > ANY(SELECT score FROM imooc_user_score_rank);结果如下:+----------+| username |+----------+| tom |+----------+tom 的分数为 1000, 大于 imooc_user_score_rank 表中的最小值 700,而其它的用户均小于 imooc_user_score_rank 表中任意分数。
def query_students_fetchone(): sql = 'SELECT * FROM students' rows = cursor.execute(sql) print('There are %d students' % rows) for i in range(rows): student = cursor.fetchone() print(student)在第 1 行,定义函数 query_students_fetchone,使用 fetchone 方法查询数据在第 3 行,cursor.execute(sql) 返回查询记录的条数在第 7 行,使用 fetchone() 获取一条查询记录编写测试程序如下:open_conn()query_students_fetchone()close_conn() 程序输出如下:There are 2 students('1', '张三', 20)('2', '李四', 21)查询记录是一个元组第 0 项是 sno第 1 项是 name第 2 项是 age
以 teacher 表为例,查询年龄大于 25 或 教师姓氏 王 的教师信息:SELECT * FROM teacher WHERE age > 25 OR name LIKE '王%';执行结果如下图:Tips:这里还想加更多的条件可以在后面继续跟 OR,若 AND 和 OR 混合使用则需要把同一组表达式用 () 包起来,如 : (age > 25 AND name LIKE '王%') OR (age < 20 AND name LIKE '刘%')。
def query_students_fetchall(): sql = 'SELECT * FROM students' rows = cursor.execute(sql) print('There are %d students' % rows) students = cursor.fetchall() for student in students: print(student)在第 1 行,定义函数 query_students_fetchall,使用 fetchall 方法查询数据在第 3 行,cursor.execute(sql) 返回查询记录的条数在第 6 行,使用 fetchall() 获取所有的查询记录编写测试程序如下:open_conn()query_students_fetchall()close_conn() 程序输出如下:There are 2 students('1', '张三', 20)('2', '李四', 21)
请书写 SQL 语句,查询imooc_user表中年龄大于等于18但小于25的用户名。分析:条件字段仍是 age,但筛选条件从一个变成了两个,第一个条件,age 要大于等于 18,第二个条件,age 要小于 25。两个条件之间使用 AND 连接。语句:整理语句如下:SELECT username from imooc_userWHERE age >= 18AND age < 25;结果如下:+----------+| username |+----------+| pedro || mike |+----------+
以 student 表为例,使用正则表达式查询出姓王的教师:SELECT * FROM student WHERE name REGEXP '^王';查询结果如下图:使用正则表达式查询 name 字段中包含小字的数据:SELECT * FROM student WHERE name REGEXP '小';查询结果如下图:以 teacher 表为例,使用正则表达式匹配符合邮箱格式的数据:SELECT * FROM teacher WHERE email REGEXP '^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$';查询结果如下图:Tips:如上图所示, 其中 ^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$ 为符合邮箱匹配规则的正则表达式,查询结果 email 的值如果不满足此正则表达式,则该条数据不会被查询出来。
Pandas 在解析数据时,会根据一定的条件进行解析处理,这种方式虽然在源数据上做了筛选,但实际的业务需求中,对解析出来的数据,我们会根据更加明确的条件和需要,去查询数据内容,为进一步的数据操作和分析做好铺垫。Pandas 中提供了多种查询函数,方便我们的数据查询操作,我们需要查询的数据条件不同,所采用的操作也有所不同,总的来说,我们的查询条件可以为按单个值查询、按值列表查询、按值区间查询、按条件表达式查询和按函数查询五种查询的方式,接下来我们将以 loc() 查询函数为例,详细讲解每种查询的具体操作。Tips:loc() 的查询条件,可以使用label值,也可以使用布尔值,他丰富的传值方式,以及简洁的使用方式,成为 Pandas 数据查询较为常用的方法。查询方法简述loc( )通过标签或布尔数字查询数据集 (推荐使用的查询方法)iloc( )通过索引位来查询数据集query( )通过布尔表达式查询数据列