• JDBC批处理存储过程及事务


    存储过程是数据库中一种预编译的SQL语句代码集,类似于Java的方法封装具有很高重用功能。

    优点:执行效率高,提高访问速度。

    缺点:更换数据库系统时存储过程不兼容。

    JDBC API

    CallableStatement接口是唯一处理数据库系统存储过程的通用组件

    CallableStatement接口

    CallableStatementPreparedStatement接口的子接口用来操作存储过程,此接口由Connection对象获得其实例

    批处理

    批处理(Batch process)是指一次连接访问数据中发送一组SQL操作语句,通常对数据库多条数据进行更新操作。

    合理使用批处理能够在最少次访问数据库时执行多条SQL操作从而提高数据库的访问速度并提高数据库的应用效率。

    一般情况下批处理执行类似的相近操作,如批量修改,批量删除,批量插入等。

    Statement接口批处理方法

    void addBatch(String sql)throws SQLException

    int[] executeBatch()throws SQLException

    oid clearBatch()throws SQLException

    void addBatch()throws SQLException

    JDBC事务处理

    原子性——不可分割

    隔离性——事物之间的边界

    一致性——确保数据正确一致

    持久型——永久影响数据库

    对于默认的JDBC操作,事务的执行是自动开启的,每个sql执行都将在不产生错误时自动提交,如果在一个线程方法中涉及多个相关sql语句操作,则应在程序中设计事务的手动处理,要么全部成功提交(commit)事务,要么出现操作异常回滚(rollback)所有操作。

    Connection事务处理相关方法

    void setAutoCommit(boolean autoCommit)

    void commit()

    void rollback()

    Savepoint setSavepoint(String name)

    void setTransactionIsolation(int level)

    void rollback(Savepoint savepoint)

    分事务的隔离级别

    TRANSACTION_NONE 不支持事务

    TRANSACTION_READ_COMMITTED 禁止脏读和不可重复读,允许虚读(默认)

    TRANSACTION_READ_UNCOMMITTED 允许脏读、不可重复读和虚读

    TRANSACTION_REPEATABLE_READ 禁止脏读和不可重复读;允许虚读

    TRANSACTION_SERIALIZABLE 禁止脏读、不可重复读和虚读

    脏读dirty reads:当事务读取还未提交的数据时,就会发生这种事件。举例来说:Transaction1修改了一行数据,然后Transcation2Transaction1还未提交修改操作之前读取了被修改的行。如果Transaction1回滚了修改操作,那么Transaction2读取的数据就可以看作是从未存在过的。

    不可重复的读non-repeatable reads:当事务两次读取同一行数据,但每次得到的数据都不一样时,就会发生这种事件。举例来说:Transaction1读取一行数据,然后Transaction2修改或删除该行并提交修改操作。当Transaction1试图重新读取该行时,它就会得到不同的数据值(如果该行被更新)或发现该行不再存在(如果该行被删除)

    虚读phantom read:如果符合搜索条件的一行数据在后面的读取操作中出现,但该行数据却不属于最初的数据,就会发生这种事件。举例来说:Transaction1读取满足某种搜索条件的一些行,然后Transaction2插入了符合Transaction1的搜索条件的一个新行。如果Transaction1重新执行产生原来那些行的查询,就会得到不同的行。

    今天JDBC作业中遇到一个错误:

    java.sql.SQLException: 索引中丢失  IN OUT 参数:: 4

    这个原因是数据库中的字段类型与SQL语句中的类型不匹配造成的,后边的数字,代表第几个参数错误。找到对应参数配置或者SQL中这个参数的类型是否与数据库中匹配,更改后便解决了!

    sql语句中要求SEX值为1时显示为"男",为0时显示为"女";

    select s.id,s.numbers,s.name,case when s.gender = '1' then ''

    when s.gender = '0' then '' end sex,

    s.birth,s.phone,s.daid,s.cid,s.apartment,s.descripte

    from students s inner join classinfo c on s.cid = c.id and c.id = (select c.id from classinfo c where c.name = '信管2')

    order by s.birth desc

    Statement和PreparedStatement的区别,Statement是拼接的数据库语句,传过去的时候已经把参数都拼好了。PreparedStatement是可预编译的,先传sql语句过去,再传问号占位,最后传参数。

    如果是确实是用JDBC写的话,肯定是使用prepare statement,不会用statements,statements不安全。

    /*在SubjectDao中定义方法实现添加新学科的功能;
    在ScoreDao 中定义方法实现添加学生成绩;
    在相应的XXXDao 数据访问组件中添加相应方法完成以下功能需求:
    4 根据给定的学科名称获取此属于此学科的所有及格成绩,并显示成绩的谁(学生姓名)的,及此学生属于哪个班级(显示班级名称);
    
    任务1 分页查询功能
    1 分页查询显示所有学科的学生成绩信息,包括学科名称,学生姓名,学号,分数,考试日期,是否及格;
    2 分页查询显示所有某学科的所有学生成绩信息,包括学科名称,学生姓名,学号,分数,考试日期,是否及格;
    3 分页查询显示某个班级的某个学科的所有成绩,包括班级名称,学科名称,学生姓名,分数,考试日期;
    
    任务2 数据统计
    4 分别统计不同专业下的所有学生人数,要求显示专业代码,专业名称,人数;
    5 按照学生分组分别统计此学生的某个学科成绩的总分,平均分,要求显示学生ID,学生姓名;
    6 实现将给定的的两个班级和学科名称汇总显示此两个班级的此学科总分和平飓风。
    
    1 在数据库中定义一个存储过程,完成给定班级名称和学号及学科,获取此学生此学科成绩所有信息,在应用程序中定义相关方法完成调用此存储过程显示成绩信息。
    */
    
    package com.xzit.platform.edu.dao;
    
    import com.xzit.platform.edu.pojo.Score;
    import com.xzit.util.DataSourceManager;
    import oracle.jdbc.OracleTypes;
    
    import java.sql.*;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    public class ScoreDao {
        /**
         *4 根据给定的学科名称获取此属于此学科的所有及格成绩,
         * 并显示成绩的谁(学生姓名)的,及此学生属于哪个班级(显示班级名称);
         * @param subjectName 要查询的学科名字
         * @return
         */
        public List<Map<String,Object>> queryScoresBySubject(String subjectName){
            List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
            String sql = "select stu.name,cla.name,sub.name,sco.scores " +
                    "from students stu inner join score sco on stu.id = sco.stuid " +
                    "inner join subject sub on sco.subid = sub.id " +
                    "inner join classinfo cla on cla.id = stu.cid " +
                    "where sub.name = '"+subjectName+"' " +
                    "and sco.scores > 60";
            Connection conn = DataSourceManager.getConnection();    //获取连接
            PreparedStatement ps = null;    //获取PreparedStatement接口对象
            ResultSet set = null;
            try {
                ps = conn.prepareStatement(sql);
                set = ps.executeQuery();    //查询返回ResultSet结果集对象
                /* 处理结果集,封装结果集中的Java对象 */
                while(set.next()){
                    Map<String,Object> map = new HashMap<String,Object>(); //每行记录封装为Map对象
                    map.put("stuName",set.getString(1));
                    map.put("claName",set.getString(2));
                    map.put("subName",set.getString(3));
                    map.put("scoName",set.getString(4));
                    list.add(map);//将Map对象添加到List集合中
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } finally {
                DataSourceManager.close(set);
                DataSourceManager.close(ps);
                DataSourceManager.close(conn);
            }
            return list;//返回封装Map对象的List接口对象
        }
    
    
        /**
         * 1 分页查询显示所有学科的学生成绩信息,包括学科名称,学生姓名,学号,分数,考试日期,是否及格;
         * @param pageNum
         * @param pageSize
         * @return
         */
        public Map<String,Object> queryAllSubjectScore(int pageNum,int pageSize){
            Map<String,Object> map = new HashMap<>();
    
            Connection conn = DataSourceManager.getConnection();    //获取连接
            PreparedStatement ps2 = null;   //执行查询下统计条目数
            PreparedStatement ps3 = null;   //执行查询结果
    
            ResultSet set2 = null;  //封装统计条目的结果集
            ResultSet set3 = null;  //封装统计查询结果集
    
            int rowCount = 0;//总记录条目数
            int pageSum = 0;//最后分页数量
    
            /* 统计符合查询条件的总记录行数 */
            String rowcountSql = "select COUNT(ID) ROWCOUNT FROM score";
            /* 分页查询sql */
            String pagingSql = "select s4.name subjectName," +
                    "s5.name studentName," +
                    "s5.numbers studentNum," +
                    "s3.scores scores," +
                    "s3.testdate testday," +
                    "case when s3.ispass = '1' then '及格' " +
                    "when s3.ispass = '0' then '不及格' end " +
                    "from (select rownum rt,s2.* from score s2 where rownum <=?) s3 " +
                    "inner join subject s4 on s3.subid = s4.id " +
                    "inner join students s5 on s3.stuid = s5.id " +
                    "where s3.rt >=?";
    
            try {
                ps2 = conn.prepareStatement(rowcountSql);
                set2 = ps2.executeQuery();//执行条目统计
                while(set2.next()){
                    rowCount = set2.getInt(1);
                }
                map.put("rowCount",rowCount);
                /* 统计总共分成多少页(总记录行数/pageSize) */
                pageSum = countPageSum(rowCount,pageSize);
                map.put("pageSum",pageSum);
                /* 统计符合条件每页结果集 */
                ps3 = conn.prepareStatement(pagingSql);
                ps3.setInt(1,pageSize*pageNum);//设置第一个?
                ps3.setInt(2,pageSize*pageNum-(pageSize-1));
                set3 = ps3.executeQuery();
                List<Map<String,Object>> rows = new ArrayList<>();
                while (set3.next()){
                    Map<String,Object> rowMap = new HashMap<>();
                    rowMap.put("subjectName",set3.getString(1));
                    rowMap.put("studentName",set3.getString(2));
                    rowMap.put("studentNum",set3.getString(3));
                    rowMap.put("scores",set3.getString(4));
                    rowMap.put("testday",set3.getDate(5));
                    rows.add(rowMap);
                }
                map.put("rows",rows);//添加到查询结果集List map中
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } finally {
                DataSourceManager.close(set3);
                DataSourceManager.close(set2);
                DataSourceManager.close(ps3);
                DataSourceManager.close(ps2);
                DataSourceManager.close(conn);
            }
            return map;
        }
    
        /**
         * 计算总共分成多少页
         * @param rowCount
         * @param pageSize
         * @return
         */
        public int countPageSum(int rowCount,int pageSize){
            /**
             * 三目运算符,如果总行数rowCount除以一页要显示的行数pageSize余0,
             * 意味着一页中可以显示pageSize这么多行,例总行数10行,除以要显示5行余0,意味着可以分成2页
             * 否则显示rowCount/pageSize+1行,例总行数11行,除以要显示5行等于2.2,+1等于3.2,约等于3页
             */
            return rowCount%pageSize==0 ? rowCount/pageSize : rowCount/pageSize+1;
        }
    
        /**
         * 2 分页查询显示所有某学科的所有学生成绩信息,包括学科名称,学生姓名,学号,分数,考试日期,是否及格;
         * @param pageNum
         * @param pageSize
         * @return
         */
        public Map<String,Object> queryScoreBySubName(int pageNum,int pageSize,String subjectName){
            Map<String,Object> map = new HashMap<>();
    
            Connection conn = DataSourceManager.getConnection();    //获取连接
            PreparedStatement ps2 = null;   //执行查询下统计条目数
            PreparedStatement ps3 = null;   //执行查询结果
    
            ResultSet set2 = null;  //封装统计条目的结果集
            ResultSet set3 = null;  //封装统计查询结果集
    
            int rowCount = 0;//总记录条目数
            int pageSum = 0;//最后分页数量
    
            /* 统计符合查询条件的总记录行数 */
            String rowcountSql = "select COUNT(s1.ID) ROWCOUNT FROM score s1 " +
                    "inner join subject s2 on s1.subid = s2.id " +
                    "where s2.name = '"+subjectName+"'";
            /* 分页查询sql */
            String pagingSql = "select s4.name subjectName," +
                    "s5.name studentName," +
                    "s5.numbers studentNum," +
                    "s3.scores scores," +
                    "s3.testdate testday," +
                    "case when s3.ispass = '1' then '及格' " +
                    "when s3.ispass = '0' then '不及格' end " +
                    "from (select rownum rt,s2.* from score s2 where rownum <=?) s3 " +
                    "inner join subject s4 on s3.subid = s4.id " +
                    "inner join students s5 on s3.stuid = s5.id " +
                    "where s3.rt >=? and s4.name = ?";
    
            try {
                ps2 = conn.prepareStatement(rowcountSql);
                set2 = ps2.executeQuery();//执行条目统计
                while(set2.next()){
                    rowCount = set2.getInt(1);
                }
                map.put("rowCount",rowCount);
                /* 统计总共分成多少页(总记录行数/pageSize) */
                pageSum = countPageSum(rowCount,pageSize);
                map.put("pageSum",pageSum);
                /* 统计符合条件每页结果集 */
                ps3 = conn.prepareStatement(pagingSql);
                ps3.setInt(1,pageSize*pageNum);//设置第一个?
                ps3.setInt(2,pageSize*pageNum-(pageSize-1));
                ps3.setString(3,subjectName);
                set3 = ps3.executeQuery();
                List<Map<String,Object>> rows = new ArrayList<>();
                while (set3.next()){
                    Map<String,Object> rowMap = new HashMap<>();
                    rowMap.put("subjectName",set3.getString(1));
                    rowMap.put("studentName",set3.getString(2));
                    rowMap.put("studentNum",set3.getString(3));
                    rowMap.put("scores",set3.getString(4));
                    rowMap.put("testday",set3.getDate(5));
                    rows.add(rowMap);
                }
                map.put("rows",rows);//添加到查询结果集List map中
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } finally {
                DataSourceManager.close(set3);
                DataSourceManager.close(set2);
                DataSourceManager.close(ps3);
                DataSourceManager.close(ps2);
                DataSourceManager.close(conn);
            }
            return map;
        }
    
        /**
         * 3 分页查询显示某个班级的某个学科的所有成绩,包括班级名称,学科名称,学生姓名,分数,考试日期;
         * @param pageNum
         * @param pageSize
         * @return
         */
        public Map<String,Object> queryScoreByClassInfo(int pageNum,int pageSize,String className){
            Map<String,Object> map = new HashMap<>();
    
            Connection conn = DataSourceManager.getConnection();    //获取连接
            PreparedStatement ps2 = null;   //执行查询下统计条目数
            PreparedStatement ps3 = null;   //执行查询结果
    
            ResultSet set2 = null;  //封装统计条目的结果集
            ResultSet set3 = null;  //封装统计查询结果集
    
            int rowCount = 0;//总记录条目数
            int pageSum = 0;//最后分页数量
    
            /* 统计符合查询条件的总记录行数 */
            String rowcountSql = "select COUNT(s1.ID) ROWCOUNT FROM score s1 " +
                    "inner join students s5 on s1.stuid = s5.id " +
                    "inner join subject s2 on s1.subid = s2.id " +
                    "inner join ClassInfo c1 on s5.cid = c1.id " +
                    "where c1.name =  '"+className+"'";
            /* 分页查询sql */
            String pagingSql = "select c1.name className," +
                    "s4.name subjectName," +
                    "s5.name studentName," +
                    "s5.numbers studentNum," +
                    "s3.scores scores," +
                    "s3.testdate testday," +
                    "case when s3.ispass = '1' then '及格' " +
                    "when s3.ispass = '0' then '不及格' end " +
                    "from (select rownum rt,s2.* from score s2 where rownum <=?) s3 " +
                    "inner join students s5 on s3.stuid = s5.id " +
                    "inner join subject s4 on s3.subid = s4.id " +
                    "inner join ClassInfo c1 on s5.cid = c1.id " +
                    "where s3.rt >=? and c1.name = ?";
    
            try {
                ps2 = conn.prepareStatement(rowcountSql);
                set2 = ps2.executeQuery();//执行条目统计
                while(set2.next()){
                    rowCount = set2.getInt(1);
                }
                map.put("rowCount",rowCount);
                /* 统计总共分成多少页(总记录行数/pageSize) */
                pageSum = countPageSum(rowCount,pageSize);
                map.put("pageSum",pageSum);
                /* 统计符合条件每页结果集 */
                ps3 = conn.prepareStatement(pagingSql);
                ps3.setInt(1,pageSize*pageNum);//设置第一个?
                ps3.setInt(2,pageSize*pageNum-(pageSize-1));
                ps3.setString(3,className);
                set3 = ps3.executeQuery();
                List<Map<String,Object>> rows = new ArrayList<>();
                while (set3.next()){
                    Map<String,Object> rowMap = new HashMap<>();
                    rowMap.put("className",set3.getString(1));
                    rowMap.put("subjectName",set3.getString(2));
                    rowMap.put("studentName",set3.getString(3));
                    rowMap.put("studentNum",set3.getString(4));
                    rowMap.put("scores",set3.getString(5));
                    rowMap.put("testday",set3.getDate(6));
                    rows.add(rowMap);
                }
                map.put("rows",rows);//添加到查询结果集List map中
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } finally {
                DataSourceManager.close(set3);
                DataSourceManager.close(set2);
                DataSourceManager.close(ps3);
                DataSourceManager.close(ps2);
                DataSourceManager.close(conn);
            }
            return map;
        }
    
        /**
         * 4 分别统计不同专业下的所有学生人数,要求显示专业代码,专业名称,人数;
         * @return
         */
        public List<Map<String,Object>> sumStudentsByMajor(){
            List<Map<String,Object>> list = new ArrayList<>();
            String sql = "select m.id,m.name,sum(s.id) " +
                    "from major m inner join classinfo c on m.id = c.mid " +
                    "inner join students s on c.id = s.cid " +
                    "group by m.id,m.name ";
            Connection conn = DataSourceManager.getConnection();//获取数据库连接
            PreparedStatement ps = null;    //获取PeparedStatement接口对象
            ResultSet set = null;   //创建一个ResultSet结果集
            try {
                ps = conn.prepareStatement(sql);
                set = ps.executeQuery();
                while (set.next()){
                    Map<String,Object> map = new HashMap<>();//每一行封装一个map对象
                    map.put("majorId",set.getString(1));
                    map.put("majorName",set.getString(2));
                    map.put("sumId",set.getString(3));
                    list.add(map);  //将Map对象添加到List集合中
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } finally {
                DataSourceManager.close(set);
                DataSourceManager.close(ps);
                DataSourceManager.close(conn);
            }
            return list;//返回封装Map对象的List接口对
        }
    
        /**
         * 5 按照学生分组分别统计此学生的某个学科成绩的总分,平均分,要求显示学生ID,学生姓名;
         * @param subjectName
         * @return
         */
        public List<Map<String,Object>> sumScoreBySubject(String subjectName){
            List<Map<String,Object>> list = new ArrayList<>();
            String sql = "select s3.id,s3.name,s2.name,sum(s1.scores),avg(s1.scores) " +
                    "from score s1 inner join subject s2 on s1.subid = s2.id " +
                    "inner join students s3 on s1.stuid = s3.id " +
                    "and s2.name = '"+subjectName+"'" +
                    "group by s3.id,s3.name,s2.name ";
            Connection conn = DataSourceManager.getConnection();//获取数据库连接
            PreparedStatement ps = null;    //获取PeparedStatement接口对象
            ResultSet set = null;   //创建一个ResultSet结果集
    
            try {
                ps = conn.prepareStatement(sql);
                set = ps.executeQuery();
                while (set.next()){
                    Map<String,Object> map = new HashMap<>();//每一行封装一个map对象
                    map.put("stuId",set.getString(1));
                    map.put("stuName",set.getString(2));
                    map.put("subName",set.getString(3));
                    map.put("sumScore",set.getString(4));
                    map.put("avgScore",set.getString(5));
                    list.add(map);//将Map对象添加到List集合中
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } finally {
                DataSourceManager.close(set);
                DataSourceManager.close(ps);
                DataSourceManager.close(conn);
            }
    
            return list;
        }
    
        /**
         * 6 实现将给定的的两个班级和学科名称汇总显示此两个班级的此学科总分和平均分。
         * @param classname1
         * @param classname2
         * @param subjectName
         * @return
         */
        public List<Map<String,Object>> sumScoreByClassInfo(String classname1,String classname2,String subjectName){
            List<Map<String,Object>> list = new ArrayList<>();
            String sql = "select c.name," +
                    "s3.name," +
                    "sum(s2.scores)," +
                    "avg(s2.scores) " +
                    "from classinfo c inner join students s1 on c.id = s1.cid " +
                    "inner join score s2 on s1.id = s2.stuid " +
                    "inner join subject s3 on s3.id = s2.subid " +
                    "and c.name = '"+classname1+"' " +
                    "and s3.name = '"+subjectName+"' " +
                    "or c.name = '"+classname2+"' " +
                    "and s3.name = '"+subjectName+"' " +
                    "group by c.name,s3.name";
            Connection conn = DataSourceManager.getConnection();//获取数据库连接
            PreparedStatement ps = null;    //获取PeparedStatement接口对象
            ResultSet set = null;   //创建一个ResultSet结果集
            try {
                ps = conn.prepareStatement(sql);
                set = ps.executeQuery();
                while (set.next()){
                    Map<String,Object> map = new HashMap<>();//每一行封装一个map对象
                    map.put("className",set.getString(1));
                    map.put("subName",set.getString(2));
                    map.put("sumScore",set.getString(3));
                    map.put("avgScore",set.getString(4));
                    list.add(map);//将Map对象添加到List集合中
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } finally {
                DataSourceManager.close(set);
                DataSourceManager.close(ps);
                DataSourceManager.close(conn);
            }
    
            return list;
        }
    
        /**
         * 1 在数据库中定义一个存储过程,完成给定班级名称和学号及学科,
         * 获取此学生此学科成绩所有信息,在应用程序中定义相关方法完成调用此存储过程显示成绩信息。
         * @param stuNumbers
         * @param subjectName
         * @return
         */
        public List<Map<String,Object>> callProcedure3(String stuNumbers,String subjectName){
            List<Map<String,Object>> list = new ArrayList<>();
            String procName = "{call pro_querySubject(:stuNumbers,:subjectName,:datas)}";
            Connection conn = DataSourceManager.getConnection();//获取数据库连接
            CallableStatement call = null;
            ResultSet rs = null;
            try {
                call = conn.prepareCall(procName);//创建CallableStatement对象
                /* 注册oralce游标类型,此类型可以封装查询结果 */
                call.registerOutParameter("stuNumbers",Types.VARCHAR);
                call.setString("stuNumbers",stuNumbers);
                call.registerOutParameter("subjectName",Types.VARCHAR);
                call.setString("subjectName",subjectName);
                call.registerOutParameter("datas", oracle.jdbc.OracleTypes.CURSOR);
                call.execute();
                rs = (ResultSet) call.getObject("datas");//获取返回输出类型
                while(rs.next()){//遍历结果集封装为对象
                    Map<String,Object> map = new HashMap<>();
                    map.put("stuNumber",rs.getString(1));
                    map.put("className",rs.getString(2));
                    map.put("subName",rs.getString(3));
                    map.put("scores",rs.getString(4));
                    list.add(map);
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } finally {
                DataSourceManager.close(rs);
                DataSourceManager.close(call);
                DataSourceManager.close(conn);
            }
            return list;
        }
    }
    /* 在SubjectDao中定义方法实现添加新学科的功能;
    在ScoreDao 中定义方法实现添加学生成绩;
    在相应的XXXDao 数据访问组件中添加相应方法完成以下功能需求:
    1 根据给定的院系名称获取属于此院系的所有专业信息;
    2 根据给定的专业获取此专业下的班级信息,使用Map封装每个班级信息;
    3 根据给定的班级名称获取此班级下的所有性别为男的学生信息,并按照生日排序(倒序),性别为1以”男”作为显示;
     */
    
    package com.xzit.platform.edu.dao;
    
    import com.xzit.platform.edu.pojo.Students;
    import com.xzit.platform.edu.pojo.Subject;
    import com.xzit.util.DataSourceManager;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    public class SubjectDao {
        /**
         * 1 根据给定的院系名称获取属于此院系的所有专业信息
         * @return
         */
        public List<Subject> querySubjectList(){
            List<Subject> subList = new ArrayList<Subject>();
            String sql = "select ID subid,NUMBERS subnum,NAME subname," +
                    "OBLIGATORY subobl,STATUS substa,CREATEDATE subcreate," +
                    "DESCRIPTION subdesc from subject";
            Connection conn = DataSourceManager.getConnection();    //获取连接
            PreparedStatement ps = null;    //获取PreparedStatement接口对象
            ResultSet set = null;
            try {
                ps = conn.prepareStatement(sql);
                set = ps.executeQuery();    //查询返回ResultSet结果对象
                /* 处理结果集,封装结果集中行为java对象 */
                while(set.next()){
                    Subject sub = new Subject();//每一行创建一个Subject对象
    //                String id = set.getString(1);   //获取第1列id值
                    sub.setId(set.getString(1));
                    sub.setNumbers(set.getString(2));
                    sub.setName(set.getString(3));
                    sub.setObligatory(set.getString(4));
                    sub.setStatus(set.getString(5));
                    sub.setCreateDate(set.getDate(6));
                    sub.setDescription(set.getString(7));
                    subList.add(sub);
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } finally {
                DataSourceManager.close(set);
                DataSourceManager.close(ps);
                DataSourceManager.close(conn);
            }
            return subList; //封装返回subList集合
        }
    
        /**
         * 2 根据给定的专业获取此专业下的班级信息,使用Map封装每个班级信息
         * @return
         */
        public List<Map<String,Object>> querySubjectClassInfoListMap(){
            List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
            String sql = "select m.id majid,m.name majname," +
                    "c.id claid,c.name claname,c.descripte cladesc " +
                    "from major m inner join classinfo c on m.id = c.mid " +
                    "order by m.id asc";
            Connection conn = DataSourceManager.getConnection();//使用连接池数据源获取连接
            PreparedStatement ps = null;    //获取PreparedStatement接口对象
            ResultSet set = null;
            try {
                ps = conn.prepareStatement(sql);
                set = ps.executeQuery();    //查询返回ResultSet结果集对象
                /* 处理结果集,封装结果集中行为java对象 */
                while(set.next()){
                    Map<String,Object> map = new HashMap<String,Object>(); //每行记录封装为Map对象
                    map.put("majid",set.getString("majid"));
                    map.put("majname",set.getString("majname"));
                    map.put("claid",set.getString("claid"));
                    map.put("claname",set.getString("claname"));
                    map.put("cladesc",set.getString("cladesc"));
                    list.add(map);//添加结果到List中
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } finally {
                DataSourceManager.close(set);
                DataSourceManager.close(ps);
                DataSourceManager.close(conn);
            }
    
            return list;//返回查询结果
        }
    
        /**
         * 3 根据给定的班级名称获取此班级下的所有性别为男的学生信息,并按照生日排序(倒序),性别为1以”男”作为显示;
         * @param className 给定的班级名称
         * @return
         */
        public List<Students> queryStudentsByClassInfo(String className){
            List<Students> list = new ArrayList<Students>();
            String sql = "select s.id sid," +
                    "s.numbers snumber," +
                    "s.name sname," +
                    "case when s.gender = '1' then '男'" +
                    " when s.gender = '0' then '女' end sex," +
                    "s.birth sbirth," +
                    "s.phone sphone," +
                    "s.daid sdaid," +
                    "s.cid scid," +
                    "s.apartment sapa," +
                    "s.descripte sdesc " +
                    "from students s inner join classinfo c on s.cid = c.id " +
                    "and c.id = (select c.id from classinfo c " +
                    "where c.name = '"+className+"')" +
                    " order by s.birth desc";
            Connection conn = DataSourceManager.getConnection();//获取连接
            PreparedStatement ps = null; //获取PreparedStatement接口对象
            ResultSet set = null;
            try {
                ps = conn.prepareStatement(sql);
                set = ps.executeQuery(); //查询返回ResultSet结果集对象
                /* 处理结果集,封装结果集中行为java对象 */
                while(set.next()){
                    Students stu = new Students();//每一行创建一个Student对象
                    stu.setId(set.getString("sid"));
                    stu.setNumbers(set.getString("snumber"));
                    stu.setName(set.getString("sname"));
                    stu.setGender(set.getString("sex"));
                    stu.setBirth(set.getDate("sbirth"));
                    stu.setPhone(set.getString("sphone"));
                    stu.setDaid(set.getString("sdaid"));
                    stu.setApartment(set.getString("scid"));
                    stu.setDescripte(set.getString("sapa"));
                    list.add(stu);//将stu对象添加到List集合中
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } finally {
                DataSourceManager.close(set);
                DataSourceManager.close(ps);
                DataSourceManager.close(conn);
            }
            return list;
        }
    
    }
    package com.xzit.platform.edu.dao;
    /*在应用程序中添加数据访问操作DAO组件类,如下所示:
    FacultyAndMajorDao.java 对Faculty和Majo表实现增删改查
    
    在相应的Dao组件类中定义相关添加院系、专业的方法,实现对院系、专业表的数据插入功能;
    
    实现所有数据表中数据添加功能,应注表之间的关系,合理定义相关必需参数,注意方法命名规范和返回类型的合理性,类和方法必需有注释,关键代码应有注释,正确处理异常*/
    
    import com.xzit.platform.edu.pojo.Faculty;
    import com.xzit.platform.edu.pojo.Major;
    import com.xzit.util.DataSourceManager;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    
    public class FacultyAndMajorDao {
    
        /**
         * 添加新院系的方法
         * @param fac 新添加的院系
         * @return
         */
        public int addFaculty(Faculty fac){
            int res = 0;
            String sql="insert into Faculty " +
                    "(id,name,createdate,descripte) values (?,?,?,?)";//sql插入语句
            Connection conn = DataSourceManager.getConnection();//获取数据库连接
            PreparedStatement ps = null;//获取PreparedStatement接口对象
    
            try {
                ps = conn.prepareStatement(sql);    //获取PrepareStatement对象
                /* 设置替换sql语句中都参数占位符 */
                ps.setString(1,fac.getId());
                ps.setString(2,fac.getName());
                ps.setDate(3,new java.sql.Date(fac.getCreateDate().getTime()) );
                ps.setString(4,fac.getDescripte());
                res = ps.executeUpdate();
    
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } finally {
                DataSourceManager.close(ps);
                DataSourceManager.close(conn);
            }
            return res;
        }
    
        /**
         * 添加新专业的方法
         * @param maj 新添加的专业
         * @return
         */
        public int addMajor(Major maj){
            int res = 0;
            String sql="insert into Major " +
                    "(id,code,name,createdate,fid,descripte) values (?,?,?,?,?,?)";//sql插入语句
            Connection conn = DataSourceManager.getConnection();//获取数据库连接
            PreparedStatement ps = null;//获取PreparedStatement接口对象
    
            try {
                ps = conn.prepareStatement(sql);    //获取PrepareStatement对象
                /* 设置替换sql语句中都参数占位符 */
                ps.setString(1,maj.getId());
                ps.setString(2,maj.getCode());
                ps.setString(3,maj.getName());
                ps.setDate(4,new java.sql.Date(maj.getCreateDate().getTime()) );
                ps.setString(5,maj.getFid());
                ps.setString(6,maj.getDescripte());
                res = ps.executeUpdate();
    
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } finally {
                DataSourceManager.close(ps);
                DataSourceManager.close(conn);
            }
            return res;
        }
    
        /**
         * 修改选定的院系对象
         * @param fac 欲修改的院系
         * @return
         */
        public int modifyFaculty(Faculty fac){
            int res = 0;
            String sql = "update faculty set name=?,createDate=?," +
                    "descripte=? where id=?";
            Connection conn = DataSourceManager.getConnection();    //获取数据库连接
            PreparedStatement ps = null;    //获取PrepareStatement接口对象
    
            try {
                ps = conn.prepareStatement(sql);
                ps.setString(1,fac.getName());
                ps.setDate(2,new java.sql.Date(fac.getCreateDate().getTime()) );
                ps.setString(3,fac.getDescripte());
                ps.setString(4,fac.getId());
                res = ps.executeUpdate();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } finally {
                DataSourceManager.close(ps);
                DataSourceManager.close(conn);
            }
            return res;
        }
    
        /**
         * 修改选定的专业对象
         * @param maj 欲修改的专业
         * @return
         */
        public int modifyMajor(Major maj){
            int res = 0;
            String sql = "update major set code=?,name=?,createDate=?," +
                    "fid=?,descripte=? where id=?";
            Connection conn = DataSourceManager.getConnection();    //获取数据库连接
            PreparedStatement ps = null;    //获取PrepareStatement接口对象
    
            try {
                ps = conn.prepareStatement(sql);
                ps.setString(1,maj.getCode());
                ps.setString(2,maj.getName());
                ps.setDate(3,new java.sql.Date(maj.getCreateDate().getTime()) );
                ps.setString(4,maj.getFid());
                ps.setString(5,maj.getDescripte());
                ps.setString(6,maj.getId());
                res = ps.executeUpdate();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } finally {
                DataSourceManager.close(ps);
                DataSourceManager.close(conn);
            }
            return res;
        }
    
        /**
         * 删除院系的方法
         * @param id 要删除的院系id
         * @return
         */
        public int deleteFacultyById(String id){
            int res = 0;
            String sql = "delete from faculty where id = '"+id+"'";
            Connection conn = DataSourceManager.getConnection();    //获取数据库连接
            PreparedStatement ps = null;    //获取PrepareStatement接口对象
    
            try {
                ps = conn.prepareStatement(sql);
                //执行删除操作
                res = ps.executeUpdate();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } finally {
                DataSourceManager.close(ps);
                DataSourceManager.close(conn);
            }
            return res;
        }
    
        /**
         * 删除专业的方法
         * @param id 要删除的专业id
         * @return
         */
        public int deleteMajorById(String id){
            int res = 0;
            String sql = "delete from major where id = '"+id+"'";
            Connection conn = DataSourceManager.getConnection();    //获取数据库连接
            PreparedStatement ps = null;    //获取PrepareStatement接口对象
    
            try {
                ps = conn.prepareStatement(sql);
                //执行删除操作
                res = ps.executeUpdate();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } finally {
                DataSourceManager.close(ps);
                DataSourceManager.close(conn);
            }
            return res;
        }
    }
    package com.xzit.platform.edu.test;
    
    import com.xzit.platform.edu.dao.ScoreDao;
    import com.xzit.platform.edu.dao.SubjectDao;
    
    import java.util.List;
    import java.util.Map;
    
    public class TestQueryListMap {
        public static void main(String[] args) {
            /* 2 根据给定的专业获取此专业下的班级信息,使用Map封装每个班级信息; */
            List<Map<String,Object>> list = new SubjectDao().querySubjectClassInfoListMap();
            System.out.println("专业id\t专业名称\t班级id\t班级名称\t班级描述");
            for (Map<String,Object> map:list){
                System.out.println(map.get("majid")+"\t"+
                        map.get("majname")+"\t"+
                        map.get("claid")+"\t"+
                        map.get("claname")+"\t"+
                        map.get("cladesc"));
            }
            System.out.println("------------------------------------------------------");
    
            /*4 根据给定的学科名称获取此属于此学科的所有及格成绩,并显示成绩的谁(学生姓名)的,及此学生属于哪个班级(显示班级名称);*/
            List<Map<String,Object>> list1 = new ScoreDao().queryScoresBySubject("Java开发");
            System.out.println("学生姓名\t班级名称\t学科名称\t学科成绩");
            for (Map<String,Object> map:list1){
                System.out.println(map.get("stuName")+"\t"+
                        map.get("claName")+"\t"+
                        map.get("subName")+"\t"+
                        map.get("scoName"));
            }
        }
    }
    package com.xzit.platform.edu.test;
    
    import com.xzit.platform.edu.dao.ScoreDao;
    
    import java.util.List;
    import java.util.Map;
    import java.util.Scanner;
    
    public class TestPaging {
        public static void main(String[] args) {
            ScoreDao dao = new ScoreDao();
            Scanner input = new Scanner(System.in);
            /* 1 分页查询显示所有学科的学生成绩信息,包括学科名称,学生姓名,学号,分数,考试日期,是否及格; */
            System.out.println("请输入页码");
            int pageNum = input.nextInt();
            System.out.println("请输入每页显示的行数");
            int pageSize = input.nextInt();
    
            Map<String,Object> map = dao.queryAllSubjectScore(pageNum,pageSize);
    
            Object rowCount = map.get("rowCount").toString();
            System.out.println("符合条件记录总数"+rowCount+"\t");
            Object pageSum = map.get("pageSum");
            System.out.println("共 "+pageSum+"页 \t");
            System.out.println("当前是第 "+pageNum+"页");
    
            List<Map> rows = (List)map.get("rows");
    
            for (Map<String,Object>row:rows){
                System.out.println(
                                row.get("subjectName")+"\t"+
                                row.get("studentName")+"\t"+
                                row.get("studentNum")+"\t"+
                                row.get("scores")+"\t"+
                                row.get("testday")
                        );
            }
    
            /* 2 分页查询显示所有某学科的所有学生成绩信息,包括学科名称,学生姓名,学号,分数,考试日期,是否及格; */
            System.out.println("---------------------------------");
            System.out.println("请输入页码");
            int pageNum2 = input.nextInt();
            System.out.println("请输入每页显示的行数");
            int pageSize2 = input.nextInt();
            System.out.println("请输入要查询的学科");
            String subjectName = input.next();
    
            Map<String,Object> map2 = dao.queryScoreBySubName(pageNum2,pageSize2,subjectName);
    
            Object rowCount2 = map2.get("rowCount").toString();
            System.out.println("符合条件记录总数"+rowCount2+"\t");
            Object pageSum2 = map2.get("pageSum");
            System.out.println("共 "+pageSum2+"页 \t");
            System.out.println("当前是第 "+pageNum2+"页");
    
    
            List<Map> rows2 = (List)map2.get("rows");
    
            for (Map<String,Object>row2:rows2){
                System.out.println(
                        row2.get("subjectName")+"\t"+
                                row2.get("studentName")+"\t"+
                                row2.get("studentNum")+"\t"+
                                row2.get("scores")+"\t"+
                                row2.get("testday")
                );
            }
    
            System.out.println("---------------------------------");
    
            /* 3 分页查询显示某个班级的某个学科的所有成绩,包括班级名称,学科名称,学生姓名,分数,考试日期; */
            System.out.println("---------------------------------");
            System.out.println("请输入页码");
            int pageNum3 = input.nextInt();
            System.out.println("请输入每页显示的行数");
            int pageSize3 = input.nextInt();
            System.out.println("请输入要查询的班级");
            String className = input.next();
    
            Map<String,Object> map3 = dao.queryScoreByClassInfo(pageNum3,pageSize3,className);
    
            Object rowCount3 = map3.get("rowCount").toString();
            System.out.println("符合条件记录总数"+rowCount3+"\t");
            Object pageSum3 = map3.get("pageSum");
            System.out.println("共 "+pageSum3+"页 \t");
            System.out.println("当前是第 "+pageNum3+"页");
    
    
            List<Map> rows3 = (List)map3.get("rows");
    
            for (Map<String,Object>row3:rows3){
                System.out.println(
                        row3.get("className")+"\t"+
                        row3.get("subjectName")+"\t"+
                        row3.get("studentName")+"\t"+
                        row3.get("studentNum")+"\t"+
                        row3.get("scores")+"\t"+
                        row3.get("testday")
                );
            }
        }
    }
    package com.xzit.platform.edu.test;
    
    import com.xzit.platform.edu.dao.ScoreDao;
    import com.xzit.platform.edu.dao.SubjectDao;
    import com.xzit.platform.edu.pojo.Students;
    import com.xzit.platform.edu.pojo.Subject;
    
    import java.util.List;
    import java.util.Map;
    
    public class TestQuery {
        public static void main(String[] args) {
    
            /* 1 根据给定的院系名称获取属于此院系的所有专业信息 */
            List<Subject> subs = new SubjectDao().querySubjectList();
    
            System.out.println("ID编号\t学科编号\t学科名称\t是否必修\t状态\t设置日期\t备注");
    
            for (Subject sub:subs){
                System.out.println(sub.getId()+"\t"+sub.getNumbers()+"\t"+
                        sub.getName()+"\t"+sub.getObligatory()+"\t"+sub.getStatus()
                        +"\t"+sub.getCreateDate()+"\t"+sub.getDescription());
            }
    
            System.out.println("------------------------------------------------------");
    
            /* 3 根据给定的班级名称获取此班级下的所有性别为男的学生信息,并按照生日排序(倒序),性别为1以”男”作为显示; */
            List<Students> stus = new SubjectDao().queryStudentsByClassInfo("信管2班");
    
            for(Students stu:stus){
                System.out.println(stu.getId()+"\t"+stu.getNumbers()+"\t"+
                        stu.getName()+"\t"+stu.getGender()+"\t"+
                        stu.getBirth()+"\t"+stu.getPhone()+"\t"+
                        stu.getDaid()+"\t"+stu.getCid()+"\t"+
                        stu.getApartment()+"\t"+stu.getDescripte());
            }
    
            System.out.println("------------------------------------------------------");
    
            /* 4 分别统计不同专业下的所有学生人数,要求显示专业代码,专业名称,人数; */
            List<Map<String,Object>> list = new ScoreDao().sumStudentsByMajor();
            System.out.println("专业代码\t专业名称\t学生人数");
            for (Map<String,Object> map :list){
                System.out.println(
                        map.get("majorId")+"\t"+
                        map.get("majorName")+"\t"+
                        map.get("sumId")
                        );
            }
    
            System.out.println("------------------------------------------------------");
    
            /* 5 按照学生分组分别统计此学生的某个学科成绩的总分,平均分,要求显示学生ID,学生姓名; */
            List<Map<String,Object>> list2 = new ScoreDao().sumScoreBySubject("流体力学");
            System.out.println("学生id\t学生姓名\t科目名称\t成绩总和\t平均分");
            for (Map<String,Object> map2:list2){
                System.out.println(map2.get("stuId")+"\t"+
                                map2.get("stuName")+"\t"+
                                map2.get("subName")+"\t"+
                                map2.get("sumScore")+"\t"+
                                map2.get("avgScore")
                );
            }
    
            System.out.println("------------------------------------------------------");
    
            /* 6 实现将给定的的两个班级和学科名称汇总显示此两个班级的此学科总分和平均分 */
            List<Map<String,Object>> list3 = new ScoreDao().sumScoreByClassInfo("信管2班","软工1班","Java开发");
            System.out.println("班级名称\t学科名称\t成绩总和\t成绩总和\t平均分");
            for (Map<String,Object> map3:list3){
                System.out.println(map3.get("className")+"\t"+
                        map3.get("subName")+"\t"+
                        map3.get("sumScore")+"\t"+
                        map3.get("avgScore")
                );
            }
    
            System.out.println("------------------------------------------------------");
    
            List<Map<String,Object>> list4 = new ScoreDao().callProcedure3("流体力学","110380");
            for(Map<String,Object> map:list4){
                System.out.println(map.get("stuNumber")
                        +"\t"+map.get("className")
                        +"\t"+map.get("subName")
                        +"\t"+map.get("scores")
                );
            }
        }
    }
    package com.xzit.platform.edu.test;
    
    import com.xzit.platform.edu.dao.BankBusiness;
    
    public class TestTransaction {
        public static void main(String[] args) {
    
            new BankBusiness().testJdbcTransaction(5000,288,287);
        }
    }
    package com.xzit.platform.edu.test;
    
    import com.xzit.platform.edu.dao.ClassInfoAndStudentsDao;
    import com.xzit.platform.edu.pojo.ClassInfo;
    import com.xzit.platform.edu.pojo.Students;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    
    public class ClassInfoAndStudentsInsert {
        public static void main(String[] args) {
            /* 插入新的班级 */
            ClassInfo cla = new ClassInfo();
            cla.setId("1");
            cla.setName("信管2班");
            cla.setMid("1");
            cla.setNumbers("52");
            cla.setDescripte("廖爱红老师带的班");
            String time = "2014-9-1";
            try {
                cla.setCreateDate(new SimpleDateFormat("yyyy-mm-dd").parse(time));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            int res = new ClassInfoAndStudentsDao().addClassInfo(cla);
            System.out.println("影响数据库班级表的行数是 "+res);
    
            /* 插入新的学生 */
            Students stu = new Students();
            stu.setId("1");
            stu.setNumbers("110380");
            stu.setName("曾誉");
            stu.setGender("1");
            String time2 = "1996-4-26";
            try {
                stu.setBirth(new SimpleDateFormat("yyyy-mm-dd").parse(time2));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            stu.setPhone("13750018710");
            stu.setDaid("1");
            stu.setCid("1");
            stu.setApartment("D503");
            stu.setDescripte("一个普通的信管学生");
            int res2 = new ClassInfoAndStudentsDao().addStudents(stu);
            System.out.println("影响数据库学生表的行数是 "+res2);
        }
    }
    package com.xzit.platform.edu.test;
    
    import com.xzit.platform.edu.dao.ClassInfoAndStudentsDao;
    import com.xzit.platform.edu.pojo.ClassInfo;
    import com.xzit.platform.edu.pojo.Students;
    
    import java.util.Date;
    
    public class ClassInfoAndStudentsUpdate {
        public static void main(String[] args) {
            /* 修改班级信息 */
            ClassInfo cla = new ClassInfo();
            cla.setId("1");
            cla.setName("信管1班");
            cla.setCreateDate(new Date());
            cla.setMid("1");
            cla.setDescripte("王二威老师带的班级");
            cla.setNumbers("39");
            int res =  new ClassInfoAndStudentsDao().modifyClassInfo(cla);
            System.out.println("影响数据库班级表的行数是 "+res);
    
            /* 修改学生信息 */
            Students stu = new Students();
            stu.setId("1");
            stu.setName("王焕凯");
            stu.setGender("1");
            stu.setNumbers("114514");
            stu.setCid("1");
            stu.setApartment("704");
            stu.setDescripte("1班的班长");
            stu.setDaid("1");
            stu.setPhone("13750018720");
            stu.setBirth(new Date());
            int res2 = new ClassInfoAndStudentsDao().modifyStudents(stu);
            System.out.println("影响数据库学生表的行数是 "+res2);
        }
    }
    package com.xzit.platform.edu.test;
    
    import com.xzit.platform.edu.dao.ClassInfoAndStudentsDao;
    
    public class ClassInfoAndStudentsDelete {
        public static void main(String[] args) {
            /* 删除学生 */
            String id = "1";//被删除的学生对象的id(主键)
            int res = new ClassInfoAndStudentsDao().deleteStudentsById(id);
            System.out.println("删除的学生数据库表行数 "+res);
    
            /* 删除班级 */
            String id2 = "1";//被删除的班级对象的id(主键)
            int res2 = new ClassInfoAndStudentsDao().deleteClassInfoById(id);
            System.out.println("删除的学生数据库表行数 "+res2);
    
        }
    }
  • 相关阅读:
    SqlSelect记录搜索
    SqlSelect在查询结果前面加一列序号列
    关于MMC不能打开文件C:\Program Files\Microsoft SQL Server\80\Tools\Binn\SQL Server Enterprise Manager.MSC可能是由于文件不存在,不是一个MMC控制台,或者用后来的MMC版本创建。也可能你没有访问此文件的足够权限
    IsPostBack郁闷
    查询值的数目与目标字段中的数目不同
    SqlServer2000数据库备份
    三种antiTNF制剂生物学剂量增加、非生物制剂和类固醇强化作用的差异:来自临床实践的证据
    三种影像学方法证实依那西普治疗银屑病关节炎有关节修复作用
    北美地区早期和长期类风湿性关节炎患者应用依那西普10年以上的安全性和有效性
    肿瘤坏死因子(TNF)阻断剂治疗幼年型银屑病关节炎: 有效吗
  • 原文地址:https://www.cnblogs.com/zengyu1234/p/15575031.html
Copyright © 2020-2023  润新知