接上,在PersonDao.java中逐项完成方法。
PreparedStatement pmst;
Connection conn;
ResultSet rs;
增加数据:
public int addPerson(Person p) {
int i = 0;
//1.与数据库建立连接
conn = OaUtils.getConnection();
//2.sql语句
String sql = "insert into users values(?,?,?,?,?)";
try{
//3.创建PreparedStatement对象
pmst = conn.prepareStatement(sql);
//4.为占位符传值
pmst.setInt(1, p.getId());
pmst.setString(2, p.getName());
pmst.setString(3, p.getSex());
pmst.setInt(4, p.getAge());
pmst.setString(5, p.getPhone());
//5.执行sql语句
i = pmst.executeUpdate();
//释放资源
pmst.close();
conn.close();
}catch(Exception e){
e.printStackTrace();
}
return i;
}
在OaTest.java中进行测试:
@Test
public void test2(){
Person p = new Person(5,"李莲英","男",20,"158121111");
int i = dao.addPerson(p);
if(i>0){
System.out.println("插入成功!");
}else{
System.out.println("插入失败!");
}
}
运行test2,插入成功:
事物:
将id设为主键后,如果表中已有该id的值,应该报错。
在“com.xmx.oa.test”包下新建一个class“TrasctionDemo.java”
我们关闭事物自动提交,改为手动提交,并回滚:
@Test
public void test1(){
//1.与数据库建立连接
Connection conn = OaUtils.getConnection();
//SQL语句
String sql1 = "insert into users values(1,'爱好','男',20,'2424')";
String sql2 = "insert into users values(3,'第三方','女',34,'2dsg')";
String sql3 = "insert into users values(2,'的','男',31,'22fd4')";
String sql4 = "insert into users values(4,'啊','女',80,'3dfs4')";
try {
//2.关闭事物自动提交
conn.setAutoCommit(false);
Statement smt = conn.createStatement();
smt.executeUpdate(sql1);
smt.executeUpdate(sql2);
smt.executeUpdate(sql3);
smt.executeUpdate(sql4);
//3.手动提交
conn.commit();
System.out.println("插入成功!");
//释放资源
smt.close();
conn.close();
} catch (Exception e) {
//4.回滚到先前状态
System.out.println("出现异常,马上回滚!");
try {
conn.rollback();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}
}
这样可以避免在多次操作中因一步错误而产生影响。
删除单条数据:
public int deletePersonById(int id) {
int i = 0;
//1.与数据库建立连接
conn = OaUtils.getConnection();
//2.sql语句
String sql = "delete from users where id=?";
try{
//关闭事物自动提交
conn.setAutoCommit(false);
//3.创建PreparedStatement对象
pmst = conn.prepareStatement(sql);
//4.为占位符传值
pmst.setInt(1, id);
//4.执行sql语句
i = pmst.executeUpdate();
//手动提交
conn.commit();
//释放资源
pmst.close();
conn.close();
}catch(Exception e){
//回滚到先前状态
System.out.println("出现异常,马上回滚!");
try {
conn.rollback();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}
return i;
}
测试:
public void test3(){
int i = dao.deletePersonById(5);
if(i>0){
System.out.println("删除成功!");
}else{
System.out.println("删除失败!");
}
}
修改数据:
public int updatePerson(Person p) {
int i = 0;
//1.与数据库建立连接
conn = OaUtils.getConnection();
//2.sql语句
String sql = "update users set name=?, sex=?, age=?, phone=? where id=? ";
try{
//关闭事物自动提交
conn.setAutoCommit(false);
//3.创建PreparedStatement对象
pmst = conn.prepareStatement(sql);
//4.为占位符传值
pmst.setString(1, p.getName());
pmst.setString(2, p.getSex());
pmst.setInt(3, p.getAge());
pmst.setString(4, p.getPhone());
pmst.setInt(5, p.getId());
//4.执行sql语句
i = pmst.executeUpdate();
//手动提交
conn.commit();
//释放资源
pmst.close();
conn.close();
}catch(Exception e){
//回滚到先前状态
System.out.println("出现异常,马上回滚!");
try {
conn.rollback();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}
return i;
}
测试:
public void test4(){
Person p = new Person(5,"李莲英","男",20,"110");
int i = dao.updatePerson(p);
if(i>0){
System.out.println("修改成功!");
}else{
System.out.println("修改失败!");
}
}
增删改:
观察可以得到,增加删除和修改操作中大体步骤是相同的,只有sql语句和传入的参数不同。
考虑把它们合成一条:
public int executeUpdate(String sql, Object...parameters){
int i = 0;
//1.与数据库建立连接
conn = OaUtils.getConnection();
try{
//关闭事物自动提交
conn.setAutoCommit(false);
//3.创建PreparedStatement对象
pmst = conn.prepareStatement(sql);
//4.为占位符传值
if(parameters!=null && parameters.length>0){
for(int j=0; j<parameters.length; j++){
pmst.setObject(j+1, parameters[j]);
}
}
//5.执行sql语句
i = pmst.executeUpdate();
//手动提交
conn.commit();
//释放资源
pmst.close();
conn.close();
}catch(Exception e){
//回滚到先前状态
System.out.println("出现异常,马上回滚!");
try {
conn.rollback();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}
return i;
}
传入的参数为sql语句和多个参数Object...parameters。
xxx.setObject(j+1, parameters[j]);中,j+1表示sql语句中的占位符(从1开始,而j是从0开始),parameters[j]表示传入的多个参数。
测试:
public void test5(){
//增加
// Person p = new Person(6,"魏忠贤","男",35,"1123123");
// String sql = "insert into users values(?,?,?,?,?)";
// int i = dao.executeUpdate(sql, p.getId(), p.getName(), p.getSex(), p.getAge(), p.getPhone());
//删除
// String sql = "delete from users where id=?";
// int i = dao.executeUpdate(sql, "1");
//修改
Person p = new Person(5,"魏忠贤","女",35,"1123123");
String sql = "update users set name=?, sex=?, age=?, phone=? where id=?";
int i = dao.executeUpdate(sql, p.getName(), p.getSex(), p.getAge(), p.getPhone(), p.getId());
if(i>0){
System.out.println("成功!");
}else{
System.out.println("失败!");
}
}
测试各项需要分开测试。
查询所有信息:
public List<Person> findAllPerson() {
List<Person> list = new ArrayList<Person>();
//1.与数据库建立连接
conn = OaUtils.getConnection();
//2.sql语句
String sql = "select * from users order by id ";
try{
//3.创建PreparedStatement对象
pmst = conn.prepareStatement(sql);
//4.执行查询语句
rs = pmst.executeQuery(sql);
while (rs.next()){
int id = rs.getInt(1);
String name = rs.getString(2);
String sex = rs.getString(3);
int age = rs.getInt(4);
String phone = rs.getString(5);
//5.封装到Person对象中
Person p = new Person(id, name, sex, age, phone);
//6.添加到集合中
list.add(p);
}
//7.释放资源
rs.close();
pmst.close();
conn.close();
}catch(Exception e){
e.printStackTrace();
}
return list;
}
该方法的返回类型为List<Person>,因此首先定义一个该类型的list。
这里执行查询语句executeQuery(sql),与上述的更新语句executeUpdate()不同。
因为list里面的对象是Person类型的,而getString和getInt方法取出的是String和int类型,因此取出后先封装到Person中:Person p = new Person(id, name, sex, age, phone);最后再加进list:list.add(p);
测试:
public void test6(){
List<Person> list = dao.findAllPerson();
for(Person p:list){
System.out.println(p);
}
}
按id查询信息:
public Person findByIdPerson(int id) {
Person p = new Person();
//1.与数据库建立连接
conn = OaUtils.getConnection();
//2.sql语句
String sql = "select * from users where id= "+id;
try{
//3.创建PreparedStatement对象
pmst = conn.prepareStatement(sql);
//4.为占位符传值(加了这行就报错)
// pmst.setInt(1, id);
//5.执行查询语句
rs = pmst.executeQuery(sql);
rs.next();
String name = rs.getString(2);
String sex = rs.getString(3);
int age = rs.getInt(4);
String phone = rs.getString(5);
//6.封装到Person对象中
p = new Person(id, name, sex, age, phone);
//释放资源
rs.close();
pmst.close();
conn.close();
}catch(Exception e){
e.printStackTrace();
}
return p;
}
这里注意返回类型为Person型,跟上个方法不同,它只需要显示一条信息,因此仅是少了加入集合的步骤。
测试:
public void test7(){
Person p = dao.findByIdPerson(10);
System.out.println(p.toString());
}
按id删除多组:
public int deleteManyPerson(int[] id) {
int i = 0;
//1.与数据库建立连接
conn = OaUtils.getConnection();
//2.sql语句
String sql = "delete from users where id=?";
try{
//关闭事物自动提交
conn.setAutoCommit(false);
//3.创建PreparedStatement对象
pmst = conn.prepareStatement(sql);
for(int j=0; j<id.length; j++){
//4.为占位符传值
pmst.setInt(1, id[j]);
//4.执行sql语句
i = pmst.executeUpdate();
}
//手动提交
conn.commit();
//释放资源
pmst.close();
conn.close();
}catch(Exception e){
//回滚到先前状态
System.out.println("出现异常,马上回滚!");
try {
conn.rollback();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}
return i;
}
这里传入的是数组,因此为占位符传值时我们使用一个循环来多次执行,以达到删除多项的目的。
测试:
public void test8(){
int[] id = new int[]{2, 5};
int i = dao.deleteManyPerson(id);
if(i>0){
System.out.println("删除成功!");
}else{
System.out.println("删除失败!");
}
}
分页查询:
- 在mysql中支持分页查询
- select * from <表名> limit m,n
- m表示从第几条开始
- n表示显示几条
- 分页时传递的是你的当前页面和每页显示的条数
- select * from <表名> limit (currentpage-1)*size, size
public List<Person> findByPage(int currentpage, int size) {
List<Person> list = new ArrayList<Person>();
//1.与数据库建立连接
conn = OaUtils.getConnection();
//2.sql语句
int m = (currentpage-1)*size;
int n = size;
String sql = "select * from users limit "+m+","+n;
// System.out.println(sql);
try{
//3.创建PreparedStatement对象
pmst = conn.prepareStatement(sql);
//4.执行查询语句
rs = pmst.executeQuery(sql);
while (rs.next()){
int id = rs.getInt(1);
String name = rs.getString(2);
String sex = rs.getString(3);
int age = rs.getInt(4);
String phone = rs.getString(5);
//5.封装到Person对象中
Person p = new Person(id, name, sex, age, phone);
//6.添加到集合中
list.add(p);
}
//7.释放资源
rs.close();
pmst.close();
conn.close();
}catch(Exception e){
e.printStackTrace();
}
return list;
}
测试:
public void test9(){
int[] id = new int[]{2, 5};
int i = dao.deleteManyPerson(id);
if(i>0){
System.out.println("删除成功!");
}else{
System.out.println("删除失败!");
}
}
高级搜索:
public List<Person> superQuery(Person p){
List<Person> list = new ArrayList<Person>();
//1.与数据库建立连接
conn = OaUtils.getConnection();
//2.动态添加sql语句
StringBuilder sql = new StringBuilder("select * from users where 1=1");//1=1为假条件
if(p.getName()!=null && p.getName()!=""){
sql.append(" and name="+"'"+p.getName()+"'");
}
if(p.getSex()!=null && p.getSex()!=""){
sql.append(" and sex="+"'"+p.getSex()+"'");
}
if(p.getPhone()!=null && p.getPhone()!=""){
sql.append(" and phone="+"'"+p.getPhone()+"'");
}
// System.out.println(sql.toString());
try{
//3.创建PreparedStatement对象
pmst = conn.prepareStatement(sql.toString());
//4.执行查询语句
rs = pmst.executeQuery();
while (rs.next()){
int id = rs.getInt(1);
String name = rs.getString(2);
String sex = rs.getString(3);
int age = rs.getInt(4);
String phone = rs.getString(5);
//5.封装到Person对象中
Person p1 = new Person(id, name, sex, age, phone);
//6.添加到集合中
list.add(p1);
}
//7.释放资源
rs.close();
pmst.close();
conn.close();
}catch(Exception e){
e.printStackTrace();
}
return list;
}
StringBuilder实现字符串的动态拼接,append();
或者使用String.format(s,....);用占位符%s和%d也行:
String s = "select * from users where %s %s %s";
String s1="", s2="", s3="";
if(p.getName()!=null && p.getName()!=""){
s1 = "name='"+p.getName()+"'";
}
if(p.getSex()!=null && p.getSex()!=""){
s2 = "and sex='"+p.getSex()+"'";
}
if(p.getPhone()!=null && p.getPhone()!=""){
s3 = "and phone='"+p.getPhone()+"'";
}
String sql = String.format(s, s1, s2, s3);
如要实现模糊查询,把“=”改成“like”,在字段前后都加入“%”即可:
s1 = "name like'%"+p.getName()+"%'";
测试:
public void test10(){
Person p = new Person("name1", "man", null);
List<Person> list = dao.superQuery(p);
for(Person p1:list){
System.out.println(p1);
}
}