案例:基于MyBatis注解的学生管理程序
现有一个学生表s_student和一个班级表c_class,其中,班级表c_class和学生表s_student是一对多的关系。学生表s_student和班级表c_class如表1和表2所示。

请使用MyBatis注解完成以下几个要求:
根据表1和表2在数据库分别创建一个学生表s_student和一个班级表c_class, 并查询id为2的学生的信息。
修改id为4的学生的姓名修改为李雷,年龄修改为21。
MyBatis注解实现修改操作
查询出二班所有学生的信息。
创建一个名称为mybatis-4的项目,项目的具体搭建过程请参考入门笔记

在名为mybatis的数据库中,创建两个数据表,分别为学生表s_student和班级表c_class,同时在表中预先插入几条测试数据。执行的SQL语句如下所示。
USE mybatis;
# 创建一个名称为c_class的表
CREATE TABLE c_class (
id int(32) PRIMARY KEY AUTO_INCREMENT,
classname varchar(40)
);
# 插入2条数据
INSERT INTO c_class VALUES (1, '一班');
INSERT INTO c_class VALUES (2, '二班');
# 创建一个名称为s_student的表
CREATE TABLE s_student (
id int(32) PRIMARY KEY AUTO_INCREMENT,
name varchar(40),
age int,
cid int(32) NOT NULL,
FOREIGN KEY(cid) REFERENCES c_class(id)
);
# 插入4条数据
INSERT INTO s_student VALUES (1, '张三', 18,1);
INSERT INTO s_student VALUES (2, '李四', 18,2);
INSERT INTO s_student VALUES (3, '王五', 19,2);
INSERT INTO s_student VALUES (4, '赵六', 20,1);

在项目的src/main/java目录下创建com.lyrpx.pojo包,在com.lyrpx.pojo包中创建持久化类IClass,并在类中定义相关属性和方法,该类用于封装IClass对象的id、班级名称以及关联的学生集合等属性。具体代码如下所示。
IClass.java
package com.lyrpx.pojo;
import java.util.List;
/**
* 班级持久化类
*/
public class IClass {
private Integer id; // 主键id
private String classname; // 班级名称
private List<IStudent> studentList; // 学生集合
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getClassname() {
return classname;
}
public void setClassname(String classname) {
this.classname = classname;
}
public List<IStudent> getStudentList() {
return studentList;
}
public void setStudentList(List<IStudent> studentList) {
this.studentList = studentList;
}
@Override
public String toString() {
return "IClass{" +
"id=" + id +
", classname='" + classname +
", studentList=" + studentList + '}';
}
}
在com.lyrpx.pojo包中,创建持久化类IStudent,并在类中定义相关属性和方法,该类用户封装IStudent对象的id、姓名和年龄等属性。具体代码如下所示。
IStudent.java
package com.lyrpx.pojo;
/**
* 学生持久化类
*/
public class IStudent {
private Integer id; // 主键id
private String name; // 姓名
private int age; // 年龄
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" + "id=" + id +
", name='" + name + ", age=" + age + '}';
}
}
上述代码中,分别定义了各自的属性以及对应的getter/setter方法,同时为了方便查看输出结果,重写了toString()方法。
在项目的src/main/java目录下创建com.lyrpx.dao包,并在com.lyrpx.dao包下创建IStudentMapper接口,用于编写@Select注解映射的select查询语句。IStudentMapper接口具体代码如下所示。
IStudentMapper.java
package com.lyrpx.mapper;
import com.lyrpx.pojo.IStudent;
import org.apache.ibatis.annotations.Select;
public interface IStudentMapper {
@Select("select * from s_student where id = #{id}")
IStudent selectStudent(int id);
}
上述代码中,@Select注解的参数是一个查询语句,当程序调用@Select注解标注的selectStudent ()方法时,@Select注解中映射的查询语句将被执行。
在核心配置文件mybatis-config.xml中的元素下引入IStudentMapper接口,将IStudentMapper接口加载到核心配置文件中,具体代码如下所示。
<mappers>
<mapper class="com.lyrpx.mapper.IStudentMapper"/>
</mappers>
在项目src/main/java目录下创建com.lyrpx.utils包,在com.lyrpx.utils包下创建MyTool 工具类,该类用于封装读取配置文件信息的代码。具体代码如下所示。
MyTool .java
package com.lyrpx.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.InputStream;
public class MyTool {
private static SqlSessionFactory factory;//静态工厂
static {//创建静态工厂对象
try {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
factory=new SqlSessionFactoryBuilder().build(in);
}catch (Exception e){
e.printStackTrace();
}
}
//获取回话对象
public static SqlSession getSqlSession() {
return factory.openSession(true);
}
}
为了验证上述配置,在项目的src/test/java目录下创建Test文件夹,在Test文件夹创建测试类MyTest,在测试类MyTest中编写测试方法findIStudentByIdTest (),具体代码如下所示。
1@Test
2public void findIStudentByIdTest() {
3 // 1.通过工具类获取SqlSession对象
4 SqlSession session = MyBatisUtils.getSession();
5 IStudentMapper mapper = session.getMapper(IStudentMapper.class);
6 // 2.使用IStudentMapper对象查询id为1的学生的信息
7 IStudent student = mapper.selectStudent(2);
8 System.out.println(student.toString());
9 // 3.关闭SqlSession
10 session.close();
11}
findIStudentByIdTest()方法的运行结果

(1)在IStudentMapper接口中编写selectStudentByCid()方法,通过cid查询对应班级中的学生信息。
selectStudentByCid()方法具体代码如下所示。
@Select("select * from s_student where cid=#{id} ")
@Results({@Result(id = true,column = "id",property = "id"),
@Result(column = "classname",property = "classname")
})
List<IStudent> selectStudentByCid(int cid);
上述代码中,第1行代码使用@Select注解映射根据c_id查询IStudent对象的SQL语句,当程序调用@Select注解标注的selectStudentByCid
()方法时,@Select注解中映射的查询语句将被执行;第2~4行代码使用@Results注解映射查询结果,在@Results注解中,使用@Result注解完成IStudent实体类中属性和数据表中字段的映射。
(2)在项目的com.lyrpx.mapper包下创建IClassMapper接口,在该接口中编写selectClassById ()方法,通过id查询班级信息。
IClassMapper接口具体代码如下所示。
package com.lyrpx.mapper;
import com.lyrpx.pojo.IClass;
import org.apache.ibatis.annotations.Many;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
public interface IClassMapper {
@Select("select * from c_class where id=#{id} ")
@Results({@Result(id = true, column = "id", property = "id"),
@Result(column = "classname", property = "classname"),
@Result(column = "id", property = "studentList",
many = @Many(select =
"com.lyrpx.mapper.IStudentMapper.selectStudentByCid"))})
IClass selectClassById(int id);
}
上述代码中,第8行代码使用@Select注解映射根据id查询IClass对象的SQL语句,当程序调用@Select注解标注的selectClassById
()方法时,@Select注解中映射的查询语句将被执行; 第9 ~
13行代码使用@Results注解映射查询结果,在@Results注解中,使用3个@Result注解完成IClass实体类中属性和数据表中字段的映射。其中,第12~13行代码通过@Many注解表明数据表c_class和s_student之间是一对多关联关系。在@Many注解中,select属性用于指定关联属性studentList的值是通过执行com.lyrpx.dao包中IStudentMapper接口定义的selectStudentByCid
()方法获得的。
在核心配置文件mybatis-config.xml中的元素下引入IClassMapper接口,将IClassMapper接口加载到核心配置文件中,具体代码如下所示。
<mapper class="com.lyrpx.mapper.IClassMapper"/>
为了验证上述配置,可以在测试类MyTest中,编写测试方法selectClassByIdTest (),具体代码如下所示。
@Test
public void selectClassByIdTest() {
// 1.通过工具类生成SqlSession对象
SqlSession session = MyTool.getSession();
IClassMapper mapper = session.getMapper(IClassMapper.class);
// 2.查询id为2的班级中学生的信息
IClass icalss = mapper.selectClassById(2);
System.out.println(icalss.toString());
session.close();
}
效果图

我正在使用i18n从头开始构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在rubyonrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
我想用ruby编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序
我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此
我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r
刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr
我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R
我安装了ruby版本管理器,并将RVM安装的ruby实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby。有没有办法让emacs像shell一样尊重ruby的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el
如何检查Ruby文件是否是通过“require”或“load”导入的,而不是简单地从命令行执行的?例如:foo.rb的内容:puts"Hello"bar.rb的内容require'foo'输出:$./foo.rbHello$./bar.rbHello基本上,我想调用bar.rb以不执行puts调用。 最佳答案 将foo.rb改为:if__FILE__==$0puts"Hello"end检查__FILE__-当前ruby文件的名称-与$0-正在运行的脚本的名称。 关于ruby-检查是否